diff options
author | Andrew Stitcher <astitcher@apache.org> | 2011-08-12 22:32:34 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2011-08-12 22:32:34 +0000 |
commit | b6e1ca86d77463c4dcd75854e9bce8ccb8e47a10 (patch) | |
tree | 393bca56630b1c65aac3eaff99961bf4c3c46c5e /cpp | |
parent | 2ad73b9bb5ec8461e58dbea9d123761a7bf308dc (diff) | |
download | qpid-python-b6e1ca86d77463c4dcd75854e9bce8ccb8e47a10.tar.gz |
QPID-3405: Implemented simple IPv6 literal parsing/printing for c++ connection URLs
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1157275 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/qpid/Address.cpp | 8 | ||||
-rw-r--r-- | cpp/src/qpid/Url.cpp | 23 | ||||
-rw-r--r-- | cpp/src/tests/Url.cpp | 26 |
3 files changed, 53 insertions, 4 deletions
diff --git a/cpp/src/qpid/Address.cpp b/cpp/src/qpid/Address.cpp index e2b2dfbcdf..bed3d592df 100644 --- a/cpp/src/qpid/Address.cpp +++ b/cpp/src/qpid/Address.cpp @@ -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) { diff --git a/cpp/src/qpid/Url.cpp b/cpp/src/qpid/Url.cpp index ab796f4642..f699b60c17 100644 --- a/cpp/src/qpid/Url.cpp +++ b/cpp/src/qpid/Url.cpp @@ -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(); } diff --git a/cpp/src/tests/Url.cpp b/cpp/src/tests/Url.cpp index 234a62ee91..b30de682bc 100644 --- a/cpp/src/tests/Url.cpp +++ b/cpp/src/tests/Url.cpp @@ -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"); |