diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/qpid/Url.cpp | 31 | ||||
-rw-r--r-- | cpp/src/tests/Url.cpp | 17 |
2 files changed, 43 insertions, 5 deletions
diff --git a/cpp/src/qpid/Url.cpp b/cpp/src/qpid/Url.cpp index 845a98c87b..0b9fdbf6eb 100644 --- a/cpp/src/qpid/Url.cpp +++ b/cpp/src/qpid/Url.cpp @@ -59,8 +59,11 @@ string Url::str() const { } ostream& operator<<(ostream& os, const Url& url) { - Url::const_iterator i = url.begin(); os << "amqp:"; + if (!url.getUser().empty()) os << url.getUser(); + if (!url.getPass().empty()) os << "/" << url.getPass(); + if (!(url.getUser().empty() && url.getPass().empty())) os << "@"; + Url::const_iterator i = url.begin(); if (i!=url.end()) { os << *i++; while (i != url.end()) @@ -72,22 +75,35 @@ ostream& operator<<(ostream& os, const Url& url) { static const std::string TCP = "tcp"; /** Simple recursive-descent parser for this grammar: - url = ["amqp:"] protocol_addr *("," protocol_addr) - protocol_addr = [ protocol_tag ":" ] host [":" port] - protocol_tag = "tcp" / "rdma" / "ssl" - +url = ["amqp:"][ user ["/" password] "@" ] protocol_addr *("," protocol_addr) +protocol_addr = tcp_addr / rmda_addr / ssl_addr / .. others plug-in +tcp_addr = ["tcp:"] host [":" port] +rdma_addr = "rdma:" host [":" port] +ssl_addr = "ssl:" host [":" port] */ class UrlParser { public: UrlParser(Url& u, const char* s) : url(u), text(s), end(s+strlen(s)), i(s) {} bool parse() { literal("amqp:"); // Optional + userPass(); // Optional return list(&UrlParser::protocolAddr, &UrlParser::comma) && i == end; } private: typedef bool (UrlParser::*Rule)(); + bool userPass() { + const char* at = std::find(i, end, '@'); + if (at == end) return false; + const char* slash = std::find(i, at, '/'); + url.setUser(string(i, slash)); + const char* pass = (slash == at) ? slash : slash+1; + url.setPass(string(pass, at)); + i = at+1; + return true; + } + bool comma() { return literal(","); } bool protocolAddr() { @@ -206,6 +222,11 @@ void Url::throwIfEmpty() const { throw Url::Invalid("URL contains no addresses"); } +std::string Url::getUser() const { return user; } +std::string Url::getPass() const { return pass; } +void Url::setUser(const std::string& s) { user = s; } +void Url::setPass(const std::string& s) { pass = s; } + std::istream& operator>>(std::istream& is, Url& url) { std::string s; is >> s; diff --git a/cpp/src/tests/Url.cpp b/cpp/src/tests/Url.cpp index df1852dd1d..234a62ee91 100644 --- a/cpp/src/tests/Url.cpp +++ b/cpp/src/tests/Url.cpp @@ -68,6 +68,23 @@ QPID_AUTO_TEST_CASE(TestParseMultiAddress) { URL_CHECK_INVALID(",amqp:tcp:h"); } +QPID_AUTO_TEST_CASE(TestParseUserPass) { + URL_CHECK_STR("amqp:user/pass@tcp:host:123"); + URL_CHECK_STR("amqp:user@tcp:host:123"); + BOOST_CHECK_EQUAL(Url("user/pass@host").str(), "amqp:user/pass@tcp:host:5672"); + BOOST_CHECK_EQUAL(Url("user@host").str(), "amqp:user@tcp:host:5672"); + + Url u("user/pass@host"); + BOOST_CHECK_EQUAL(u.getUser(), "user"); + BOOST_CHECK_EQUAL(u.getPass(), "pass"); + Url v("foo@host"); + BOOST_CHECK_EQUAL(v.getUser(), "foo"); + BOOST_CHECK_EQUAL(v.getPass(), ""); + u = v; + BOOST_CHECK_EQUAL(u.getUser(), "foo"); + BOOST_CHECK_EQUAL(u.getPass(), ""); +} + QPID_AUTO_TEST_SUITE_END() }} // namespace qpid::tests |