diff options
| author | Alan Conway <aconway@apache.org> | 2010-05-11 14:39:58 +0000 |
|---|---|---|
| committer | Alan Conway <aconway@apache.org> | 2010-05-11 14:39:58 +0000 |
| commit | 16da0e0c511c0c1cf4ea592640c522754065200a (patch) | |
| tree | 59fb80994db731fabe19897c95a6912e68716360 /cpp/src/qpid/Url.cpp | |
| parent | be8e1bf6b6a0d760bddbbe6642d477a95f36ab42 (diff) | |
| download | qpid-python-16da0e0c511c0c1cf4ea592640c522754065200a.tar.gz | |
Support for multiple protocols in qpid::Url.
- simplified qpid::Address to hold (protocol,host,port) triples.
- protocol plugins call Url:addProtocol to add tags to Url parser.
- use Address::protocol when establishing connections.
- ssl_test: tests using URL to connect.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@943130 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/Url.cpp')
| -rw-r--r-- | cpp/src/qpid/Url.cpp | 70 |
1 files changed, 39 insertions, 31 deletions
diff --git a/cpp/src/qpid/Url.cpp b/cpp/src/qpid/Url.cpp index 3b4eb60ddd..845a98c87b 100644 --- a/cpp/src/qpid/Url.cpp +++ b/cpp/src/qpid/Url.cpp @@ -21,6 +21,7 @@ #include "qpid/Msg.h" #include "qpid/sys/SystemInfo.h" #include "qpid/sys/StrError.h" +#include "qpid/client/Connector.h" #include <boost/lexical_cast.hpp> @@ -36,7 +37,7 @@ namespace qpid { Url::Invalid::Invalid(const string& s) : Exception(s) {} Url Url::getHostNameUrl(uint16_t port) { - TcpAddress address(std::string(), port); + Address address("tcp", std::string(), port); if (!sys::SystemInfo::getLocalHostname(address)) throw Url::Invalid(QPID_MSG("Cannot get host name: " << qpid::sys::strError(errno))); return Url(address); @@ -68,50 +69,55 @@ ostream& operator<<(ostream& os, const Url& url) { return os; } +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" -/** Simple recursive-descent parser for url grammar in AMQP 0-10 spec: - - amqp_url = "amqp:" prot_addr_list - prot_addr_list = [prot_addr ","]* prot_addr - prot_addr = tcp_prot_addr | tls_prot_addr - - tcp_prot_addr = tcp_id tcp_addr - tcp_id = "tcp:" | "" - tcp_addr = [host [":" port] ] - host = <as per http://www.ietf.org/rfc/rfc3986.txt> - port = number]]> */ class UrlParser { public: UrlParser(Url& u, const char* s) : url(u), text(s), end(s+strlen(s)), i(s) {} - bool parse() { return literal("amqp:") && list(&UrlParser::protAddr, &UrlParser::comma) && i == end; } + bool parse() { + literal("amqp:"); // Optional + return list(&UrlParser::protocolAddr, &UrlParser::comma) && i == end; + } private: typedef bool (UrlParser::*Rule)(); bool comma() { return literal(","); } - // NOTE: tcpAddr must be last since it is allowed to omit it's tcp: tag. - bool protAddr() { return exampleAddr() || tcpAddr(); } - - bool tcpAddr() { - TcpAddress addr; - literal("tcp:"); // Don't check result, allowed to be absent. - return addIf(host(addr.host) && (literal(":") ? port(addr.port) : true), addr); + bool protocolAddr() { + Address addr(Address::TCP, "", Address::AMQP_PORT); // Set up defaults + protocolTag(addr.protocol); // Optional + bool ok = (host(addr.host) && + (literal(":") ? port(addr.port) : true)); + if (ok) url.push_back(addr); + return ok; } - - // Placeholder address type till we have multiple address types. Address is a single char. - bool exampleAddr () { - if (literal("example:") && i < end) { - ExampleAddress ex(*i++); - url.push_back(ex); - return true; + + bool protocolTag(string& result) { + const char* j = std::find(i,end,':'); + if (j != end) { + string tag(i,j); + if (std::find(Url::protocols.begin(), Url::protocols.end(), tag) != + Url::protocols.end()) + { + i = j+1; + result = tag; + return true; + } } return false; } - // FIXME aconway 2008-11-20: this does not implement http://www.ietf.org/rfc/rfc3986.txt. - // Works for DNS names and ipv4 literals but won't handle ipv6. + // 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. + // bool host(string& h) { const char* start=i; while (unreserved() || pctEncoded()) @@ -129,8 +135,6 @@ class UrlParser { bool port(uint16_t& p) { return decimalInt(p); } - template <class AddrType> bool addIf(bool ok, const AddrType& addr) { if (ok) url.push_back(addr); return ok; } - template <class IntType> bool decimalInt(IntType& n) { const char* start = i; while (decDigit()) @@ -209,4 +213,8 @@ std::istream& operator>>(std::istream& is, Url& url) { return is; } +std::vector<std::string> Url::protocols; + +void Url::addProtocol(const std::string& tag) { protocols.push_back(tag); } + } // namespace qpid |
