Add parse_url to _utils.
The patch adds parse_url to _utils as an attempt to find a common url format that satisfies most drivers needs. The code isn't definitive but instead the beginning for further discussions. Current code parses transport urls like this: qpid://test/test {'exchange': 'test', 'hosts': [{'host': 'test', 'password': '', 'username': ''}], 'parameters': {}, 'transport': 'qpid'} qpid://test:port/test {'exchange': 'test', 'hosts': [{'host': 'test:port', 'password': '', 'username': ''}], 'parameters': {}, 'transport': 'qpid'} qpid://username:password@test:port/test {'exchange': 'test', 'hosts': [{'host': 'test:port', 'password': 'password', 'username': 'username'}], 'parameters': {}, 'transport': 'qpid'} qpid://username:password@test:port {'exchange': None, 'hosts': [{'host': 'test:port', 'password': 'password', 'username': 'username'}], 'parameters': {}, 'transport': 'qpid'} qpid://username:password@test:port,test2:port2/test {'exchange': 'test', 'hosts': [{'host': 'test:port', 'password': 'password', 'username': 'username'}, {'host': 'test2:port2', 'password': 'password', 'username': 'username'}], 'parameters': {}, 'transport': 'qpid'} qpid://username:password@test:port,:@test2:port2/test {'exchange': 'test', 'hosts': [{'host': 'test:port', 'password': 'password', 'username': 'username'}, {'host': 'test2:port2', 'password': '', 'username': ''}], 'parameters': {}, 'transport': 'qpid'} qpid://username:password@test:port,:@test2:port2/test?option=value {'exchange': 'test', 'hosts': [{'host': 'test:port', 'password': 'password', 'username': 'username'}, {'host': 'test2:port2', 'password': '', 'username': ''}], 'parameters': {'option': ['value']}, 'transport': 'qpid'}
This commit is contained in:
parent
d559a86ec9
commit
ff2c04834f
|
@ -34,6 +34,103 @@ def version_is_compatible(imp_version, version):
|
|||
return True
|
||||
|
||||
|
||||
def parse_url(url, default_exchange=None):
|
||||
"""Parse an url.
|
||||
|
||||
Assimung a URL takes the form of:
|
||||
|
||||
transport://username:password@host1:port[,hostN:portN]/exchange[?option=value]
|
||||
|
||||
then parse the URL and return a dictionary with the following structure:
|
||||
|
||||
{
|
||||
'exchange': 'exchange'
|
||||
'transport': 'transport',
|
||||
'hosts': [{'username': 'username',
|
||||
'password': 'password'
|
||||
'host': 'host1:port1'},
|
||||
...],
|
||||
'parameters': {'option': 'value'}
|
||||
}
|
||||
|
||||
Netloc is parsed following the sequence bellow:
|
||||
|
||||
* It is first splitted by ',' in order to support multiple hosts
|
||||
* The last parsed username and password will be propagated to the rest
|
||||
of hotsts specified:
|
||||
|
||||
user:passwd@host1:port1,host2:port2
|
||||
|
||||
[
|
||||
{"username": "user", "password": "passwd", "host": "host1:port1"},
|
||||
{"username": "user", "password": "passwd", "host": "host2:port2"}
|
||||
]
|
||||
|
||||
* In order to avoid the above propagation, it is possible to alter the order
|
||||
in which the hosts are specified or specify a set of fake credentials using
|
||||
",:@host2:port2"
|
||||
|
||||
|
||||
user:passwd@host1:port1,:@host2:port2
|
||||
|
||||
[
|
||||
{"username": "user", "password": "passwd", "host": "host1:port1"},
|
||||
{"username": "", "password": "", "host": "host2:port2"}
|
||||
]
|
||||
|
||||
:param url: The URL to parse
|
||||
:type url: str
|
||||
:param default_exchange: what to return if no exchange found in URL
|
||||
:type default_exchange: str
|
||||
:returns: A dictionary with the parsed data
|
||||
"""
|
||||
|
||||
# NOTE(flaper87): Not PY3K compliant
|
||||
if not isinstance(url, basestring):
|
||||
raise TypeError(_("Wrong URL type"))
|
||||
|
||||
url = urlparse.urlparse(url)
|
||||
|
||||
parsed = dict(transport=url.scheme)
|
||||
|
||||
# NOTE(flaper87): Set the exchange.
|
||||
# if it is / or None then use the
|
||||
# default one.
|
||||
exchange = default_exchange
|
||||
if url.path and url.path != "/":
|
||||
exchange = url.path[1:].split("/")[0]
|
||||
parsed["exchange"] = exchange
|
||||
|
||||
# NOTE(flaper87): Parse netloc.
|
||||
hosts = []
|
||||
username = password = ''
|
||||
for host in url.netloc.split(","):
|
||||
if not host:
|
||||
continue
|
||||
|
||||
if "@" in host:
|
||||
creds, host = host.split("@")
|
||||
username, password = creds.split(":")
|
||||
|
||||
hosts.append({
|
||||
"host": host,
|
||||
"username": username,
|
||||
"password": password,
|
||||
})
|
||||
|
||||
parsed["hosts"] = hosts
|
||||
|
||||
parameters = {}
|
||||
if url.query:
|
||||
# NOTE(flaper87): This returns a dict with
|
||||
# key -> [value], those values need to be
|
||||
# normalized
|
||||
parameters = urlparse.parse_qs(url.query)
|
||||
parsed['parameters'] = parameters
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
def exchange_from_url(self, url, default_exchange=None):
|
||||
"""Parse an exchange name from a URL.
|
||||
|
||||
|
|
Loading…
Reference in New Issue