From 2ab8e3e8d20087521dc4aa7ffb358e3f65a7a6aa Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Mon, 28 Nov 2022 10:02:56 -0500 Subject: [PATCH] Cancel timeout on failures too. --- src/allmydata/storage/http_client.py | 7 ++++++- src/allmydata/test/test_storage_http.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/allmydata/storage/http_client.py b/src/allmydata/storage/http_client.py index 5b4ec9db8..73fba9888 100644 --- a/src/allmydata/storage/http_client.py +++ b/src/allmydata/storage/http_client.py @@ -169,7 +169,12 @@ def limited_content( collector.f.seek(0) return collector.f - return d.addCallback(done) + def failed(f): + if timeout.active(): + timeout.cancel() + return f + + return d.addCallbacks(done, failed) def _decode_cbor(response, schema: Schema, clock: IReactorTime): diff --git a/src/allmydata/test/test_storage_http.py b/src/allmydata/test/test_storage_http.py index 4f7174c06..8dbe18545 100644 --- a/src/allmydata/test/test_storage_http.py +++ b/src/allmydata/test/test_storage_http.py @@ -280,6 +280,14 @@ class TestApp(object): self.clock.callLater(59 + 59, request.write, b"c") return Deferred() + @_authorized_route(_app, set(), "/die_unfinished", methods=["GET"]) + def die(self, request, authorization): + """ + Dies half-way. + """ + request.transport.loseConnection() + return Deferred() + def result_of(d): """ @@ -423,6 +431,22 @@ class CustomHTTPServerTests(SyncTestCase): with self.assertRaises(CancelledError): error[0].raiseException() + def test_limited_content_cancels_timeout_on_failed_response(self): + """ + If the response fails somehow, the timeout is still cancelled. + """ + response = result_of( + self.client.request( + "GET", + "http://127.0.0.1/die", + ) + ) + + d = limited_content(response, self._http_server.clock, 4) + with self.assertRaises(ValueError): + result_of(d) + self.assertEqual(len(self._http_server.clock.getDelayedCalls()), 0) + class HttpTestFixture(Fixture): """