Merge "s3api: Return KeyTooLongError when upload name exceeds constraints"

This commit is contained in:
Zuul 2021-07-27 18:48:21 +00:00 committed by Gerrit Code Review
commit 660e8386dd
5 changed files with 25 additions and 3 deletions

View File

@ -67,6 +67,7 @@ import time
import six
from swift.common import constraints
from swift.common.swob import Range, bytes_to_wsgi, normalize_etag, wsgi_to_str
from swift.common.utils import json, public, reiterate, md5
from swift.common.db import utf8encode
@ -77,7 +78,7 @@ from six.moves.urllib.parse import quote, urlparse
from swift.common.middleware.s3api.controllers.base import Controller, \
bucket_operation, object_operation, check_container_existence
from swift.common.middleware.s3api.s3response import InvalidArgument, \
ErrorResponse, MalformedXML, BadDigest, \
ErrorResponse, MalformedXML, BadDigest, KeyTooLongError, \
InvalidPart, BucketAlreadyExists, EntityTooSmall, InvalidPartOrder, \
InvalidRequest, HTTPOk, HTTPNoContent, NoSuchKey, NoSuchUpload, \
NoSuchBucket, BucketAlreadyOwnedByYou
@ -403,6 +404,11 @@ class UploadsController(Controller):
"""
Handles Initiate Multipart Upload.
"""
if len(req.object_name) > constraints.MAX_OBJECT_NAME_LENGTH:
# Note that we can still run into trouble where the MPU is just
# within the limit, which means the segment names will go over
raise KeyTooLongError()
# Create a unique S3 upload id from UUID to avoid duplicates.
upload_id = unique_id()

View File

@ -15,6 +15,7 @@
import json
from swift.common import constraints
from swift.common.http import HTTP_OK, HTTP_PARTIAL_CONTENT, HTTP_NO_CONTENT
from swift.common.request_helpers import update_etag_is_at_header
from swift.common.swob import Range, content_range_header_value, \
@ -27,7 +28,7 @@ from swift.common.middleware.s3api.utils import S3Timestamp, sysmeta_header
from swift.common.middleware.s3api.controllers.base import Controller
from swift.common.middleware.s3api.s3response import S3NotImplemented, \
InvalidRange, NoSuchKey, NoSuchVersion, InvalidArgument, HTTPNoContent, \
PreconditionFailed
PreconditionFailed, KeyTooLongError
class ObjectController(Controller):
@ -138,6 +139,8 @@ class ObjectController(Controller):
"""
Handle PUT Object and PUT Object (Copy) request
"""
if len(req.object_name) > constraints.MAX_OBJECT_NAME_LENGTH:
raise KeyTooLongError()
# set X-Timestamp by s3api to use at copy resp body
req_timestamp = S3Timestamp.now()
req.headers['X-Timestamp'] = req_timestamp.internal

View File

@ -503,7 +503,7 @@ class InvalidURI(ErrorResponse):
ErrorResponse.__init__(self, msg, uri=uri, *args, **kwargs)
class KeyTooLong(ErrorResponse):
class KeyTooLongError(ErrorResponse):
_status = '400 Bad Request'
_msg = 'Your key is too long.'

View File

@ -475,6 +475,12 @@ class TestS3ApiMultiUpload(S3ApiBase):
self.conn.make_request('POST', 'nothing', key, query=query)
self.assertEqual(get_error_code(body), 'NoSuchBucket')
status, resp_headers, body = self.conn.make_request(
'POST', bucket,
'x' * (tf.cluster_info['swift']['max_object_name_length'] + 1),
query=query)
self.assertEqual(get_error_code(body), 'KeyTooLongError')
def test_list_multi_uploads_error(self):
bucket = 'bucket'
self.conn.make_request('PUT', bucket)

View File

@ -158,6 +158,13 @@ class TestS3ApiObject(S3ApiBase):
self.assertEqual(get_error_code(body), 'NoSuchBucket')
self.assertEqual(headers['content-type'], 'application/xml')
def test_put_object_name_too_long(self):
status, headers, body = self.conn.make_request(
'PUT', self.bucket,
'x' * (tf.cluster_info['swift']['max_object_name_length'] + 1))
self.assertEqual(get_error_code(body), 'KeyTooLongError')
self.assertEqual(headers['content-type'], 'application/xml')
def test_put_object_copy_error(self):
obj = 'object'
self.conn.make_request('PUT', self.bucket, obj)