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 import six
from swift.common import constraints
from swift.common.swob import Range, bytes_to_wsgi, normalize_etag, wsgi_to_str 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.utils import json, public, reiterate, md5
from swift.common.db import utf8encode 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, \ from swift.common.middleware.s3api.controllers.base import Controller, \
bucket_operation, object_operation, check_container_existence bucket_operation, object_operation, check_container_existence
from swift.common.middleware.s3api.s3response import InvalidArgument, \ from swift.common.middleware.s3api.s3response import InvalidArgument, \
ErrorResponse, MalformedXML, BadDigest, \ ErrorResponse, MalformedXML, BadDigest, KeyTooLongError, \
InvalidPart, BucketAlreadyExists, EntityTooSmall, InvalidPartOrder, \ InvalidPart, BucketAlreadyExists, EntityTooSmall, InvalidPartOrder, \
InvalidRequest, HTTPOk, HTTPNoContent, NoSuchKey, NoSuchUpload, \ InvalidRequest, HTTPOk, HTTPNoContent, NoSuchKey, NoSuchUpload, \
NoSuchBucket, BucketAlreadyOwnedByYou NoSuchBucket, BucketAlreadyOwnedByYou
@ -403,6 +404,11 @@ class UploadsController(Controller):
""" """
Handles Initiate Multipart Upload. 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. # Create a unique S3 upload id from UUID to avoid duplicates.
upload_id = unique_id() upload_id = unique_id()

View File

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

View File

@ -503,7 +503,7 @@ class InvalidURI(ErrorResponse):
ErrorResponse.__init__(self, msg, uri=uri, *args, **kwargs) ErrorResponse.__init__(self, msg, uri=uri, *args, **kwargs)
class KeyTooLong(ErrorResponse): class KeyTooLongError(ErrorResponse):
_status = '400 Bad Request' _status = '400 Bad Request'
_msg = 'Your key is too long.' _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.conn.make_request('POST', 'nothing', key, query=query)
self.assertEqual(get_error_code(body), 'NoSuchBucket') 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): def test_list_multi_uploads_error(self):
bucket = 'bucket' bucket = 'bucket'
self.conn.make_request('PUT', 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(get_error_code(body), 'NoSuchBucket')
self.assertEqual(headers['content-type'], 'application/xml') 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): def test_put_object_copy_error(self):
obj = 'object' obj = 'object'
self.conn.make_request('PUT', self.bucket, obj) self.conn.make_request('PUT', self.bucket, obj)