PUT with X-Copy-From header and a non-zero Content-Length will now error as a 400

This commit is contained in:
John Dickinson 2010-10-28 20:27:21 +00:00 committed by Tarmac
commit 937554c85e
3 changed files with 31 additions and 3 deletions

View File

@ -100,6 +100,9 @@ def check_object_creation(req, object_name):
if req.content_length is None and \
req.headers.get('transfer-encoding') != 'chunked':
return HTTPLengthRequired(request=req)
if 'X-Copy-From' in req.headers and req.content_length:
return HTTPBadRequest(body='Copy requests require a zero byte body',
request=req, content_type='text/plain')
if len(object_name) > MAX_OBJECT_NAME_LENGTH:
return HTTPBadRequest(body='Object name length of %d longer than %d' %
(len(object_name), MAX_OBJECT_NAME_LENGTH), request=req,

View File

@ -644,7 +644,8 @@ class ObjectController(Controller):
environ=req.environ, headers=req.headers)
new_req.content_length = source_resp.content_length
new_req.etag = source_resp.etag
new_req.headers['X-Copy-From'] = source_header.split('/', 2)[2]
# we no longer need the X-Copy-From header
del new_req.headers['X-Copy-From']
for k, v in source_resp.headers.items():
if k.lower().startswith('x-object-meta-'):
new_req.headers[k] = v
@ -767,8 +768,9 @@ class ObjectController(Controller):
bodies.append('')
resp = self.best_response(req, statuses, reasons, bodies, 'Object PUT',
etag=etag)
if 'x-copy-from' in req.headers:
resp.headers['X-Copied-From'] = req.headers['x-copy-from']
if source_header:
resp.headers['X-Copied-From'] = quote(
source_header.split('/', 2)[2])
for k, v in req.headers.items():
if k.lower().startswith('x-object-meta-'):
resp.headers[k] = v

View File

@ -1089,6 +1089,17 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '5',
'X-Copy-From': 'c/o'})
self.app.update_request(req)
proxy_server.http_connect = \
fake_http_connect(200, 200, 200, 200, 200)
# acct cont acct cont objc
self.app.memcache.store = {}
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 400)
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': 'c/o/o2'})
@ -1101,6 +1112,18 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o/o2')
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': 'c/o%20o2'})
req.account = 'a'
proxy_server.http_connect = \
fake_http_connect(200, 200, 200, 200, 200, 201, 201, 201)
# acct cont acct cont objc obj obj obj
self.app.memcache.store = {}
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o%20o2')
# repeat tests with leading /
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',