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:
Flaper Fesp 2013-05-21 15:34:14 +02:00
parent d559a86ec9
commit ff2c04834f
1 changed files with 97 additions and 0 deletions

View File

@ -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.