summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2010-05-17 15:34:14 +0000
committerAlan Conway <aconway@apache.org>2010-05-17 15:34:14 +0000
commit8945f4cbf70146400dbd28a0695a4cd268a80eee (patch)
tree9d65d3aecdaec1ed470c99f150f88dc66d326de9 /cpp/src
parentf9f6f9e1a230643efd6eae08101731ccdbd562e5 (diff)
downloadqpid-python-8945f4cbf70146400dbd28a0695a4cd268a80eee.tar.gz
Added support for user/pass@ syntax in Url.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@945211 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/qpid/Url.cpp31
-rw-r--r--cpp/src/tests/Url.cpp17
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