summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/url.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-11-25 14:46:58 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2013-11-25 14:46:58 -0500
commit6029496bd3fb78caeab349ef8df5b58f058db16e (patch)
tree9c218dbec71973452daa585cf1db6caa034e8571 /lib/sqlalchemy/engine/url.py
parent2800e34710672b408fa4a7bdd6d58d63a7128f04 (diff)
downloadsqlalchemy-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.py17
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: