+New tag to fix handling of chunked requests.
+
+ A broken or confused HTTP/1.1 client may send a chunked HTTP
+ request to Squid. Squid does not have full support for that
+ feature yet. To cope with such requests, Squid buffers the
+ entire request and then dechunks request body to create a
+ plain HTTP/1.0 request with a known content length. The plain
+ request is then used by the rest of Squid code as usual.
+
+ The option value specifies the maximum size of the buffer used
+ to hold the request before the conversion. If the chunked
+ request size exceeds the specified limit, the conversion
+ fails, and the client receives an "unsupported request" error,
+ as if dechunking was disabled.
+
+ Dechunking is enabled by default. To disable conversion of
+ chunked requests, set the maximum to zero.
+
+ Request dechunking feature and this option in particular are a
+ temporary hack. When chunking requests and responses are fully
+ supported, there will be no need to buffer a chunked request.
+
+
+
+
diff --git a/doc/release-notes/release-3.0.sgml b/doc/release-notes/release-3.0.sgml
index 361e29f900..036edd40bc 100644
--- a/doc/release-notes/release-3.0.sgml
+++ b/doc/release-notes/release-3.0.sgml
@@ -537,6 +537,30 @@ See the accf_http(9) man page.
your value with 0.
+ chunked_request_body_max_size
+ New tag to fix handling of chunked requests.
+
+ A broken or confused HTTP/1.1 client may send a chunked HTTP
+ request to Squid. Squid does not have full support for that
+ feature yet. To cope with such requests, Squid buffers the
+ entire request and then dechunks request body to create a
+ plain HTTP/1.0 request with a known content length. The plain
+ request is then used by the rest of Squid code as usual.
+
+ The option value specifies the maximum size of the buffer used
+ to hold the request before the conversion. If the chunked
+ request size exceeds the specified limit, the conversion
+ fails, and the client receives an "unsupported request" error,
+ as if dechunking was disabled.
+
+ Dechunking is enabled by default. To disable conversion of
+ chunked requests, set the maximum to zero.
+
+ Request dechunking feature and this option in particular are a
+ temporary hack. When chunking requests and responses are fully
+ supported, there will be no need to buffer a chunked request.
+
+
diff --git a/src/cf.data.pre b/src/cf.data.pre
index eed64c5e73..d0378bc0fd 100644
--- a/src/cf.data.pre
+++ b/src/cf.data.pre
@@ -2851,8 +2851,6 @@ DOC_START
Request dechunking feature and this option in particular are a
temporary hack. When chunking requests and responses are fully
supported, there will be no need to buffer a chunked request.
- Dechunking requires ICAP support in Squid v3.0 but not in later
- versions (see --enable-icap-client configure option).
DOC_END
NAME: broken_posts
diff --git a/src/client_side.cc b/src/client_side.cc
index 6fb14abf52..5e616f0198 100755
--- a/src/client_side.cc
+++ b/src/client_side.cc
@@ -75,10 +75,7 @@
#include "ClientRequestContext.h"
#include "MemBuf.h"
#include "SquidTime.h"
-
-#if ICAP_CLIENT
-#include "ICAP/ChunkedCodingParser.h"
-#endif
+#include "ChunkedCodingParser.h"
#if LINGERING_CLOSE
#define comm_close comm_lingering_close
@@ -1955,16 +1952,10 @@ parseHttpRequest(ConnStateData::Pointer & conn, HttpParser *hp, method_t * metho
// entire body is available so that we can set the content length and
// forward the request without chunks. The primary reason for this is
// to avoid forwarding a chunked request because the server side lacks
- // logic to determine when it is valid to do so. The secondary reason
- // is that we should not send chunked requests if we cannot handle
- // chunked responses and Squid v3.0 cannot.
+ // logic to determine when it is valid to do so.
// FUTURE_CODE_TO_SUPPORT_CHUNKED_REQUESTS below will replace this hack.
if (hp->v_min == 1 && hp->v_maj == 1 && // broken client, may send chunks
-#if ICAP_CLIENT
Config.maxChunkedRequestBodySize > 0 && // configured to dechunk
-#else
- false && // ICAP required for v3.0 because of ICAP/ChunkedCodingParser
-#endif
(*method_p == METHOD_PUT || *method_p == METHOD_POST)) {
// check only once per request because isChunkedRequest is expensive
@@ -2645,8 +2636,7 @@ ConnStateData::handleRequestBodyData()
// The code below works, in principle, but we cannot do dechunking
// on-the-fly because that would mean sending chunked requests to
// the next hop. Squid lacks logic to determine which servers can
- // receive chunk requests. Squid v3.0 code cannot even handle chunked
- // responses which we may encourage by sending chunked requests.
+ // receive chunk requests.
// The error generation code probably needs more work.
if (in.bodyParser) { // chunked body
debugs(33,5, HERE << "handling chunked request body for FD " << fd);
@@ -3419,9 +3409,7 @@ ConnStateData::startDechunkingRequest(HttpParser *hp)
debugs(33, 5, HERE << "start dechunking at " << HttpParserRequestLen(hp));
assert(in.dechunkingState == chunkUnknown);
assert(!in.bodyParser);
-#if ICAP_CLIENT
in.bodyParser = new ChunkedCodingParser;
-#endif
in.chunkedSeen = HttpParserRequestLen(hp); // skip headers when dechunking
in.chunked.init(); // TODO: should we have a smaller-than-default limit?
in.dechunked.init();
@@ -3436,9 +3424,7 @@ ConnStateData::finishDechunkingRequest(HttpParser *hp)
assert(in.dechunkingState == chunkReady);
assert(in.bodyParser);
-#if ICAP_CLIENT
delete in.bodyParser;
-#endif
in.bodyParser = NULL;
const mb_size_t headerSize = HttpParserRequestLen(hp);
@@ -3471,7 +3457,6 @@ ConnStateData::finishDechunkingRequest(HttpParser *hp)
bool
ConnStateData::parseRequestChunks(HttpParser *)
{
-#if ICAP_CLIENT
debugs(33,5, HERE << "parsing chunked request body at " <<
in.chunkedSeen << " < " << in.notYetUsed);
assert(in.bodyParser);
@@ -3512,7 +3497,6 @@ ConnStateData::parseRequestChunks(HttpParser *)
debugs(33,3, HERE << "chunk parsing error");
in.dechunkingState = chunkError;
}
-#endif
return false; // error, unsupported, or done
}
@@ -3532,9 +3516,5 @@ ConnStateData::In::~In()
if (allocatedSize)
memFreeBuf(allocatedSize, buf);
if (bodyParser)
-#if ICAP_CLIENT
delete bodyParser; // TODO: pool
-#else
- assert(false); // chunked requests are only supported if ICAP is
-#endif
}