diff --git a/minio/compat.py b/minio/compat.py index 1743eef48..ae5e9649a 100644 --- a/minio/compat.py +++ b/minio/compat.py @@ -40,15 +40,9 @@ from Queue import Empty queue_empty = Empty - from urllib import quote - _urlencode = quote + from urllib import quote, unquote - from urllib import unquote - urldecode = unquote - - import urlparse - urlsplit = urlparse.urlsplit - parse_qs = urlparse.parse_qs + from urlparse import urlsplit, parse_qs ## Create missing types. bytes = str @@ -68,15 +62,7 @@ from queue import Empty queue_empty = Empty - from urllib.request import quote - _urlencode = quote - - from urllib.request import unquote - urldecode = unquote - - import urllib.parse - urlsplit = urllib.parse.urlsplit - parse_qs = urllib.parse.parse_qs + from urllib.parse import quote, unquote, urlsplit, parse_qs ## Create types to compat with py2. builtin_range = range @@ -93,16 +79,19 @@ numeric_types = (int, long, float) -def urlencode(resource): + +# Note earlier versions of minio.compat exposed urllib.quote as urlencode +def _quote(resource): """ - This implementation of urlencode supports all unicode characters + This implementation of urllib.quote supports all unicode characters :param: resource: Resource value to be url encoded. """ if isinstance(resource, str): - return _urlencode(resource.encode('utf-8')) + return quote(resource.encode('utf-8')) + + return quote(resource) - return _urlencode(resource) def queryencode(query): """ @@ -110,4 +99,4 @@ def queryencode(query): :param: query: Query value to be url encoded. """ - return urlencode(query).replace('/', '%2F') + return _quote(query).replace('/', '%2F') diff --git a/minio/helpers.py b/minio/helpers.py index 61e960c64..5eb57ad20 100644 --- a/minio/helpers.py +++ b/minio/helpers.py @@ -42,7 +42,7 @@ import errno import math -from .compat import (urlsplit, urlencode, queryencode, +from .compat import (urlsplit, _quote, queryencode, str, bytes, basestring, _is_py3, _is_py2) from .error import (InvalidBucketError, InvalidEndpointError, InvalidArgumentError) @@ -599,7 +599,7 @@ def encode_object_name(object_name): :return: URL encoded input object name. """ is_non_empty_string(object_name) - return urlencode(object_name) + return _quote(object_name) class Hasher(object): """ diff --git a/minio/parsers.py b/minio/parsers.py index ee05facec..a6e5d90df 100644 --- a/minio/parsers.py +++ b/minio/parsers.py @@ -35,7 +35,7 @@ # minio specific. from .error import (ETREE_EXCEPTIONS, InvalidXMLError, MultiDeleteError) -from .compat import urldecode +from .compat import unquote from .definitions import (Object, Bucket, IncompleteUpload, UploadPart, MultipartUploadResult, CopyObjectResult) @@ -112,7 +112,7 @@ def get_urldecoded_elem_text(self, name, strict=True): """ text = self.get_child_text(name, strict) # strictness is already enforced above. - return urldecode(text) if text is not None else None + return unquote(text) if text is not None else None def get_etag_elem(self, strict=True): """Fetches an 'ETag' child element suitably processed. diff --git a/tests/unit/sign_test.py b/tests/unit/sign_test.py index 8c3ca6495..42624c6c8 100644 --- a/tests/unit/sign_test.py +++ b/tests/unit/sign_test.py @@ -24,7 +24,7 @@ generate_signing_key, generate_authorization_header, presign_v4, sign_v4) from minio.error import InvalidArgumentError -from minio.compat import urlsplit, urlencode, queryencode +from minio.compat import urlsplit, _quote, queryencode from minio.fold_case_dict import FoldCaseDict from minio.credentials import Credentials, Static from minio.helpers import get_target_url @@ -139,20 +139,20 @@ def test_signv4(self): eq_(hdrs['Authorization'], 'AWS4-HMAC-SHA256 Credential=minio/20150620/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=a2f4546f647981732bd90dfa5a7599c44dca92f44bea48ecc7565df06032c25b') class UnicodeEncodeTest(TestCase): - def test_unicode_urlencode(self): - eq_(urlencode('/test/123/汉字'), '/test/123/%E6%B1%89%E5%AD%97') + def test_unicode_quote(self): + eq_(_quote('/test/123/汉字'), '/test/123/%E6%B1%89%E5%AD%97') def test_unicode_queryencode(self): eq_(queryencode('/test/123/汉字'), '%2Ftest%2F123%2F%E6%B1%89%E5%AD%97') - def test_unicode_urlencode_u(self): - eq_(urlencode(u'/test/123/汉字'), '/test/123/%E6%B1%89%E5%AD%97') + def test_unicode_quote_u(self): + eq_(_quote(u'/test/123/汉字'), '/test/123/%E6%B1%89%E5%AD%97') def test_unicode_queryencode_u(self): eq_(queryencode(u'/test/123/汉字'), '%2Ftest%2F123%2F%E6%B1%89%E5%AD%97') - def test_unicode_urlencode_b(self): - eq_(urlencode(b'/test/123/\xe6\xb1\x89\xe5\xad\x97'), '/test/123/%E6%B1%89%E5%AD%97') + def test_unicode_quote_b(self): + eq_(_quote(b'/test/123/\xe6\xb1\x89\xe5\xad\x97'), '/test/123/%E6%B1%89%E5%AD%97') def test_unicode_queryencode_b(self): eq_(queryencode(b'/test/123/\xe6\xb1\x89\xe5\xad\x97'), '%2Ftest%2F123%2F%E6%B1%89%E5%AD%97')