diff --git a/swift/common/middleware/slo.py b/swift/common/middleware/slo.py index 24e2faad32..ad34e28f45 100644 --- a/swift/common/middleware/slo.py +++ b/swift/common/middleware/slo.py @@ -591,7 +591,7 @@ class StaticLargeObject(object): except (ValueError, TypeError): raise HTTPBadRequest('Invalid Manifest File') if seg_size < self.min_segment_size and \ - (index == 0 or index < len(parsed_data) - 1): + len(parsed_data) > 1 and index < len(parsed_data) - 1: raise HTTPBadRequest( 'Each segment, except the last, must be at least ' '%d bytes.' % self.min_segment_size) diff --git a/test/unit/common/middleware/test_slo.py b/test/unit/common/middleware/test_slo.py index 2dd076ad72..4ee0c155f5 100644 --- a/test/unit/common/middleware/test_slo.py +++ b/test/unit/common/middleware/test_slo.py @@ -196,7 +196,14 @@ class TestSloPutManifest(SloTestCase): self.assertEquals(e.status_int, 413) with patch.object(self.slo, 'min_segment_size', 1000): - req = Request.blank('/v1/a/c/o', body=test_json_data) + test_json_data_2obj = json.dumps( + [{'path': '/cont/small_object1', + 'etag': 'etagoftheobjectsegment', + 'size_bytes': 10}, + {'path': '/cont/small_object2', + 'etag': 'etagoftheobjectsegment', + 'size_bytes': 10}]) + req = Request.blank('/v1/a/c/o', body=test_json_data_2obj) try: self.slo.handle_multipart_put(req, fake_start_response) except HTTPException as e: @@ -248,6 +255,19 @@ class TestSloPutManifest(SloTestCase): self.slo(req.environ, fake_start_response) self.assertTrue('X-Static-Large-Object' in req.headers) + def test_handle_multipart_put_success_allow_only_one_small_segment(self): + with patch.object(self.slo, 'min_segment_size', 50): + test_json_data = json.dumps([{'path': '/cont/small_object', + 'etag': 'etagoftheobjectsegment', + 'size_bytes': 10}]) + req = Request.blank( + '/v1/AUTH_test/c/man?multipart-manifest=put', + environ={'REQUEST_METHOD': 'PUT'}, headers={'Accept': 'test'}, + body=test_json_data) + self.assertTrue('X-Static-Large-Object' not in req.headers) + self.slo(req.environ, fake_start_response) + self.assertTrue('X-Static-Large-Object' in req.headers) + def test_handle_multipart_put_success_unicode(self): test_json_data = json.dumps([{'path': u'/cont/object\u2661', 'etag': 'etagoftheobjectsegment',