From: Christos Tsantilas Date: Thu, 6 Oct 2011 08:29:03 +0000 (+0300) Subject: Bug 3190: Large HTTP POST stuck after early ICAP 400 error response X-Git-Tag: BumpSslServerFirst.take01~124 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eb44b2d7a051a572446cceb7ff9334e734743b08;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 2b918fa31d..4c2666a451 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -3938,6 +3938,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() diff --git a/src/client_side.h b/src/client_side.h index ba11aee90a..e895024f04 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -262,6 +262,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 805729ddb1..f4da4d49b6 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1791,6 +1791,7 @@ ClientHttpRequest::handleAdaptationFailure(int errDetail, bool bypassable) request->detailError(ERR_ICAP_FAILURE, errDetail); c->flags.readMore = true; + c->expectNoForwarding(); node = (clientStreamNode *)client_stream.tail->data; clientStreamRead(node, this, node->readBuffer); }