You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2011/08/13 00:32:34 UTC

svn commit: r1157275 - in /qpid/trunk/qpid/cpp/src: qpid/Address.cpp qpid/Url.cpp tests/Url.cpp

Author: astitcher
Date: Fri Aug 12 22:32:34 2011
New Revision: 1157275

URL: http://svn.apache.org/viewvc?rev=1157275&view=rev
Log:
QPID-3405: Implemented simple IPv6 literal parsing/printing for c++ connection URLs

Modified:
    qpid/trunk/qpid/cpp/src/qpid/Address.cpp
    qpid/trunk/qpid/cpp/src/qpid/Url.cpp
    qpid/trunk/qpid/cpp/src/tests/Url.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/Address.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/Address.cpp?rev=1157275&r1=1157274&r2=1157275&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/Address.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/Address.cpp Fri Aug 12 22:32:34 2011
@@ -28,7 +28,13 @@ namespace qpid {
 const string Address::TCP("tcp");
 
 ostream& operator<<(ostream& os, const Address& a) {
-    return os << a.protocol << ":" << a.host << ":" << a.port;
+    // If the host is an IPv6 literal we need to print "[]" around it
+    // (we detect IPv6 literals because they contain ":" which is otherwise illegal)
+    if (a.host.find(':') != string::npos) {
+        return os << a.protocol << ":[" << a.host << "]:" << a.port;
+    } else {
+        return os << a.protocol << ":" << a.host << ":" << a.port;
+    }
 }
 
 bool operator==(const Address& x, const Address& y) {

Modified: qpid/trunk/qpid/cpp/src/qpid/Url.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/Url.cpp?rev=1157275&r1=1157274&r2=1157275&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/Url.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/Url.cpp Fri Aug 12 22:32:34 2011
@@ -156,11 +156,12 @@ class UrlParser {
         return false;
     }
 
-    // TODO aconway 2008-11-20: this does not fully implement
-    // http://www.ietf.org/rfc/rfc3986.txt. Works for DNS names and
-    // ipv4 literals but won't handle ipv6.
+    // A liberal interpretation of http://www.ietf.org/rfc/rfc3986.txt.
+    // Works for DNS names and and ipv4 and ipv6 literals
     // 
     bool host(string& h) {
+        if (ip6literal(h)) return true;
+
         const char* start=i;
         while (unreserved() || pctEncoded())
             ;
@@ -169,6 +170,22 @@ class UrlParser {
         return true;
     }
 
+    // This is a bit too liberal for IPv6 literal addresses, but probably good enough
+    bool ip6literal(string& h) {
+        if (literal("[")) {
+            const char* start = i;
+            while (hexDigit() || literal(":") || literal("."))
+                ;
+            const char* end = i;
+            if ( end-start < 2 ) return false; // Smallest valid address is "::"
+            if (literal("]")) {
+                h.assign(start, end);
+                return true;
+            }
+        }
+        return false;
+    }
+
     bool unreserved() { return (::isalnum(*i) || ::strchr("-._~", *i)) && advance(); }
 
     bool pctEncoded() { return literal("%") && hexDigit() && hexDigit(); }

Modified: qpid/trunk/qpid/cpp/src/tests/Url.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/Url.cpp?rev=1157275&r1=1157274&r2=1157275&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/Url.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/Url.cpp Fri Aug 12 22:32:34 2011
@@ -60,6 +60,32 @@ QPID_AUTO_TEST_CASE(TestParseXyz) {
     BOOST_CHECK_EQUAL(Url("xyz:host").str(), "amqp:xyz:host:5672");
 }
 
+QPID_AUTO_TEST_CASE(TestParseTricky) {
+    BOOST_CHECK_EQUAL(Url("amqp").str(), "amqp:tcp:amqp:5672");
+    BOOST_CHECK_EQUAL(Url("amqp:tcp").str(), "amqp:tcp:tcp:5672");
+    // These are ambiguous parses and arguably not the best result
+    BOOST_CHECK_EQUAL(Url("amqp:876").str(), "amqp:tcp:876:5672");
+    BOOST_CHECK_EQUAL(Url("tcp:567").str(), "amqp:tcp:567:5672");
+}
+
+QPID_AUTO_TEST_CASE(TestParseIPv6) {
+    Url u1("[::]");
+    BOOST_CHECK_EQUAL(u1[0].host, "::");
+    BOOST_CHECK_EQUAL(u1[0].port, 5672);
+    Url u2("[::1]");
+    BOOST_CHECK_EQUAL(u2[0].host, "::1");
+    BOOST_CHECK_EQUAL(u2[0].port, 5672);
+    Url u3("[::127.0.0.1]");
+    BOOST_CHECK_EQUAL(u3[0].host, "::127.0.0.1");
+    BOOST_CHECK_EQUAL(u3[0].port, 5672);
+    Url u4("[2002::222:68ff:fe0b:e61a]");
+    BOOST_CHECK_EQUAL(u4[0].host, "2002::222:68ff:fe0b:e61a");
+    BOOST_CHECK_EQUAL(u4[0].port, 5672);
+    Url u5("[2002::222:68ff:fe0b:e61a]:123");
+    BOOST_CHECK_EQUAL(u5[0].host, "2002::222:68ff:fe0b:e61a");
+    BOOST_CHECK_EQUAL(u5[0].port, 123);
+}
+
 QPID_AUTO_TEST_CASE(TestParseMultiAddress) {
     Url::addProtocol("xyz");
     URL_CHECK_STR("amqp:tcp:host:0,xyz:foo:123,tcp:foo:0,xyz:bar:1");



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org