diff --git a/swift/common/internal_client.py b/swift/common/internal_client.py index 368c20b90a..7dceda8427 100644 --- a/swift/common/internal_client.py +++ b/swift/common/internal_client.py @@ -27,7 +27,7 @@ from time import gmtime, strftime, time from zlib import compressobj from swift.common.utils import quote -from swift.common.http import HTTP_NOT_FOUND +from swift.common.http import HTTP_NOT_FOUND, HTTP_MULTIPLE_CHOICES from swift.common.swob import Request from swift.common.wsgi import loadapp, pipeline_property @@ -256,6 +256,8 @@ class InternalClient(object): (path, quote(marker), quote(end_marker)), {}, acceptable_statuses) if not resp.status_int == 200: + if resp.status_int >= HTTP_MULTIPLE_CHOICES: + ''.join(resp.app_iter) break data = json.loads(resp.body) if not data: diff --git a/test/unit/common/test_internal_client.py b/test/unit/common/test_internal_client.py index d4b7c1521a..d2ef735324 100644 --- a/test/unit/common/test_internal_client.py +++ b/test/unit/common/test_internal_client.py @@ -628,6 +628,59 @@ class TestInternalClient(unittest.TestCase): self.assertEqual('one\xc3\xa9 two'.split(), items) + def test_iter_item_read_response_if_status_is_acceptable(self): + class Response(object): + def __init__(self, status_int, body, app_iter): + self.status_int = status_int + self.body = body + self.app_iter = app_iter + + class InternalClient(internal_client.InternalClient): + def __init__(self, test, responses): + self.test = test + self.responses = responses + + def make_request( + self, method, path, headers, acceptable_statuses, + body_file=None): + resp = self.responses.pop(0) + if resp.status_int in acceptable_statuses or \ + resp.status_int // 100 in acceptable_statuses: + return resp + if resp: + raise internal_client.UnexpectedResponse( + 'Unexpected response: %s' % resp.status_int, resp) + + num_list = [] + + def generate_resp_body(): + for i in range(1, 5): + yield str(i) + num_list.append(i) + + exp_items = [] + responses = [Response(204, json.dumps([]), generate_resp_body())] + items = [] + client = InternalClient(self, responses) + for item in client._iter_items('/'): + items.append(item) + self.assertEqual(exp_items, items) + self.assertEqual(len(num_list), 0) + + responses = [Response(300, json.dumps([]), generate_resp_body())] + client = InternalClient(self, responses) + self.assertRaises(internal_client.UnexpectedResponse, + next, client._iter_items('/')) + + exp_items = [] + responses = [Response(404, json.dumps([]), generate_resp_body())] + items = [] + client = InternalClient(self, responses) + for item in client._iter_items('/'): + items.append(item) + self.assertEqual(exp_items, items) + self.assertEqual(len(num_list), 4) + def test_set_metadata(self): class InternalClient(internal_client.InternalClient): def __init__(self, test, path, exp_headers):