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
This commit is contained in:
Florent Vennetier 2021-09-27 18:43:42 +02:00 committed by Tim Burke
parent 029e57679c
commit c15818f1e6
2 changed files with 6 additions and 5 deletions

View File

@ -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()

View File

@ -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()