proxy: fix is_useful_response for py2

py2 http responses don't have a 'headers' attribute, so don't try to
use it.

Unfortunately the unit test infrastructure's FakeConn class does
have a 'headers' attribute (whose value doesn't match the result of
calling its 'getheaders()' method!), so this bug was not caught by
tests in the Related-Change.

Related-Change: I96f28ab0b2b5f9374c399e8905ee240e7b093f8b
Change-Id: I2cd820280b8c69cafc5730183903c9d379d8dde5
This commit is contained in:
Alistair Coles 2024-09-25 18:49:28 +01:00
parent 94dc4cad09
commit 6e4ecfc5dc
3 changed files with 16 additions and 6 deletions

View File

@ -1112,7 +1112,7 @@ def is_useful_response(resp, node):
return False
if ('handoff_index' in node
and resp.status == 404
and resp.headers.get('x-backend-timestamp') is None):
and resp.getheader('x-backend-timestamp') is None):
# a 404 from a handoff are not considered authoritative unless they
# have an x-backend-timestamp that indicates that there is a tombstone
return False

View File

@ -809,7 +809,7 @@ def fake_http_connect(*code_iter, **kwargs):
self.received = 0
self.etag = etag
self.body = body
self.headers = headers or {}
self._headers = headers or {}
self.expect_headers = expect_headers or {}
if timestamp == -1:
# -1 is reserved to mean "magic default"
@ -894,7 +894,7 @@ def fake_http_connect(*code_iter, **kwargs):
headers['x-container-timestamp'] = '1'
except StopIteration:
pass
headers.update(self.headers)
headers.update(self._headers)
return headers.items()
def get_slow(self):

View File

@ -1462,7 +1462,12 @@ class CommonObjectControllerMixin(BaseObjectControllerMixin):
primary_failure = self.replicas() - primary_success
primary_codes = [Timeout()] * primary_failure + [202] * primary_success
handoff_codes = [404] * primary_failure
with mocked_http_conn(*(primary_codes + handoff_codes)):
# note: by default fake_http_connect will return an x-backend-timestamp
# header; we need to override that for handoffs by setting to None
with mocked_http_conn(
*(primary_codes + handoff_codes),
headers=[{}] * len(primary_codes) +
[{'x-backend-timestamp': None}] * len(handoff_codes)):
resp = req.get_response(self.app)
self.assertEqual(503, resp.status_int,
'replicas = %s' % self.replicas())
@ -1484,7 +1489,12 @@ class CommonObjectControllerMixin(BaseObjectControllerMixin):
handoff_not_found = self.replicas() - handoff_success
primary_codes = [Timeout()] * self.replicas()
handoff_codes = [202] * handoff_success + [404] * handoff_not_found
with mocked_http_conn(*(primary_codes + handoff_codes)):
# note: by default fake_http_connect will return an x-backend-timestamp
# header; we need to override that for handoffs by setting to None
with mocked_http_conn(
*(primary_codes + handoff_codes),
headers=[{}] * len(primary_codes) +
[{'x-backend-timestamp': None}] * len(handoff_codes)):
resp = req.get_response(self.app)
self.assertEqual(503, resp.status_int,
'replicas = %s' % self.replicas())
@ -6365,7 +6375,7 @@ class TestECObjController(ECObjectControllerMixin, unittest.TestCase):
self.assertIn(req.headers['x-trans-id'], line)
etag2_conns = []
for conn in log.responses:
if conn.headers.get('X-Object-Sysmeta-Ec-Etag') == etag2:
if conn._headers.get('X-Object-Sysmeta-Ec-Etag') == etag2:
etag2_conns.append(conn)
self.assertEqual(
([True] * 8) + [False], # the resumed etag2 doesn't get closed