diff --git a/swift/common/constraints.py b/swift/common/constraints.py index 880a9dfb32..f1d300a032 100644 --- a/swift/common/constraints.py +++ b/swift/common/constraints.py @@ -80,7 +80,9 @@ def check_metadata(req, target_type): meta_size = 0 for key, value in req.headers.iteritems(): if isinstance(value, basestring) and len(value) > MAX_HEADER_SIZE: - return HTTPBadRequest('Header Line Too Long') + return HTTPBadRequest(body='Header value too long: %s' % + key[:MAX_META_NAME_LENGTH], + request=req, content_type='text/plain') if not key.lower().startswith(prefix): continue key = key[len(prefix):] @@ -91,11 +93,12 @@ def check_metadata(req, target_type): meta_size += len(key) + len(value) if len(key) > MAX_META_NAME_LENGTH: return HTTPBadRequest( - body='Metadata name too long; max %d' % MAX_META_NAME_LENGTH, + body='Metadata name too long: %s%s' % (prefix, key), request=req, content_type='text/plain') elif len(value) > MAX_META_VALUE_LENGTH: return HTTPBadRequest( - body='Metadata value too long; max %d' % MAX_META_VALUE_LENGTH, + body='Metadata value longer than %d: %s%s' % ( + MAX_META_VALUE_LENGTH, prefix, key), request=req, content_type='text/plain') elif meta_count > MAX_META_COUNT: return HTTPBadRequest( diff --git a/test/unit/common/test_constraints.py b/test/unit/common/test_constraints.py index ff86277009..52a6a20e2d 100644 --- a/test/unit/common/test_constraints.py +++ b/test/unit/common/test_constraints.py @@ -26,6 +26,13 @@ from swift.common import constraints class TestConstraints(unittest.TestCase): + def assertIn(self, member, container, msg=None): + """Copied from 2.7""" + if member not in container: + standardMsg = '%s not found in %s' % (safe_repr(member), + safe_repr(container)) + self.fail(self._formatMessage(msg, standardMsg)) + def test_check_metadata_empty(self): headers = {} self.assertEquals(constraints.check_metadata(Request.blank('/', @@ -50,6 +57,9 @@ class TestConstraints(unittest.TestCase): headers = {'X-Object-Meta-%s' % name: 'v'} self.assertEquals(constraints.check_metadata(Request.blank('/', headers=headers), 'object').status_int, HTTP_BAD_REQUEST) + self.assertIn(('X-Object-Meta-%s' % name).lower(), + constraints.check_metadata(Request.blank('/', headers=headers), + 'object').body.lower()) def test_check_metadata_value_length(self): value = 'a' * constraints.MAX_META_VALUE_LENGTH @@ -60,6 +70,12 @@ class TestConstraints(unittest.TestCase): headers = {'X-Object-Meta-Name': value} self.assertEquals(constraints.check_metadata(Request.blank('/', headers=headers), 'object').status_int, HTTP_BAD_REQUEST) + self.assertIn('x-object-meta-name', + constraints.check_metadata(Request.blank('/', headers=headers), + 'object').body.lower()) + self.assertIn(str(constraints.MAX_META_VALUE_LENGTH), + constraints.check_metadata(Request.blank('/', headers=headers), + 'object').body) def test_check_metadata_count(self): headers = {} @@ -210,6 +226,8 @@ class TestConstraints(unittest.TestCase): 'ab' * constraints.MAX_HEADER_SIZE}) self.assertEquals(constraints.check_metadata(req, 'object').status_int, HTTP_BAD_REQUEST) + self.assertIn('x-object-meta-hello', constraints.check_metadata(req, + 'object').body.lower()) def test_validate_constraints(self): c = constraints