From c15818f1e6f77119b57d2646c291d694cebd2698 Mon Sep 17 00:00:00 2001 From: Florent Vennetier Date: Mon, 27 Sep 2021 18:43:42 +0200 Subject: [PATCH] s3api: fix the copy of non-ASCII objects Trying to copy an object with non-ASCII characters in its name results in, depending on the pipeline: - an error code 412 because of a badly urlencoded path - an error code 500 "TypeError: Expected a WSGI string" This commit fixes the problem by calling str_to_wsgi on the object name after it has been urldecoded. We do not need to call this on the container name because it is supposed to contain only ASCII characters. Change-Id: If837d4e55735b10a783c85d91f37fbea5e3baf1d --- swift/common/middleware/s3api/s3request.py | 3 ++- test/functional/s3api/test_object.py | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py index 2d1f7f2871..d4c33512de 100644 --- a/swift/common/middleware/s3api/s3request.py +++ b/swift/common/middleware/s3api/s3request.py @@ -910,7 +910,8 @@ class S3Request(swob.Request): headers = swob.HeaderKeyDict() headers.update(self._copy_source_headers()) - src_resp = self.get_response(app, 'HEAD', src_bucket, src_obj, + src_resp = self.get_response(app, 'HEAD', src_bucket, + swob.str_to_wsgi(src_obj), headers=headers, query=query) if src_resp.status_int == 304: # pylint: disable-msg=E1101 raise PreconditionFailed() diff --git a/test/functional/s3api/test_object.py b/test/functional/s3api/test_object.py index f5e78b0785..f8245318ef 100644 --- a/test/functional/s3api/test_object.py +++ b/test/functional/s3api/test_object.py @@ -1,4 +1,5 @@ -# Copyright (c) 2015 OpenStack Foundation +# -*- coding: utf-8 -*- +# Copyright (c) 2015-2021 OpenStack Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,12 +26,11 @@ import email.parser from email.utils import formatdate, parsedate from time import mktime import six -from six.moves.urllib.parse import quote import test.functional as tf from swift.common.middleware.s3api.etree import fromstring -from swift.common.utils import md5 +from swift.common.utils import md5, quote from test.functional.s3api import S3ApiBase from test.functional.s3api.s3_test_client import Connection @@ -59,7 +59,7 @@ class TestS3ApiObject(S3ApiBase): self.assertCommonResponseHeaders(headers, etag) def test_object(self): - obj = 'object name with %-sign' + obj = u'object name with %-sign 🙂' content = b'abc123' etag = md5(content, usedforsecurity=False).hexdigest()