Merge "s3api: Return KeyTooLongError when upload name exceeds constraints"
This commit is contained in:
commit
660e8386dd
@ -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()
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.'
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user