Support urlencoding/decoding for hostname (#181)

* Use URL Parse library to decode % encodes

Use URL Parse library for what it's good for: to decode % URL encode strings. Don't do it here -- we're already importing a better library for that!

* Test revision with Google Cloud SQL connector

Add synthetic test correlating to Google Cloud SQL connector socket, to make sure Issue https://github.com/jacobian/dj-database-url/issues/132 is solved

Co-authored-by: jared-hardy <jaredhardy@gmail.com>
This commit is contained in:
Mike 2022-12-12 12:18:02 -08:00 committed by GitHub
parent d2e4719a8d
commit e0cd4c10b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 5 deletions

View file

@ -162,7 +162,7 @@ URL schema
+----------------------+-----------------------------------------------+--------------------------------------------------+
| MSSQL [5]_ | ``mssql`` | ``mssqlms://USER:PASSWORD@HOST:PORT/NAME`` |
+----------------------+-----------------------------------------------+--------------------------------------------------+
| MySQL | ``django.db.backends.mysql`` | ``mysql://USER:PASSWORD@HOST:PORT/NAME`` |
| MySQL | ``django.db.backends.mysql`` | ``mysql://USER:PASSWORD@HOST:PORT/NAME`` [2]_ |
+----------------------+-----------------------------------------------+--------------------------------------------------+
| MySQL (GIS) | ``django.contrib.gis.db.backends.mysql`` | ``mysqlgis://USER:PASSWORD@HOST:PORT/NAME`` |
+----------------------+-----------------------------------------------+--------------------------------------------------+
@ -185,9 +185,10 @@ URL schema
.. [1] The django.db.backends.postgresql backend is named django.db.backends.postgresql_psycopg2 in older releases. For
backwards compatibility, the old name still works in newer versions. (The new name does not work in older versions).
.. [2] With PostgreSQL, you can also use unix domain socket paths with
.. [2] With PostgreSQL or CloudSQL, you can also use unix domain socket paths with
`percent encoding <http://www.postgresql.org/docs/9.2/interactive/libpq-connect.html#AEN38162>`_:
``postgres://%2Fvar%2Flib%2Fpostgresql/dbname``.
``postgres://%2Fvar%2Flib%2Fpostgresql/dbname``
``mysql://uf07k1i6d8ia0v@%2fcloudsql%2fproject%3alocation%3ainstance/dbname``
.. [3] SQLite connects to file based databases. The same URL format is used, omitting
the hostname, and using the "file" portion as the filename of the database.
This has the effect of four slashes being present for an absolute file path:

View file

@ -102,14 +102,15 @@ def parse(
# Handle postgres percent-encoded paths.
hostname = url.hostname or ""
if "%2f" in hostname.lower():
if "%" in hostname:
# Switch to url.netloc to avoid lower cased paths
hostname = url.netloc
if "@" in hostname:
hostname = hostname.rsplit("@", 1)[1]
if ":" in hostname:
hostname = hostname.split(":", 1)[0]
hostname = hostname.replace("%2f", "/").replace("%2F", "/")
# Use URL Parse library to decode % encodes
hostname = urlparse.unquote(hostname)
# Lookup specified engine.
engine = SCHEMES[url.scheme] if engine is None else engine

View file

@ -38,6 +38,17 @@ class DatabaseTestSuite(unittest.TestCase):
assert url["PASSWORD"] == ""
assert url["PORT"] == ""
def test_postgres_google_cloud_parsing(self):
url = "postgres://uf07k1i6d8ia0v:wegauwhgeuioweg@%2Fcloudsql%2Fproject_id%3Aregion%3Ainstance_id/d8r82722r2kuvn"
url = dj_database_url.parse(url)
assert url["ENGINE"] == "django.db.backends.postgresql"
assert url["NAME"] == "d8r82722r2kuvn"
assert url["HOST"] == "/cloudsql/project_id:region:instance_id"
assert url["USER"] == "uf07k1i6d8ia0v"
assert url["PASSWORD"] == "wegauwhgeuioweg"
assert url["PORT"] == ""
def test_ipv6_parsing(self):
url = "postgres://ieRaekei9wilaim7:wegauwhgeuioweg@[2001:db8:1234::1234:5678:90af]:5431/d8r82722r2kuvn"
url = dj_database_url.parse(url)