diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py index 8508e2a0b4..eb24fb76b5 100644 --- a/swift/proxy/controllers/obj.py +++ b/swift/proxy/controllers/obj.py @@ -2447,10 +2447,12 @@ class ECObjectController(BaseObjectController): headers = [] for getter, _parts_iter in bad_bucket.get_responses(): if best_bucket and best_bucket.durable: - headers = HeaderKeyDict(getter.last_headers) - t_data_file = headers.get('X-Backend-Data-Timestamp') - t_obj = headers.get('X-Backend-Timestamp', - headers.get('X-Timestamp')) + bad_resp_headers = HeaderKeyDict(getter.last_headers) + t_data_file = bad_resp_headers.get( + 'X-Backend-Data-Timestamp') + t_obj = bad_resp_headers.get( + 'X-Backend-Timestamp', + bad_resp_headers.get('X-Timestamp')) bad_ts = Timestamp(t_data_file or t_obj or '0') if bad_ts <= Timestamp(best_bucket.timestamp_str): # We have reason to believe there's still good data diff --git a/test/unit/proxy/controllers/test_obj.py b/test/unit/proxy/controllers/test_obj.py index 4acc962069..bd6528d377 100644 --- a/test/unit/proxy/controllers/test_obj.py +++ b/test/unit/proxy/controllers/test_obj.py @@ -2269,6 +2269,18 @@ class TestECObjController(ECObjectControllerMixin, unittest.TestCase): self.assertIn('Accept-Ranges', resp.headers) self.assertNotIn('Connection', resp.headers) + def test_GET_not_found_when_404_newer(self): + # if proxy receives a 404, it keeps waiting for other connections until + # max number of nodes in hopes of finding an object, but if 404 is + # more recent than a 200, then it should ignore 200 and return 404 + req = swift.common.swob.Request.blank('/v1/a/c/o') + rest = 2 * self.policy.object_ring.replica_count - 2 + codes = [200, 404] + [200] * rest + ts_iter = iter([1, 2] + [1] * rest) + with set_http_connect(*codes, timestamps=ts_iter): + resp = req.get_response(self.app) + self.assertEqual(resp.status_int, 404) + def _test_if_match(self, method): num_responses = self.policy.ec_ndata if method == 'GET' else 1