From 37337d5fcb0a29344381f8de7d810a9e76e10928 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Singh Date: Sun, 17 May 2015 13:35:58 +0530 Subject: [PATCH] Read the response body, if response status is greater than 300. internal_client was not reading response if response status is not 200. So proxy server treats this as client disconnect and logs 499 in log file. This patch fixes that by reading response if response status is greater than or equal to 300 and in acceptable statuses. Closes-Bug: #1364752 Change-Id: I0512a25895da583956f76031e3c5de5c970bce01 --- swift/common/internal_client.py | 4 +- test/unit/common/test_internal_client.py | 53 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) 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):