Fix conflict SLO reponse
This patch fixes Swift to respond "409 Conflict" when a segment object path of the manifest on PUT SLO is same as requested object path. It is because the request will overwrite the segment and then it will absolutely cause "409 Conflict" on GET SLO. e.g.: request: PUT "http://hostname/v1/AUTH_account/container/segment_object_00?multipart-manifest=put" manifest file: [{"path" : "container/segment_object_00", "etag" : "<etag of segment_object_00>", "size_bytes" : <size of segment_object_00>}, {"path" : "container/segment_object_01", "etag" : "<etag of segment_object_01>", "size_bytes" : <size of segment_object_01>}, {"path" : "container/segment_object_02", "etag" : "<etag of segment_object_02>", "size_bytes" : <size of segment_object_02>}] Change-Id: I4f4f7b9dbeb6a7c355b801c7e0ae560aa19a70b4 Closes-Bug: 1417936
This commit is contained in:
parent
399a66fb12
commit
e4d326b5a7
1
AUTHORS
1
AUTHORS
@ -223,3 +223,4 @@ Hua Zhang (zhuadl@cn.ibm.com)
|
||||
Jian Zhang (jian.zhang@intel.com)
|
||||
Ning Zhang (ning@zmanda.com)
|
||||
Yuan Zhou (yuan.zhou@intel.com)
|
||||
Kazuhiro Miyahara (miyahara.kazuhiro@lab.ntt.co.jp)
|
||||
|
@ -586,6 +586,11 @@ class StaticLargeObject(object):
|
||||
if isinstance(obj_name, unicode):
|
||||
obj_name = obj_name.encode('utf-8')
|
||||
obj_path = '/'.join(['', vrs, account, obj_name.lstrip('/')])
|
||||
if req.path == quote(obj_path):
|
||||
raise HTTPConflict(
|
||||
'Manifest object name "%s" '
|
||||
'cannot be included in the manifest'
|
||||
% obj_name)
|
||||
try:
|
||||
seg_size = int(seg_dict['size_bytes'])
|
||||
except (ValueError, TypeError):
|
||||
|
@ -24,7 +24,7 @@ from swift.common import swob, utils
|
||||
from swift.common.exceptions import ListingIterError, SegmentError
|
||||
from swift.common.middleware import slo
|
||||
from swift.common.swob import Request, Response, HTTPException
|
||||
from swift.common.utils import json
|
||||
from swift.common.utils import quote, json
|
||||
from test.unit.common.middleware.helpers import FakeSwift
|
||||
|
||||
|
||||
@ -139,6 +139,11 @@ class TestSloPutManifest(SloTestCase):
|
||||
swob.HTTPOk,
|
||||
{'Content-Length': '100', 'Etag': 'etagoftheobjectsegment'},
|
||||
None)
|
||||
self.app.register(
|
||||
'HEAD', '/v1/AUTH_test/cont/object2',
|
||||
swob.HTTPOk,
|
||||
{'Content-Length': '100', 'Etag': 'etagoftheobjectsegment'},
|
||||
None)
|
||||
self.app.register(
|
||||
'HEAD', '/v1/AUTH_test/cont/object\xe2\x99\xa1',
|
||||
swob.HTTPOk,
|
||||
@ -149,6 +154,11 @@ class TestSloPutManifest(SloTestCase):
|
||||
swob.HTTPOk,
|
||||
{'Content-Length': '10', 'Etag': 'etagoftheobjectsegment'},
|
||||
None)
|
||||
self.app.register(
|
||||
'HEAD', u'/v1/AUTH_test/cont/あ_1',
|
||||
swob.HTTPOk,
|
||||
{'Content-Length': '1', 'Etag': 'a'},
|
||||
None)
|
||||
self.app.register(
|
||||
'PUT', '/v1/AUTH_test/c/man', swob.HTTPCreated, {}, None)
|
||||
self.app.register(
|
||||
@ -391,6 +401,46 @@ class TestSloPutManifest(SloTestCase):
|
||||
self.assertEquals(errors[4][0], '/checktest/slob')
|
||||
self.assertEquals(errors[4][1], 'Etag Mismatch')
|
||||
|
||||
def test_handle_multipart_put_manifest_equal_slo(self):
|
||||
test_json_data = json.dumps([{'path': '/cont/object',
|
||||
'etag': 'etagoftheobjectsegment',
|
||||
'size_bytes': 100}])
|
||||
req = Request.blank(
|
||||
'/v1/AUTH_test/cont/object?multipart-manifest=put',
|
||||
environ={'REQUEST_METHOD': 'PUT'}, headers={'Accept': 'test'},
|
||||
body=test_json_data)
|
||||
status, headers, body = self.call_slo(req)
|
||||
self.assertEqual(status, '409 Conflict')
|
||||
self.assertEqual(self.app.call_count, 0)
|
||||
|
||||
def test_handle_multipart_put_manifest_equal_slo_non_ascii(self):
|
||||
test_json_data = json.dumps([{'path': u'/cont/あ_1',
|
||||
'etag': 'a',
|
||||
'size_bytes': 1}])
|
||||
path = quote(u'/v1/AUTH_test/cont/あ_1')
|
||||
req = Request.blank(
|
||||
path + '?multipart-manifest=put',
|
||||
environ={'REQUEST_METHOD': 'PUT'}, headers={'Accept': 'test'},
|
||||
body=test_json_data)
|
||||
status, headers, body = self.call_slo(req)
|
||||
self.assertEqual(status, '409 Conflict')
|
||||
self.assertEqual(self.app.call_count, 0)
|
||||
|
||||
def test_handle_multipart_put_manifest_equal_last_segment(self):
|
||||
test_json_data = json.dumps([{'path': '/cont/object',
|
||||
'etag': 'etagoftheobjectsegment',
|
||||
'size_bytes': 100},
|
||||
{'path': '/cont/object2',
|
||||
'etag': 'etagoftheobjectsegment',
|
||||
'size_bytes': 100}])
|
||||
req = Request.blank(
|
||||
'/v1/AUTH_test/cont/object2?multipart-manifest=put',
|
||||
environ={'REQUEST_METHOD': 'PUT'}, headers={'Accept': 'test'},
|
||||
body=test_json_data)
|
||||
status, headers, body = self.call_slo(req)
|
||||
self.assertEqual(status, '409 Conflict')
|
||||
self.assertEqual(self.app.call_count, 1)
|
||||
|
||||
|
||||
class TestSloDeleteManifest(SloTestCase):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user