diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-11-25 14:46:58 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-11-25 14:46:58 -0500 |
commit | 6029496bd3fb78caeab349ef8df5b58f058db16e (patch) | |
tree | 9c218dbec71973452daa585cf1db6caa034e8571 /lib/sqlalchemy/engine/url.py | |
parent | 2800e34710672b408fa4a7bdd6d58d63a7128f04 (diff) | |
download | sqlalchemy-6029496bd3fb78caeab349ef8df5b58f058db16e.tar.gz |
- adjustment, the spec says: "Within the user and password field, any ":",
"@", or "/" must be encoded." - so re-apply encoding to both password
and username, don't encode spaces as plus signs, don't encode any chars
outside of :, @, / on stringification - but we still parse for any
%XX character (is that right?)
Diffstat (limited to 'lib/sqlalchemy/engine/url.py')
-rw-r--r-- | lib/sqlalchemy/engine/url.py | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 28c15299e..77fbe2346 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -65,9 +65,10 @@ class URL(object): def __to_string__(self, hide_password=True): s = self.drivername + "://" if self.username is not None: - s += self.username + s += _rfc_1738_quote(self.username) if self.password is not None: - s += ':' + ('***' if hide_password else self.password) + s += ':' + ('***' if hide_password + else _rfc_1738_quote(self.password)) s += "@" if self.host is not None: if ':' in self.host: @@ -194,6 +195,12 @@ def _parse_rfc1738_args(name): query = None components['query'] = query + if components['username'] is not None: + components['username'] = _rfc_1738_unquote(components['username']) + + if components['password'] is not None: + components['password'] = _rfc_1738_unquote(components['password']) + ipv4host = components.pop('ipv4host') ipv6host = components.pop('ipv6host') components['host'] = ipv4host or ipv6host @@ -204,6 +211,12 @@ def _parse_rfc1738_args(name): "Could not parse rfc1738 URL from string '%s'" % name) +def _rfc_1738_quote(text): + return re.sub(r'[:@/]', lambda m: "%%%X" % ord(m.group(0)), text) + +def _rfc_1738_unquote(text): + return util.unquote(text) + def _parse_keyvalue_args(name): m = re.match(r'(\w+)://(.*)', name) if m is not None: |