From 65f8a559db8a2436f96b0ccb9aa1c71e9348071b Mon Sep 17 00:00:00 2001 From: vinay karanam Date: Thu, 9 Sep 2021 07:54:49 +0530 Subject: [PATCH] S3Boto3Storage with custom domain now accepts url parameters (#1054) --- storages/backends/s3boto3.py | 12 ++++++++---- tests/test_s3boto3.py | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/storages/backends/s3boto3.py b/storages/backends/s3boto3.py index 1e7f19f0b..72b2b6653 100644 --- a/storages/backends/s3boto3.py +++ b/storages/backends/s3boto3.py @@ -7,7 +7,7 @@ from datetime import datetime, timedelta from gzip import GzipFile from tempfile import SpooledTemporaryFile -from urllib.parse import parse_qsl, urlsplit +from urllib.parse import parse_qsl, urlencode, urlsplit from django.contrib.staticfiles.storage import ManifestFilesMixin from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation @@ -559,12 +559,17 @@ def _strip_signing_parameters(self, url): def url(self, name, parameters=None, expire=None, http_method=None): # Preserve the trailing slash after normalizing the path. name = self._normalize_name(self._clean_name(name)) + params = parameters.copy() if parameters else {} if expire is None: expire = self.querystring_expire if self.custom_domain: - url = "{}//{}/{}".format( - self.url_protocol, self.custom_domain, filepath_to_uri(name)) + url = "{}//{}/{}{}".format( + self.url_protocol, + self.custom_domain, + filepath_to_uri(name), + "?{}".format(urlencode(params)) if params else "", + ) if self.querystring_auth and self.cloudfront_signer: expiration = datetime.utcnow() + timedelta(seconds=expire) @@ -573,7 +578,6 @@ def url(self, name, parameters=None, expire=None, http_method=None): return url - params = parameters.copy() if parameters else {} params['Bucket'] = self.bucket.name params['Key'] = name url = self.bucket.meta.client.generate_presigned_url('get_object', Params=params, diff --git a/tests/test_s3boto3.py b/tests/test_s3boto3.py index 513113ac0..f128c4ca3 100644 --- a/tests/test_s3boto3.py +++ b/tests/test_s3boto3.py @@ -627,6 +627,14 @@ def test_special_characters(self): parsed_url = urlparse(url) self.assertEqual(parsed_url.path, "/%C3%A3l%C3%B6h%C3%A2.jpg") + def test_custom_domain_parameters(self): + self.storage.custom_domain = "mock.cloudfront.net" + filename = "filename.mp4" + url = self.storage.url(filename, parameters={"version": 10}) + parsed_url = urlparse(url) + self.assertEqual(parsed_url.path, "/filename.mp4") + self.assertEqual(parsed_url.query, "version=10") + def test_strip_signing_parameters(self): expected = 'http://bucket.s3-aws-region.amazonaws.com/foo/bar' self.assertEqual(self.storage._strip_signing_parameters(