Fixes bug where "/" was not allowed in Destination header in COPY requests
This commit is contained in:
commit
8ed75703fc
@ -618,7 +618,7 @@ class ObjectController(Controller):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return HTTPPreconditionFailed(request=req,
|
return HTTPPreconditionFailed(request=req,
|
||||||
body='X-Copy-From header must be of the form'
|
body='X-Copy-From header must be of the form'
|
||||||
'container/object')
|
'<container name>/<object name>')
|
||||||
source_req = Request.blank(source_header)
|
source_req = Request.blank(source_header)
|
||||||
orig_obj_name = self.object_name
|
orig_obj_name = self.object_name
|
||||||
orig_container_name = self.container_name
|
orig_container_name = self.container_name
|
||||||
@ -809,11 +809,11 @@ class ObjectController(Controller):
|
|||||||
if not dest.startswith('/'):
|
if not dest.startswith('/'):
|
||||||
dest = '/' + dest
|
dest = '/' + dest
|
||||||
try:
|
try:
|
||||||
_, dest_container, dest_object = dest.split('/', 3)
|
_, dest_container, dest_object = dest.split('/', 2)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return HTTPPreconditionFailed(request=req,
|
return HTTPPreconditionFailed(request=req,
|
||||||
body='Destination header must be of the form '
|
body='Destination header must be of the form '
|
||||||
'container/object')
|
'<container name>/<object name>')
|
||||||
new_source = '/' + self.container_name + '/' + self.object_name
|
new_source = '/' + self.container_name + '/' + self.object_name
|
||||||
self.container_name = dest_container
|
self.container_name = dest_container
|
||||||
self.object_name = dest_object
|
self.object_name = dest_object
|
||||||
|
@ -1014,6 +1014,18 @@ class TestObjectController(unittest.TestCase):
|
|||||||
self.assertEquals(resp.status_int, 201)
|
self.assertEquals(resp.status_int, 201)
|
||||||
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
|
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||||
|
headers={'Content-Length': '0',
|
||||||
|
'X-Copy-From': 'c/o/o2'})
|
||||||
|
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/o2')
|
||||||
|
|
||||||
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||||
headers={'Content-Length': '0',
|
headers={'Content-Length': '0',
|
||||||
'X-Copy-From': '/c/o'})
|
'X-Copy-From': '/c/o'})
|
||||||
@ -1026,6 +1038,18 @@ class TestObjectController(unittest.TestCase):
|
|||||||
self.assertEquals(resp.status_int, 201)
|
self.assertEquals(resp.status_int, 201)
|
||||||
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
|
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||||
|
headers={'Content-Length': '0',
|
||||||
|
'X-Copy-From': '/c/o/o2'})
|
||||||
|
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/o2')
|
||||||
|
|
||||||
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||||
headers={'Content-Length': '0',
|
headers={'Content-Length': '0',
|
||||||
'X-Copy-From': '/c/o'})
|
'X-Copy-From': '/c/o'})
|
||||||
@ -1073,6 +1097,123 @@ class TestObjectController(unittest.TestCase):
|
|||||||
self.assertEquals(resp.headers.get('x-object-meta-test'), 'testing')
|
self.assertEquals(resp.headers.get('x-object-meta-test'), 'testing')
|
||||||
self.assertEquals(resp.headers.get('x-object-meta-ours'), 'okay')
|
self.assertEquals(resp.headers.get('x-object-meta-ours'), 'okay')
|
||||||
|
|
||||||
|
def test_COPY(self):
|
||||||
|
with save_globals():
|
||||||
|
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
|
||||||
|
headers={'Content-Length': '0'})
|
||||||
|
req.account = 'a'
|
||||||
|
proxy_server.http_connect = \
|
||||||
|
fake_http_connect(200, 200, 201, 201, 201)
|
||||||
|
# acct cont obj obj obj
|
||||||
|
resp = controller.PUT(req)
|
||||||
|
self.assertEquals(resp.status_int, 201)
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': 'c/o'})
|
||||||
|
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.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 201)
|
||||||
|
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o/o2', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': 'c/o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o/o2'
|
||||||
|
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.COPY(req)
|
||||||
|
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': 'COPY'},
|
||||||
|
headers={'Destination': '/c/o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o'
|
||||||
|
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.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 201)
|
||||||
|
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o/o2', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': '/c/o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o/o2'
|
||||||
|
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.COPY(req)
|
||||||
|
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': 'COPY'},
|
||||||
|
headers={'Destination': 'c_o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o'
|
||||||
|
proxy_server.http_connect = \
|
||||||
|
fake_http_connect(200, 200)
|
||||||
|
# acct cont
|
||||||
|
self.app.memcache.store = {}
|
||||||
|
resp = controller.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 412)
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': '/c/o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o'
|
||||||
|
proxy_server.http_connect = \
|
||||||
|
fake_http_connect(200, 200, 503, 503, 503)
|
||||||
|
# acct cont objc objc objc
|
||||||
|
self.app.memcache.store = {}
|
||||||
|
resp = controller.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 503)
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': '/c/o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o'
|
||||||
|
proxy_server.http_connect = \
|
||||||
|
fake_http_connect(200, 200, 404, 404, 404)
|
||||||
|
# acct cont objc objc objc
|
||||||
|
self.app.memcache.store = {}
|
||||||
|
resp = controller.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 404)
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': '/c/o'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o'
|
||||||
|
proxy_server.http_connect = \
|
||||||
|
fake_http_connect(200, 200, 404, 404, 200, 201, 201, 201)
|
||||||
|
# acct cont objc objc objc obj obj obj
|
||||||
|
self.app.memcache.store = {}
|
||||||
|
resp = controller.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 201)
|
||||||
|
|
||||||
|
req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
|
||||||
|
headers={'Destination': '/c/o',
|
||||||
|
'X-Object-Meta-Ours': 'okay'})
|
||||||
|
req.account = 'a'
|
||||||
|
controller.object_name = 'o'
|
||||||
|
proxy_server.http_connect = \
|
||||||
|
fake_http_connect(200, 200, 200, 201, 201, 201)
|
||||||
|
# acct cont objc obj obj obj
|
||||||
|
self.app.memcache.store = {}
|
||||||
|
resp = controller.COPY(req)
|
||||||
|
self.assertEquals(resp.status_int, 201)
|
||||||
|
self.assertEquals(resp.headers.get('x-object-meta-test'), 'testing')
|
||||||
|
self.assertEquals(resp.headers.get('x-object-meta-ours'), 'okay')
|
||||||
|
|
||||||
def test_chunked_put_and_a_bit_more(self):
|
def test_chunked_put_and_a_bit_more(self):
|
||||||
# Since we're starting up a lot here, we're going to test more than
|
# Since we're starting up a lot here, we're going to test more than
|
||||||
# just chunked puts; we're also going to test parts of
|
# just chunked puts; we're also going to test parts of
|
||||||
|
Loading…
x
Reference in New Issue
Block a user