From: Christos Tsantilas Date: Tue, 11 Oct 2011 02:04:19 +0000 (-0600) Subject: Bug 3190: Large HTTP POST stuck after early ICAP 400 error response X-Git-Tag: SQUID_3_1_16~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9569849ee3fcf57b4bc5460c9713f0350792e7dc;p=thirdparty%2Fsquid.git Bug 3190: Large HTTP POST stuck after early ICAP 400 error response When an ICAP REQMOD service responds with an error to (or the REQMOD transaction aborts while processing) a large HTTP request, the HTTP request may get stuck because the request body buffer gets full and nobody consumes the no-longer-needed content. The ICAP code quits but leaves the body buffer intact in case the client-side code wants to bypass the error. After that, nobody consumes the request body because the buggy client side does not inform the body pipe that there will be no other consumers, which would have triggered a noteBodyConsumerAborted() callback and enable auto-consumption or closed the client connection. This is a Measurement Factory project --- diff --git a/src/client_side.cc b/src/client_side.cc index e9d2a4f2e6..146f6c0331 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -3827,6 +3827,14 @@ ConnStateData::startClosing(const char *reason) bodyPipe->enableAutoConsumption(); } +void +ConnStateData::expectNoForwarding() { + if (bodyPipe != NULL) { + debugs(33, 4, HERE << "no consumer for virgin body " << bodyPipe->status()); + bodyPipe->expectNoConsumption(); + } +} + // initialize dechunking state void ConnStateData::startDechunkingRequest(HttpParser *hp) diff --git a/src/client_side.h b/src/client_side.h index 899541e59e..d85d71bbd8 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -216,6 +216,7 @@ public: bool closing() const; void startClosing(const char *reason); + void expectNoForwarding(); ///< cleans up virgin request [body] forwarding state BodyPipe::Pointer expectRequestBody(int64_t size); virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index e4c0d35e50..a690743f66 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1559,6 +1559,7 @@ ClientHttpRequest::handleAdaptationFailure(bool bypassable) (c != NULL && c->auth_user_request ? c->auth_user_request : request->auth_user_request)); c->flags.readMoreRequests = true; + c->expectNoForwarding(); node = (clientStreamNode *)client_stream.tail->data; clientStreamRead(node, this, node->readBuffer); }