diff -u -r -N squid-3.0.STABLE15/ChangeLog squid-3.0.STABLE16-RC1/ChangeLog
--- squid-3.0.STABLE15/ChangeLog	2009-05-06 23:11:25.000000000 +1200
+++ squid-3.0.STABLE16-RC1/ChangeLog	2009-05-16 00:47:46.000000000 +1200
@@ -1,3 +1,8 @@
+Changes to squid-3.0.STABLE16-RC1 (16 May 2009):
+
+	- Bug 1148 Ported from 3.1: Chunked Transfer Encoding
+	- Bug 2648: NTLM helpers not shutting down when deferred
+
 Changes to squid-3.0.STABLE15 (06 May 2009):
 
 	- Regression Bug 2635: Incorrect Max-Forwards header type
diff -u -r -N squid-3.0.STABLE15/configure squid-3.0.STABLE16-RC1/configure
--- squid-3.0.STABLE15/configure	2009-05-06 23:11:43.000000000 +1200
+++ squid-3.0.STABLE16-RC1/configure	2009-05-16 00:47:59.000000000 +1200
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision: 1.488.2.3 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.0.STABLE15.
+# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.0.STABLE16-RC1.
 #
 # Report bugs to <http://www.squid-cache.org/bugs/>.
 #
@@ -751,8 +751,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.0.STABLE15'
-PACKAGE_STRING='Squid Web Proxy 3.0.STABLE15'
+PACKAGE_VERSION='3.0.STABLE16-RC1'
+PACKAGE_STRING='Squid Web Proxy 3.0.STABLE16-RC1'
 PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/'
 
 ac_unique_file="src/main.cc"
@@ -1663,7 +1663,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Squid Web Proxy 3.0.STABLE15 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.0.STABLE16-RC1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1733,7 +1733,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE15:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE16-RC1:";;
    esac
   cat <<\_ACEOF
 
@@ -2045,7 +2045,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.0.STABLE15
+Squid Web Proxy configure 3.0.STABLE16-RC1
 generated by GNU Autoconf 2.62
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -2059,7 +2059,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Squid Web Proxy $as_me 3.0.STABLE15, which was
+It was created by Squid Web Proxy $as_me 3.0.STABLE16-RC1, which was
 generated by GNU Autoconf 2.62.  Invocation command line was
 
   $ $0 $@
@@ -2777,7 +2777,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.0.STABLE15'
+ VERSION='3.0.STABLE16-RC1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -47802,7 +47802,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Squid Web Proxy $as_me 3.0.STABLE15, which was
+This file was extended by Squid Web Proxy $as_me 3.0.STABLE16-RC1, which was
 generated by GNU Autoconf 2.62.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -47855,7 +47855,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-Squid Web Proxy config.status 3.0.STABLE15
+Squid Web Proxy config.status 3.0.STABLE16-RC1
 configured by $0, generated by GNU Autoconf 2.62,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff -u -r -N squid-3.0.STABLE15/configure.in squid-3.0.STABLE16-RC1/configure.in
--- squid-3.0.STABLE15/configure.in	2009-05-06 23:11:43.000000000 +1200
+++ squid-3.0.STABLE16-RC1/configure.in	2009-05-16 00:47:59.000000000 +1200
@@ -1,7 +1,7 @@
 dnl  Configuration input file for Squid
 dnl
 dnl
-AC_INIT(Squid Web Proxy, 3.0.STABLE15, http://www.squid-cache.org/bugs/, squid)
+AC_INIT(Squid Web Proxy, 3.0.STABLE16-RC1, http://www.squid-cache.org/bugs/, squid)
 AC_PREREQ(2.52)
 AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
diff -u -r -N squid-3.0.STABLE15/include/version.h squid-3.0.STABLE16-RC1/include/version.h
--- squid-3.0.STABLE15/include/version.h	2009-05-06 23:11:43.000000000 +1200
+++ squid-3.0.STABLE16-RC1/include/version.h	2009-05-16 00:47:59.000000000 +1200
@@ -9,5 +9,5 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1241608284
+#define SQUID_RELEASE_TIME 1242391665
 #endif
diff -u -r -N squid-3.0.STABLE15/RELEASENOTES.html squid-3.0.STABLE16-RC1/RELEASENOTES.html
--- squid-3.0.STABLE15/RELEASENOTES.html	2009-05-06 23:12:25.000000000 +1200
+++ squid-3.0.STABLE16-RC1/RELEASENOTES.html	2009-05-16 00:48:42.000000000 +1200
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.50">
- <TITLE>Squid 3.0.STABLE15 release notes</TITLE>
+ <TITLE>Squid 3.0.STABLE16-RC1 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.0.STABLE15 release notes</H1>
+<H1>Squid 3.0.STABLE16-RC1 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -15,7 +15,7 @@
 <HR>
 <H2><A NAME="s1">1. Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.0.STABLE15.</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.0.STABLE16-RC1.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.0/">http://www.squid-cache.org/Versions/v3/3.0/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
@@ -652,6 +652,32 @@
 </PRE>
 </P>
 
+<DT><B>chunked_request_body_max_size</B><DD>
+<P>New tag to fix handling of chunked requests.
+<PRE>
+        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.
+        
+</PRE>
+</P>
+
 </DL>
 </P>
 
diff -u -r -N squid-3.0.STABLE15/src/cf.data.pre squid-3.0.STABLE16-RC1/src/cf.data.pre
--- squid-3.0.STABLE15/src/cf.data.pre	2009-05-06 23:11:41.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/cf.data.pre	2009-05-16 00:47:57.000000000 +1200
@@ -2826,6 +2826,33 @@
 	be no limit imposed.
 DOC_END
 
+NAME: chunked_request_body_max_size
+COMMENT: (bytes)
+TYPE: b_int64_t
+DEFAULT: 64 KB
+LOC: Config.maxChunkedRequestBodySize
+DOC_START
+	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.
+DOC_END
+
 NAME: broken_posts
 TYPE: acl_access
 DEFAULT: none
diff -u -r -N squid-3.0.STABLE15/src/ChunkedCodingParser.cc squid-3.0.STABLE16-RC1/src/ChunkedCodingParser.cc
--- squid-3.0.STABLE15/src/ChunkedCodingParser.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/ChunkedCodingParser.cc	2009-05-16 00:47:56.000000000 +1200
@@ -0,0 +1,232 @@
+#include "squid.h"
+#include "Parsing.h"
+#include "TextException.h"
+#include "ChunkedCodingParser.h"
+#include "MemBuf.h"
+
+ChunkedCodingParser::Step ChunkedCodingParser::psChunkBeg = &ChunkedCodingParser::parseChunkBeg;
+ChunkedCodingParser::Step ChunkedCodingParser::psChunkBody = &ChunkedCodingParser::parseChunkBody;
+ChunkedCodingParser::Step ChunkedCodingParser::psChunkEnd = &ChunkedCodingParser::parseChunkEnd;
+ChunkedCodingParser::Step ChunkedCodingParser::psTrailer = &ChunkedCodingParser::parseTrailer;
+ChunkedCodingParser::Step ChunkedCodingParser::psMessageEnd = &ChunkedCodingParser::parseMessageEnd;
+
+ChunkedCodingParser::ChunkedCodingParser()
+{
+    reset();
+}
+
+void ChunkedCodingParser::reset()
+{
+    theStep = psChunkBeg;
+    theChunkSize = theLeftBodySize = 0;
+    doNeedMoreData = false;
+    theIn = theOut = NULL;
+}
+
+bool ChunkedCodingParser::parse(MemBuf *rawData, MemBuf *parsedContent)
+{
+    Must(rawData && parsedContent);
+    theIn = rawData;
+    theOut = parsedContent;
+
+    // we must reset this all the time so that mayContinue() lets us
+    // output more content if we stopped due to needsMoreSpace() before
+    doNeedMoreData = !theIn->hasContent();
+
+    while (mayContinue()) {
+        (this->*theStep)();
+    }
+
+    return theStep == psMessageEnd;
+}
+
+bool ChunkedCodingParser::needsMoreData() const
+{
+    return doNeedMoreData;
+}
+
+bool ChunkedCodingParser::needsMoreSpace() const
+{
+    assert(theOut);
+    return theStep == psChunkBody && !theOut->hasPotentialSpace();
+}
+
+bool ChunkedCodingParser::mayContinue() const
+{
+    return !needsMoreData() && !needsMoreSpace() && theStep != psMessageEnd;
+}
+
+void ChunkedCodingParser::parseChunkBeg()
+{
+    Must(theChunkSize <= 0); // Should(), really
+
+    size_t crlfBeg = 0;
+    size_t crlfEnd = 0;
+
+    if (findCrlf(crlfBeg, crlfEnd)) {
+        debugs(94,7, "found chunk-size end: " << crlfBeg << "-" << crlfEnd);
+        int64_t size = -1;
+        const char *p = 0;
+
+        if (StringToInt64(theIn->content(), size, &p, 16)) {
+            if (size < 0) {
+                throw TexcHere("negative chunk size");
+                return;
+            }
+
+            theIn->consume(crlfEnd);
+            theChunkSize = theLeftBodySize = size;
+            debugs(94,7, "found chunk: " << theChunkSize);
+            theStep = theChunkSize == 0 ? psTrailer : psChunkBody;
+            return;
+        }
+
+        throw TexcHere("corrupted chunk size");
+    }
+
+    doNeedMoreData = true;
+}
+
+void ChunkedCodingParser::parseChunkBody()
+{
+    Must(theLeftBodySize > 0); // Should, really
+
+    const size_t availSize = XMIN(theLeftBodySize, (uint64_t)theIn->contentSize());
+    const size_t safeSize = XMIN(availSize, (size_t)theOut->potentialSpaceSize());
+
+    doNeedMoreData = availSize < theLeftBodySize;
+    // and we may also need more space
+
+    theOut->append(theIn->content(), safeSize);
+    theIn->consume(safeSize);
+    theLeftBodySize -= safeSize;
+
+    if (theLeftBodySize == 0)
+        theStep = psChunkEnd;
+    else
+        Must(needsMoreData() || needsMoreSpace());
+}
+
+void ChunkedCodingParser::parseChunkEnd()
+{
+    Must(theLeftBodySize == 0); // Should(), really
+
+    size_t crlfBeg = 0;
+    size_t crlfEnd = 0;
+
+    if (findCrlf(crlfBeg, crlfEnd)) {
+        if (crlfBeg != 0) {
+            throw TexcHere("found data bewteen chunk end and CRLF");
+            return;
+        }
+
+        theIn->consume(crlfEnd);
+        theChunkSize = 0; // done with the current chunk
+        theStep = psChunkBeg;
+        return;
+    }
+
+    doNeedMoreData = true;
+}
+
+void ChunkedCodingParser::parseTrailer()
+{
+    Must(theChunkSize == 0); // Should(), really
+
+    while (mayContinue())
+        parseTrailerHeader();
+}
+
+void ChunkedCodingParser::parseTrailerHeader()
+{
+    size_t crlfBeg = 0;
+    size_t crlfEnd = 0;
+
+    if (findCrlf(crlfBeg, crlfEnd)) {
+        if (crlfBeg > 0)
+
+            ; //theTrailer.append(theIn->content(), crlfEnd);
+
+        theIn->consume(crlfEnd);
+
+        if (crlfBeg == 0)
+            theStep = psMessageEnd;
+
+        return;
+    }
+
+    doNeedMoreData = true;
+}
+
+void ChunkedCodingParser::parseMessageEnd()
+{
+    // termination step, should not be called
+    Must(false); // Should(), really
+}
+
+// finds next CRLF
+bool ChunkedCodingParser::findCrlf(size_t &crlfBeg, size_t &crlfEnd)
+{
+    // XXX: This code was copied, with permission, from another software.
+    // There is a similar and probably better code inside httpHeaderParse
+    // but it seems difficult to isolate due to parsing-unrelated bloat.
+    // Such isolation should probably be done before this class is used
+    // for handling of traffic "more external" than ICAP.
+
+    const char *buf = theIn->content();
+    size_t size = theIn->contentSize();
+
+    ssize_t crOff = -1;
+    bool quoted = false;
+    bool slashed = false;
+
+    for (size_t i = 0; i < size; ++i) {
+        if (slashed) {
+            slashed = false;
+            continue;
+        }
+
+        const char c = buf[i];
+
+        // handle quoted strings
+        if (quoted) {
+            if (c == '\\')
+                slashed = true;
+            else
+                if (c == '"')
+                    quoted = false;
+
+            continue;
+        } else
+            if (c == '"') {
+                quoted = true;
+                crOff = -1;
+                continue;
+            }
+
+        if (crOff < 0) { // looking for the first CR or LF
+
+            if (c == '\n') {
+                crlfBeg = i;
+                crlfEnd = ++i;
+                return true;
+            }
+
+            if (c == '\r')
+                crOff = i;
+        } else { // skipping CRs, looking for the first LF
+
+            if (c == '\n') {
+                crlfBeg = crOff;
+                crlfEnd = ++i;
+                return true;
+            }
+
+            if (c != '\r')
+                crOff = -1;
+        }
+    }
+
+    return false;
+}
+
diff -u -r -N squid-3.0.STABLE15/src/ChunkedCodingParser.h squid-3.0.STABLE16-RC1/src/ChunkedCodingParser.h
--- squid-3.0.STABLE15/src/ChunkedCodingParser.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/ChunkedCodingParser.h	2009-05-16 00:47:56.000000000 +1200
@@ -0,0 +1,89 @@
+
+/*
+ * $Id: ChunkedCodingParser.h,v 1.1 2007/12/26 22:33:32 hno Exp $
+ * 
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#ifndef SQUID_CHUNKEDCODINGPARSER_H
+#define SQUID_CHUNKEDCODINGPARSER_H
+
+#include "RefCount.h"
+
+// ChunkedCodingParser is an incremental parser for chunked transfer coding
+// used by HTTP and ICAP. The parser shovels content bytes from the raw
+// input buffer into the content output buffer, both caller-supplied.
+// Ignores chunk extensions except for ICAP's ieof.
+// Has a trailer-handling placeholder.
+
+class ChunkedCodingParser
+{
+
+public:
+    ChunkedCodingParser();
+
+    void reset();
+
+    // true = complete success; false == needs more data
+    bool parse(MemBuf *rawData, MemBuf *parsedContent); // throws on error
+
+    bool needsMoreData() const;
+    bool needsMoreSpace() const;
+
+private:
+    typedef void (ChunkedCodingParser::*Step)();
+
+private:
+    bool mayContinue() const;
+
+    void parseChunkBeg();
+    void parseChunkBody();
+    void parseChunkEnd();
+    void parseTrailer();
+    void parseTrailerHeader();
+    void parseMessageEnd();
+
+    bool findCrlf(size_t &crlfBeg, size_t &crlfEnd);
+
+private:
+    static Step psChunkBeg;
+    static Step psChunkBody;
+    static Step psChunkEnd;
+    static Step psTrailer;
+    static Step psMessageEnd;
+
+    MemBuf *theIn;
+    MemBuf *theOut;
+
+    Step theStep;
+    uint64_t theChunkSize;
+    uint64_t theLeftBodySize;
+    bool doNeedMoreData;
+};
+
+#endif /* SQUID_CHUNKEDCODINGPARSER_H */
diff -u -r -N squid-3.0.STABLE15/src/client_side.cc squid-3.0.STABLE16-RC1/src/client_side.cc
--- squid-3.0.STABLE15/src/client_side.cc	2009-05-06 23:11:41.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/client_side.cc	2009-05-16 00:47:57.000000000 +1200
@@ -75,6 +75,7 @@
 #include "ClientRequestContext.h"
 #include "MemBuf.h"
 #include "SquidTime.h"
+#include "ChunkedCodingParser.h"
 
 #if LINGERING_CLOSE
 #define comm_close comm_lingering_close
@@ -1820,6 +1821,17 @@
     }
 }
 
+// Temporary hack helper: determine whether the request is chunked, expensive
+static bool
+isChunkedRequest(const HttpParser *hp) {
+    HttpRequest request;
+    if (!request.parseHeader(HttpParserHdrBuf(hp), HttpParserHdrSz(hp)))
+        return false;
+
+    return request.header.has(HDR_TRANSFER_ENCODING) &&
+        request.header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',');
+}
+
 /*
  *  parseHttpRequest()
  * 
@@ -1832,7 +1844,6 @@
 static ClientSocketContext *
 parseHttpRequest(ConnStateData::Pointer & conn, HttpParser *hp, method_t * method_p, HttpVersion *http_ver)
 {
-    char *url = NULL;
     char *req_hdr = NULL;
     char *end;
     size_t req_sz;
@@ -1908,17 +1919,6 @@
         return parseHttpRequestAbort(conn, "error:unsupported-request-method");
     }
 
-    /* set url */
-    /*
-     * XXX this should eventually not use a malloc'ed buffer; the transformation code
-     * below needs to be modified to not expect a mutable nul-terminated string.
-     */
-    url = (char *)xmalloc(hp->u_end - hp->u_start + 16);
-
-    memcpy(url, hp->buf + hp->u_start, hp->u_end - hp->u_start + 1);
-
-    url[hp->u_end - hp->u_start + 1] = '\0';
-
     /*
      * Process headers after request line
      * TODO: Use httpRequestParse here.
@@ -1938,7 +1938,6 @@
      */
     if ( squid_strnstr(req_hdr, "\r\r\n", req_sz) ) {
         debugs(33, 1, "WARNING: suspicious HTTP request contains double CR");
-        xfree(url);
         return parseHttpRequestAbort(conn, "error:double-CR");
     }
 
@@ -1946,6 +1945,35 @@
            (int) HttpParserRequestLen(hp) << ", req_line_sz = " <<
            HttpParserReqSz(hp));
 
+    // Temporary hack: We might receive a chunked body from a broken HTTP/1.1
+    // client that sends chunked requests to HTTP/1.0 Squid. If the request
+    // might have a chunked body, parse the headers early to look for the
+    // "Transfer-Encoding: chunked" header. If we find it, wait until the
+    // 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.
+    // 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
+        Config.maxChunkedRequestBodySize > 0 && // configured to dechunk
+        (*method_p == METHOD_PUT || *method_p == METHOD_POST)) {
+
+        // check only once per request because isChunkedRequest is expensive
+        if (conn->in.dechunkingState == ConnStateData::chunkUnknown) {
+            if (isChunkedRequest(hp))
+                conn->startDechunkingRequest(hp);
+            else
+                conn->in.dechunkingState = ConnStateData::chunkNone;
+        }
+
+        if (conn->in.dechunkingState == ConnStateData::chunkParsing) {
+            if (conn->parseRequestChunks(hp)) // parses newly read chunks
+                return NULL; // wait for more data
+            debugs(33, 5, HERE << "Got complete chunked request or err.");
+            assert(conn->in.dechunkingState != ConnStateData::chunkParsing);
+        }
+    }
+
     /* Ok, all headers are received */
     http = new ClientHttpRequest(conn);
 
@@ -1962,6 +1990,17 @@
 
     debugs(33, 5, "parseHttpRequest: Request Header is\n" <<(hp->buf) + hp->hdr_start);
 
+    /* set url */
+    /*
+     * XXX this should eventually not use a malloc'ed buffer; the transformation code
+     * below needs to be modified to not expect a mutable nul-terminated string.
+     */
+    char *url = (char *)xmalloc(hp->u_end - hp->u_start + 16);
+
+    memcpy(url, hp->buf + hp->u_start, hp->u_end - hp->u_start + 1);
+
+    url[hp->u_end - hp->u_start + 1] = '\0';
+
 #if THIS_VIOLATES_HTTP_SPECS_ON_URL_TRANSFORMATION
 
     if ((t = strchr(url, '#')))	/* remove HTML anchors */
@@ -2099,6 +2138,11 @@
 int
 connKeepReadingIncompleteRequest(ConnStateData::Pointer & conn)
 {
+    // when we read chunked requests, the entire body is buffered
+    // XXX: this check ignores header size and its limits.
+    if (conn->in.dechunkingState == ConnStateData::chunkParsing)
+        return conn->in.notYetUsed < Config.maxChunkedRequestBodySize;
+
     return conn->in.notYetUsed >= Config.maxRequestHeaderSize ? 0 : 1;
 }
 
@@ -2108,8 +2152,13 @@
     ClientSocketContext *context = parseHttpRequestAbort(conn, "error:request-too-large");
     clientStreamNode *node = context->getClientReplyContext();
     assert(!connKeepReadingIncompleteRequest(conn));
-    debugs(33, 1, "Request header is too large (" << conn->in.notYetUsed << " bytes)");
-    debugs(33, 1, "Config 'request_header_max_size'= " << Config.maxRequestHeaderSize << " bytes.");
+    if (conn->in.dechunkingState == ConnStateData::chunkParsing) {
+        debugs(33, 1, "Chunked request is too large (" << conn->in.notYetUsed << " bytes)");
+        debugs(33, 1, "Config 'chunked_request_body_max_size'= " << Config.maxChunkedRequestBodySize << " bytes.");
+    } else {
+        debugs(33, 1, "Request header is too large (" << conn->in.notYetUsed << " bytes)");
+        debugs(33, 1, "Config 'request_header_max_size'= " << Config.maxRequestHeaderSize << " bytes.");
+    }
     clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
     assert (repContext);
     repContext->setReplyToError(ERR_TOO_BIG,
@@ -2155,6 +2204,9 @@
     ClientHttpRequest *http = context->http;
     HttpRequest *request = NULL;
     bool notedUseOfBuffer = false;
+    bool tePresent = false;
+    bool deChunked = false;
+    bool unsupportedTe = false;
 
     /* We have an initial client stream in place should it be needed */
     /* setup our private context */
@@ -2238,8 +2290,17 @@
     request->my_port = ntohs(conn->me.sin_port);
     request->http_ver = http_ver;
 
-    if (!urlCheckRequest(request) ||
-            request->header.has(HDR_TRANSFER_ENCODING)) {
+    tePresent = request->header.has(HDR_TRANSFER_ENCODING);
+    deChunked = conn->in.dechunkingState == ConnStateData::chunkReady;
+    if (deChunked) {
+        assert(tePresent);
+        request->setContentLength(conn->in.dechunked.contentSize());
+        request->header.delById(HDR_TRANSFER_ENCODING);
+        conn->finishDechunkingRequest(hp);
+    }
+
+    unsupportedTe = tePresent && !deChunked;
+    if (!urlCheckRequest(request) || unsupportedTe) {
         clientStreamNode *node = context->getClientReplyContext();
         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
         assert (repContext);
@@ -2569,13 +2630,73 @@
 {
     assert(bodyPipe != NULL);
 
-    if (const size_t putSize = bodyPipe->putMoreData(in.buf, in.notYetUsed))
-        connNoteUseOfBuffer(this, putSize);
+    size_t putSize = 0;    
+
+#if FUTURE_CODE_TO_SUPPORT_CHUNKED_REQUESTS
+   // 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.
+   // The error generation code probably needs more work.
+    if (in.bodyParser) { // chunked body
+        debugs(33,5, HERE << "handling chunked request body for FD " << fd);
+        bool malformedChunks = false;
+
+        MemBuf raw; // ChunkedCodingParser only works with MemBufs
+        raw.init(in.notYetUsed, in.notYetUsed);
+        raw.append(in.buf, in.notYetUsed);
+        try { // the parser will throw on errors
+            const mb_size_t wasContentSize = raw.contentSize();
+            BodyPipeCheckout bpc(*bodyPipe);
+            const bool parsed = in.bodyParser->parse(&raw, &bpc.buf);
+            bpc.checkIn();
+            putSize = wasContentSize - raw.contentSize();
+
+            if (parsed) {
+                stopProducingFor(bodyPipe, true); // this makes bodySize known
+            } else {
+                // parser needy state must imply body pipe needy state
+                if (in.bodyParser->needsMoreData() &&
+                    !bodyPipe->mayNeedMoreData())
+                    malformedChunks = true;
+                // XXX: if bodyParser->needsMoreSpace, how can we guarantee it?
+            }
+        } catch (...) { // XXX: be more specific
+            malformedChunks = true;
+        }
+
+        if (malformedChunks) {
+            if (bodyPipe != NULL)
+                stopProducingFor(bodyPipe, false);
+
+            ClientSocketContext::Pointer context = getCurrentContext();
+            if (!context->http->out.offset) {
+                clientStreamNode *node = context->getClientReplyContext();
+                clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
+                assert (repContext);
+                repContext->setReplyToError(ERR_INVALID_REQ, HTTP_BAD_REQUEST,
+                    METHOD_NONE, NULL, &peer.sin_addr,
+                    NULL, NULL, NULL);
+                context->pullData();
+            }
+            flags.readMoreRequests = false;
+            return; // XXX: is that sufficient to generate an error?
+        }
+    } else // identity encoding 
+#endif
+    {
+        debugs(33,5, HERE << "handling plain request body for FD " << fd);
+        putSize = bodyPipe->putMoreData(in.buf, in.notYetUsed);
+        if (!bodyPipe->mayNeedMoreData()) {
+            // BodyPipe will clear us automagically when we produced everything
+            bodyPipe = NULL;
+        }
+    }
 
-    if (!bodyPipe->mayNeedMoreData()) {
-        // BodyPipe will clear us automagically when we produced everything
-        bodyPipe = NULL;
+    if (putSize > 0)
+        connNoteUseOfBuffer(this, putSize);
 
+    if (!bodyPipe) {
         debugs(33,5, HERE << "produced entire request body for FD " << fd);
 
         if (closing()) {
@@ -3281,17 +3402,119 @@
     bodyPipe->enableAutoConsumption();
 }
 
+// initialize dechunking state
+void
+ConnStateData::startDechunkingRequest(HttpParser *hp)
+{
+    debugs(33, 5, HERE << "start dechunking at " << HttpParserRequestLen(hp));
+    assert(in.dechunkingState == chunkUnknown);
+    assert(!in.bodyParser);
+    in.bodyParser = new ChunkedCodingParser;
+    in.chunkedSeen = HttpParserRequestLen(hp); // skip headers when dechunking
+    in.chunked.init();  // TODO: should we have a smaller-than-default limit?
+    in.dechunked.init();
+    in.dechunkingState = chunkParsing;
+}
+
+// put parsed content into input buffer and clean up
+void
+ConnStateData::finishDechunkingRequest(HttpParser *hp)
+{
+    debugs(33, 5, HERE << "finish dechunking; content: " << in.dechunked.contentSize());
+
+    assert(in.dechunkingState == chunkReady);
+    assert(in.bodyParser); 
+    delete in.bodyParser;
+    in.bodyParser = NULL;
+
+    const mb_size_t headerSize = HttpParserRequestLen(hp);
+
+    // dechunking cannot make data bigger
+    assert(headerSize + in.dechunked.contentSize() + in.chunked.contentSize()
+        <= static_cast<mb_size_t>(in.notYetUsed));
+    assert(in.notYetUsed <= in.allocatedSize);
+
+    // copy dechunked content
+    char *end = in.buf + headerSize;
+    xmemmove(end, in.dechunked.content(), in.dechunked.contentSize());
+    end += in.dechunked.contentSize();
+
+    // copy post-chunks leftovers, if any, caused by request pipelining?
+    if (in.chunked.contentSize()) {
+        xmemmove(end, in.chunked.content(), in.chunked.contentSize());
+        end += in.chunked.contentSize();
+    }
+
+    in.notYetUsed = end - in.buf;
+
+    in.chunked.clean();
+    in.dechunked.clean();
+    in.dechunkingState = chunkUnknown;
+}
+
+// parse newly read request chunks and buffer them for finishDechunkingRequest
+// returns true iff needs more data
+bool
+ConnStateData::parseRequestChunks(HttpParser *)
+{
+    debugs(33,5, HERE << "parsing chunked request body at " <<
+        in.chunkedSeen << " < " << in.notYetUsed);
+    assert(in.bodyParser);
+    assert(in.dechunkingState == chunkParsing);
+
+    assert(in.chunkedSeen <= in.notYetUsed);
+    const mb_size_t fresh = in.notYetUsed - in.chunkedSeen;
+
+    // be safe: count some chunked coding metadata towards the total body size
+    if (fresh + in.dechunked.contentSize() > Config.maxChunkedRequestBodySize) {
+        debugs(33,3, HERE << "chunked body (" << fresh << " + " <<
+            in.dechunked.contentSize() << " may exceed " <<
+            "chunked_request_body_max_size=" <<
+            Config.maxChunkedRequestBodySize);
+        in.dechunkingState = chunkError;
+        return false;
+    }
+        
+    if (fresh > in.chunked.potentialSpaceSize()) {
+        // should not happen if Config.maxChunkedRequestBodySize is reasonable
+        debugs(33,1, HERE << "request_body_max_size exceeds chunked buffer " <<
+            "size: " << fresh << " + " << in.chunked.contentSize() << " > " <<
+            in.chunked.potentialSpaceSize() << " with " <<
+            "chunked_request_body_max_size=" <<
+            Config.maxChunkedRequestBodySize);
+        in.dechunkingState = chunkError;
+        return false;
+    }
+    in.chunked.append(in.buf + in.chunkedSeen, fresh);
+    in.chunkedSeen += fresh;
+
+    try { // the parser will throw on errors
+        if (in.bodyParser->parse(&in.chunked, &in.dechunked))
+            in.dechunkingState = chunkReady; // successfully parsed all chunks
+        else
+            return true; // need more, keep the same state
+    } catch (...) {
+        debugs(33,3, HERE << "chunk parsing error");
+        in.dechunkingState = chunkError;
+    }
+    return false; // error, unsupported, or done
+}
+
 char *
 ConnStateData::In::addressToReadInto() const
 {
     return buf + notYetUsed;
 }
 
-ConnStateData::In::In() : buf (NULL), notYetUsed (0), allocatedSize (0)
+ConnStateData::In::In() : bodyParser(NULL),
+    buf (NULL), notYetUsed (0), allocatedSize (0),
+    dechunkingState(ConnStateData::chunkUnknown)
 {}
 
 ConnStateData::In::~In()
 {
     if (allocatedSize)
         memFreeBuf(allocatedSize, buf);
+    if (bodyParser)
+        delete bodyParser; // TODO: pool
 }
diff -u -r -N squid-3.0.STABLE15/src/client_side.h squid-3.0.STABLE16-RC1/src/client_side.h
--- squid-3.0.STABLE15/src/client_side.h	2009-05-06 23:11:41.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/client_side.h	2009-05-16 00:47:57.000000000 +1200
@@ -46,6 +46,9 @@
 
 class AuthUserRequest;
 
+class ChunkedCodingParser;
+class HttpParser;
+
 template <class T>
 
 class Range;
@@ -149,14 +152,23 @@
 
     int fd;
 
+    /// chunk buffering and parsing algorithm state
+    typedef enum { chunkUnknown, chunkNone, chunkParsing, chunkReady, chunkError } DechunkingState;
+
     struct In
     {
         In();
         ~In();
         char *addressToReadInto() const;
+
+        ChunkedCodingParser *bodyParser; ///< parses chunked request body
+        MemBuf chunked; ///< contains unparsed raw (chunked) body data
+        MemBuf dechunked; ///< accumulates parsed (dechunked) content
         char *buf;
         size_t notYetUsed;
         size_t allocatedSize;
+        size_t chunkedSeen; ///< size of processed or ignored raw read data
+        DechunkingState dechunkingState; ///< request dechunking state
     } in;
 
     int64_t bodySizeLeft();
@@ -208,6 +220,10 @@
     void handleReadData(char *buf, size_t size);
     void handleRequestBodyData();
 
+    void startDechunkingRequest(HttpParser *hp);
+    bool parseRequestChunks(HttpParser *hp);
+    void finishDechunkingRequest(HttpParser *hp);
+
 private:
     CBDATA_CLASS2(ConnStateData);
     bool transparent_;
diff -u -r -N squid-3.0.STABLE15/src/helper.cc squid-3.0.STABLE16-RC1/src/helper.cc
--- squid-3.0.STABLE15/src/helper.cc	2009-05-06 23:11:41.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/helper.cc	2009-05-16 00:47:58.000000000 +1200
@@ -1548,6 +1548,7 @@
                     && !srv->deferred_requests) {
                 int wfd = srv->wfd;
                 srv->wfd = -1;
+                srv->flags.closing=1;
                 comm_close(wfd);
             } else {
                 if (srv->queue.head)
diff -u -r -N squid-3.0.STABLE15/src/http.cc squid-3.0.STABLE16-RC1/src/http.cc
--- squid-3.0.STABLE15/src/http.cc	2009-05-06 23:11:41.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/http.cc	2009-05-16 00:47:58.000000000 +1200
@@ -56,6 +56,16 @@
 #include "DelayPools.h"
 #endif
 #include "SquidTime.h"
+#include "TextException.h"
+
+#define SQUID_ENTER_THROWING_CODE() try {
+#define SQUID_EXIT_THROWING_CODE(status) \
+  	status = true; \
+    } \
+    catch (const TextException &e) { \
+	debugs (11, 1, "Exception error:" << e.message); \
+	status = false; \
+    }  
 
 CBDATA_CLASS_INIT(HttpStateData);
 
@@ -68,7 +78,7 @@
         HttpHeader * hdr_out, int we_do_ranges, http_state_flags);
 
 HttpStateData::HttpStateData(FwdState *theFwdState) : ServerStateData(theFwdState),
-        header_bytes_read(0), reply_bytes_read(0)
+		       lastChunk(0), header_bytes_read(0), reply_bytes_read(0), httpChunkDecoder(NULL)
 {
     debugs(11,5,HERE << "HttpStateData " << this << " created");
     ignoreCacheControl = false;
@@ -119,7 +129,6 @@
         entry->setNoDelay(_peer->options.no_delay);
 
 #endif
-
     }
 
     /*
@@ -139,6 +148,9 @@
 
     delete readBuf;
 
+    if(httpChunkDecoder)
+	delete httpChunkDecoder;
+
     HTTPMSGUNLOCK(orig_request);
 
     debugs(11,5, HERE << "HttpStateData " << this << " destroyed; FD " << fd);
@@ -735,6 +747,12 @@
 	 readBuf->consume(header_bytes_read);
     }
 
+    flags.chunked = 0;
+    if (newrep->header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',')) {
+	 flags.chunked = 1;
+	 httpChunkDecoder = new ChunkedCodingParser;
+    }
+
     HttpReply *vrep = setVirginReply(newrep);
     flags.headers_parsed = 1;
 
@@ -899,6 +917,13 @@
     if (eof) // already reached EOF
         return COMPLETE_NONPERSISTENT_MSG;
 
+    /* In chunked responce we do not know the content length but we are absolutelly 
+     * sure about the end of response, so we are calling the statusIfComplete to
+     * decide if we can be persistant 
+     */
+    if (lastChunk && flags.chunked)
+	return statusIfComplete();
+
     const int64_t clen = vrep->bodySize(request->method);
 
     debugs(11, 5, "persistentConnStatus: clen=" << clen);
@@ -1098,10 +1123,31 @@
 {
     const char *data = readBuf->content();
     int len = readBuf->contentSize();
-
     addVirginReplyBody(data, len);
     readBuf->consume(len);
+}
 
+bool
+HttpStateData::decodeAndWriteReplyBody()
+{
+    const char *data = NULL;
+    int len;
+    bool status = false;
+    assert(flags.chunked);
+    assert(httpChunkDecoder);
+    SQUID_ENTER_THROWING_CODE();
+    MemBuf decodedData;
+    decodedData.init();
+    const bool done = httpChunkDecoder->parse(readBuf,&decodedData);
+    len = decodedData.contentSize();
+    data=decodedData.content();
+    addVirginReplyBody(data, len);
+    if (done) {
+        lastChunk = 1;
+        flags.do_next_read = 0;
+    }
+    SQUID_EXIT_THROWING_CODE(status);
+    return status;
 }
 
 /*
@@ -1134,7 +1180,15 @@
      * That means header content has been removed from readBuf and
      * it contains only body data.
      */
-    writeReplyBody();
+    if(flags.chunked){
+	if(!decodeAndWriteReplyBody()){
+	    flags.do_next_read = 0;
+	    serverComplete();
+	    return;
+	}
+    }
+    else
+	writeReplyBody();
 
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
         /*
diff -u -r -N squid-3.0.STABLE15/src/http.h squid-3.0.STABLE16-RC1/src/http.h
--- squid-3.0.STABLE15/src/http.h	2009-05-06 23:11:41.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/http.h	2009-05-16 00:47:58.000000000 +1200
@@ -1,6 +1,6 @@
 
 /*
- * $Id: http.h,v 1.32 2007/08/09 23:30:53 rousskov Exp $
+ * $Id: http.h,v 1.33 2007/12/26 23:39:55 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -38,6 +38,7 @@
 #include "comm.h"
 #include "forward.h"
 #include "Server.h"
+#include "ChunkedCodingParser.h"
 
 class HttpStateData : public ServerStateData
 {
@@ -65,6 +66,7 @@
 
     peer *_peer;		/* peer request made to */
     int eof;			/* reached end-of-object? */
+    int lastChunk;		/* reached last chunk of a chunk-encoded reply */
     HttpRequest *orig_request;
     int fd;
     http_state_flags flags;
@@ -103,6 +105,7 @@
     virtual void handleRequestBodyProducerAborted();
 
     void writeReplyBody();
+    bool decodeAndWriteReplyBody();
     void doneSendingRequestBody();
     void requestBodyHandler(MemBuf &);
     virtual void sentRequestBody(int fd, size_t size, comm_err_t errflag);
@@ -113,6 +116,7 @@
                                  http_state_flags flags);
     static bool decideIfWeDoRanges (HttpRequest * orig_request);
 
+    ChunkedCodingParser *httpChunkDecoder;
 private:
     CBDATA_CLASS2(HttpStateData);
 };
diff -u -r -N squid-3.0.STABLE15/src/HttpMsg.cc squid-3.0.STABLE16-RC1/src/HttpMsg.cc
--- squid-3.0.STABLE15/src/HttpMsg.cc	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/HttpMsg.cc	2009-05-16 00:47:57.000000000 +1200
@@ -309,6 +309,14 @@
     return -1;
 }
 
+void
+HttpMsg::setContentLength(int64_t clen)
+{
+    header.delById(HDR_CONTENT_LENGTH); // if any
+    header.putInt64(HDR_CONTENT_LENGTH, clen);
+    content_length = clen;
+}
+
 /* returns true if connection should be "persistent"
  * after processing this message */
 int
diff -u -r -N squid-3.0.STABLE15/src/HttpMsg.h squid-3.0.STABLE16-RC1/src/HttpMsg.h
--- squid-3.0.STABLE15/src/HttpMsg.h	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/HttpMsg.h	2009-05-16 00:47:57.000000000 +1200
@@ -55,6 +55,9 @@
     virtual HttpMsg *_lock();	// please use HTTPMSGLOCK()
     virtual void _unlock();	// please use HTTPMSGUNLOCK()
 
+    /// [re]sets Content-Length header and cached value
+    void setContentLength(int64_t clen);
+
 public:
     HttpVersion http_ver;
 
@@ -104,7 +107,8 @@
 };
 
 /* Temporary parsing state; might turn into the replacement parser later on */
-struct _HttpParser {
+class HttpParser {
+public:
 	char state;
 	const char *buf;
 	int bufsiz;
@@ -115,7 +119,6 @@
 	int v_start, v_end;
 	int v_maj, v_min;
 };
-typedef struct _HttpParser HttpParser;
 
 extern void HttpParserInit(HttpParser *, const char *buf, int len);
 extern int HttpParserParseReqLine(HttpParser *hp);
diff -u -r -N squid-3.0.STABLE15/src/ICAP/ChunkedCodingParser.cc squid-3.0.STABLE16-RC1/src/ICAP/ChunkedCodingParser.cc
--- squid-3.0.STABLE15/src/ICAP/ChunkedCodingParser.cc	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/ICAP/ChunkedCodingParser.cc	1970-01-01 12:00:00.000000000 +1200
@@ -1,245 +0,0 @@
-#include "squid.h"
-#include "Parsing.h"
-#include "TextException.h"
-#include "ChunkedCodingParser.h"
-#include "MemBuf.h"
-
-ChunkedCodingParser::Step ChunkedCodingParser::psChunkBeg = &ChunkedCodingParser::parseChunkBeg;
-ChunkedCodingParser::Step ChunkedCodingParser::psChunkBody = &ChunkedCodingParser::parseChunkBody;
-ChunkedCodingParser::Step ChunkedCodingParser::psChunkEnd = &ChunkedCodingParser::parseChunkEnd;
-ChunkedCodingParser::Step ChunkedCodingParser::psTrailer = &ChunkedCodingParser::parseTrailer;
-ChunkedCodingParser::Step ChunkedCodingParser::psMessageEnd = &ChunkedCodingParser::parseMessageEnd;
-
-ChunkedCodingParser::ChunkedCodingParser()
-{
-    reset();
-}
-
-void ChunkedCodingParser::reset()
-{
-    theStep = psChunkBeg;
-    theChunkSize = theLeftBodySize = 0;
-    doNeedMoreData = false;
-    sawIeof = false;
-    theIn = theOut = NULL;
-}
-
-bool ChunkedCodingParser::parse(MemBuf *rawData, MemBuf *parsedContent)
-{
-    Must(rawData && parsedContent);
-    theIn = rawData;
-    theOut = parsedContent;
-
-    // we must reset this all the time so that mayContinue() lets us
-    // output more content if we stopped due to needsMoreSpace() before
-    doNeedMoreData = !theIn->hasContent();
-
-    while (mayContinue()) {
-        (this->*theStep)();
-    }
-
-    return theStep == psMessageEnd;
-}
-
-bool ChunkedCodingParser::needsMoreData() const
-{
-    return doNeedMoreData;
-}
-
-bool ChunkedCodingParser::needsMoreSpace() const
-{
-    assert(theOut);
-    return theStep == psChunkBody && !theOut->hasPotentialSpace();
-}
-
-bool ChunkedCodingParser::mayContinue() const
-{
-    return !needsMoreData() && !needsMoreSpace() && theStep != psMessageEnd;
-}
-
-void ChunkedCodingParser::parseChunkBeg()
-{
-    Must(theChunkSize <= 0); // Should(), really
-
-    size_t crlfBeg = 0;
-    size_t crlfEnd = 0;
-
-    if (findCrlf(crlfBeg, crlfEnd)) {
-        debugs(93,7, "found chunk-size end: " << crlfBeg << "-" << crlfEnd);
-        int64_t size = -1;
-        const char *p = 0;
-
-        if (StringToInt64(theIn->content(), size, &p, 16)) {
-            if (size < 0) {
-                throw TexcHere("negative chunk size");
-                return;
-            }
-
-            // check for ieof chunk extension in the last-chunk
-            if (size == 0 && p && *p++ == ';') {
-                const char *e = theIn->content() + crlfBeg; // end of extension
-
-                while (p < e && xisspace(*p))
-                    ++p; // skip space
-
-                sawIeof = e - p >= 4 &&
-                          strncmp(p, "ieof", 4) == 0 &&
-                          xisspace(p[4]);
-            }
-
-            theIn->consume(crlfEnd);
-            theChunkSize = theLeftBodySize = size;
-            debugs(93,7, "found chunk: " << theChunkSize);
-            theStep = theChunkSize == 0 ? psTrailer : psChunkBody;
-            return;
-        }
-
-        throw TexcHere("corrupted chunk size");
-    }
-
-    doNeedMoreData = true;
-}
-
-void ChunkedCodingParser::parseChunkBody()
-{
-    Must(theLeftBodySize > 0); // Should, really
-
-    const size_t availSize = XMIN(theLeftBodySize, (uint64_t)theIn->contentSize());
-    const size_t safeSize = XMIN(availSize, (size_t)theOut->potentialSpaceSize());
-
-    doNeedMoreData = availSize < theLeftBodySize;
-    // and we may also need more space
-
-    theOut->append(theIn->content(), safeSize);
-    theIn->consume(safeSize);
-    theLeftBodySize -= safeSize;
-
-    if (theLeftBodySize == 0)
-        theStep = psChunkEnd;
-    else
-        Must(needsMoreData() || needsMoreSpace());
-}
-
-void ChunkedCodingParser::parseChunkEnd()
-{
-    Must(theLeftBodySize == 0); // Should(), really
-
-    size_t crlfBeg = 0;
-    size_t crlfEnd = 0;
-
-    if (findCrlf(crlfBeg, crlfEnd)) {
-        if (crlfBeg != 0) {
-            throw TexcHere("found data bewteen chunk end and CRLF");
-            return;
-        }
-
-        theIn->consume(crlfEnd);
-        theChunkSize = 0; // done with the current chunk
-        theStep = psChunkBeg;
-        return;
-    }
-
-    doNeedMoreData = true;
-}
-
-void ChunkedCodingParser::parseTrailer()
-{
-    Must(theChunkSize == 0); // Should(), really
-
-    while (mayContinue())
-        parseTrailerHeader();
-}
-
-void ChunkedCodingParser::parseTrailerHeader()
-{
-    size_t crlfBeg = 0;
-    size_t crlfEnd = 0;
-
-    if (findCrlf(crlfBeg, crlfEnd)) {
-        if (crlfBeg > 0)
-
-            ; //theTrailer.append(theIn->content(), crlfEnd);
-
-        theIn->consume(crlfEnd);
-
-        if (crlfBeg == 0)
-            theStep = psMessageEnd;
-
-        return;
-    }
-
-    doNeedMoreData = true;
-}
-
-void ChunkedCodingParser::parseMessageEnd()
-{
-    // termination step, should not be called
-    Must(false); // Should(), really
-}
-
-// finds next CRLF
-bool ChunkedCodingParser::findCrlf(size_t &crlfBeg, size_t &crlfEnd)
-{
-    // XXX: This code was copied, with permission, from another software.
-    // There is a similar and probably better code inside httpHeaderParse
-    // but it seems difficult to isolate due to parsing-unrelated bloat.
-    // Such isolation should probably be done before this class is used
-    // for handling of traffic "more external" than ICAP.
-
-    const char *buf = theIn->content();
-    size_t size = theIn->contentSize();
-
-    ssize_t crOff = -1;
-    bool quoted = false;
-    bool slashed = false;
-
-    for (size_t i = 0; i < size; ++i) {
-        if (slashed) {
-            slashed = false;
-            continue;
-        }
-
-        const char c = buf[i];
-
-        // handle quoted strings
-        if (quoted) {
-            if (c == '\\')
-                slashed = true;
-            else
-                if (c == '"')
-                    quoted = false;
-
-            continue;
-        } else
-            if (c == '"') {
-                quoted = true;
-                crOff = -1;
-                continue;
-            }
-
-        if (crOff < 0) { // looking for the first CR or LF
-
-            if (c == '\n') {
-                crlfBeg = i;
-                crlfEnd = ++i;
-                return true;
-            }
-
-            if (c == '\r')
-                crOff = i;
-        } else { // skipping CRs, looking for the first LF
-
-            if (c == '\n') {
-                crlfBeg = crOff;
-                crlfEnd = ++i;
-                return true;
-            }
-
-            if (c != '\r')
-                crOff = -1;
-        }
-    }
-
-    return false;
-}
-
diff -u -r -N squid-3.0.STABLE15/src/ICAP/ChunkedCodingParser.h squid-3.0.STABLE16-RC1/src/ICAP/ChunkedCodingParser.h
--- squid-3.0.STABLE15/src/ICAP/ChunkedCodingParser.h	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/ICAP/ChunkedCodingParser.h	1970-01-01 12:00:00.000000000 +1200
@@ -1,90 +0,0 @@
-
-/*
- * $Id: ChunkedCodingParser.h,v 1.3 2007/08/13 17:20:53 hno Exp $
- * 
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *  
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *  
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
-
-#ifndef SQUID_CHUNKEDCODINGPARSER_H
-#define SQUID_CHUNKEDCODINGPARSER_H
-
-#include "RefCount.h"
-
-// ChunkedCodingParser is an incremental parser for chunked transfer coding
-// used by HTTP and ICAP. The parser shovels content bytes from the raw
-// input buffer into the content output buffer, both caller-supplied.
-// Ignores chunk extensions except for ICAP's ieof.
-// Has a trailer-handling placeholder.
-
-class ChunkedCodingParser
-{
-
-public:
-    ChunkedCodingParser();
-
-    void reset();
-
-    // true = complete success; false == needs more data
-    bool parse(MemBuf *rawData, MemBuf *parsedContent); // throws on error
-
-    bool needsMoreData() const;
-    bool needsMoreSpace() const;
-    bool sawIeof; // saw ieof chunk extension after a 0-size chunk
-
-private:
-    typedef void (ChunkedCodingParser::*Step)();
-
-private:
-    bool mayContinue() const;
-
-    void parseChunkBeg();
-    void parseChunkBody();
-    void parseChunkEnd();
-    void parseTrailer();
-    void parseTrailerHeader();
-    void parseMessageEnd();
-
-    bool findCrlf(size_t &crlfBeg, size_t &crlfEnd);
-
-private:
-    static Step psChunkBeg;
-    static Step psChunkBody;
-    static Step psChunkEnd;
-    static Step psTrailer;
-    static Step psMessageEnd;
-
-    MemBuf *theIn;
-    MemBuf *theOut;
-
-    Step theStep;
-    uint64_t theChunkSize;
-    uint64_t theLeftBodySize;
-    bool doNeedMoreData;
-};
-
-#endif /* SQUID_CHUNKEDCODINGPARSER_H */
diff -u -r -N squid-3.0.STABLE15/src/ICAP/TextException.cc squid-3.0.STABLE16-RC1/src/ICAP/TextException.cc
--- squid-3.0.STABLE15/src/ICAP/TextException.cc	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/ICAP/TextException.cc	1970-01-01 12:00:00.000000000 +1200
@@ -1,27 +0,0 @@
-#include "squid.h"
-#include "TextException.h"
-
-TextException::TextException(const char *aMsg, const char *aFileName, int aLineNo):
-        message(xstrdup(aMsg)), theFileName(aFileName), theLineNo(aLineNo)
-{}
-
-TextException::~TextException()
-{
-    xfree(message);
-}
-
-void Throw(const char *message, const char *fileName, int lineNo)
-{
-
-    // or should we let the exception recepient print the exception instead?
-
-    if (fileName) {
-        debugs(0, 3, fileName << ':' << lineNo << ": exception" <<
-               (message ? ": " : ".") << (message ? message : ""));
-    } else {
-        debugs(0, 3, "exception" <<
-               (message ? ": " : ".") << (message ? message : ""));
-    }
-
-    throw TextException(message, fileName, lineNo);
-}
diff -u -r -N squid-3.0.STABLE15/src/ICAP/TextException.h squid-3.0.STABLE16-RC1/src/ICAP/TextException.h
--- squid-3.0.STABLE15/src/ICAP/TextException.h	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/ICAP/TextException.h	1970-01-01 12:00:00.000000000 +1200
@@ -1,46 +0,0 @@
-#ifndef SQUID__TEXTEXCEPTION_H
-#define SQUID__TEXTEXCEPTION_H
-
-// Origin: xstd/TextException
-
-
-// simple exception to report custom errors
-// we may want to change the interface to be able to report system errors
-
-class TextException
-{
-
-public:
-    TextException(const char *aMessage, const char *aFileName = 0, int aLineNo = -1);
-    ~TextException();
-
-    // ostream &print(ostream &os) const;
-
-public:
-    char *message; // read-only
-
-protected:
-    // optional location information
-    const char *theFileName;
-    int theLineNo;
-};
-
-//inline
-//ostream &operator <<(ostream &os, const TextException &exx) {
-//    return exx.print(os);
-//}
-
-#if !defined(TexcHere)
-#    define TexcHere(msg) TextException((msg), __FILE__, __LINE__)
-#endif
-
-extern void Throw(const char *message, const char *fileName, int lineNo);
-
-// Must(condition) is like assert(condition) but throws an exception instead
-#if !defined(Must)
-#   define Must(cond) ((cond) ? \
-        (void)0 : \
-        (void)Throw(#cond, __FILE__, __LINE__))
-#endif
-
-#endif /* SQUID__TEXTEXCEPTION_H */
diff -u -r -N squid-3.0.STABLE15/src/Makefile.am squid-3.0.STABLE16-RC1/src/Makefile.am
--- squid-3.0.STABLE15/src/Makefile.am	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/Makefile.am	2009-05-16 00:47:57.000000000 +1200
@@ -426,6 +426,8 @@
 	carp.cc \
 	cbdata.cc \
 	cbdata.h \
+	ChunkedCodingParser.cc \
+	ChunkedCodingParser.h \
 	client_db.cc \
 	client_side.cc \
 	client_side.h \
@@ -605,6 +607,8 @@
 	structs.h \
 	SwapDir.cc \
 	SwapDir.h \
+	TextException.cc \
+	TextException.h \
 	time.cc \
 	tools.cc \
 	tunnel.cc \
@@ -677,8 +681,6 @@
 ICAP_libicap_a_SOURCES = \
 	ICAP/AsyncJob.cc \
 	ICAP/AsyncJob.h \
- 	ICAP/ChunkedCodingParser.cc \
- 	ICAP/ChunkedCodingParser.h \
 	ICAP/ICAPClient.cc \
 	ICAP/ICAPClient.h \
 	ICAP/ICAPInitiator.cc \
@@ -701,9 +703,7 @@
 	ICAP/ICAPServiceRep.cc \
 	ICAP/ICAPServiceRep.h \
 	ICAP/ICAPXaction.cc \
-	ICAP/ICAPXaction.h \
-	ICAP/TextException.cc \
-	ICAP/TextException.h
+	ICAP/ICAPXaction.h
 
 
 unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc
@@ -769,6 +769,8 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
+	ChunkedCodingParser.h \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -873,6 +875,8 @@
 	store_swapout.cc \
 	structs.h \
 	SwapDir.cc \
+	TextException.cc \
+	TextException.h \
 	tools.cc \
 	typedefs.h \
 	$(UNLINKDSOURCE) \
@@ -1305,6 +1309,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -1397,6 +1402,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -1473,6 +1479,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -1564,6 +1571,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -1627,6 +1635,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -1718,6 +1727,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -1805,6 +1815,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -1902,6 +1913,7 @@
 	StoreSwapLogData.cc \
 	String.cc \
 	SwapDir.cc \
+	TextException.cc \
 	time.cc \
 	tools.cc \
 	tunnel.cc \
@@ -1966,6 +1978,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -2058,6 +2071,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -2307,6 +2321,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -2398,6 +2413,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
diff -u -r -N squid-3.0.STABLE15/src/Makefile.in squid-3.0.STABLE16-RC1/src/Makefile.in
--- squid-3.0.STABLE15/src/Makefile.in	2009-05-06 23:11:40.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/Makefile.in	2009-05-16 00:47:57.000000000 +1200
@@ -77,13 +77,12 @@
 ICAP_libicap_a_LIBADD =
 am__dirstamp = $(am__leading_dot)dirstamp
 am_ICAP_libicap_a_OBJECTS = ICAP/AsyncJob.$(OBJEXT) \
-	ICAP/ChunkedCodingParser.$(OBJEXT) ICAP/ICAPClient.$(OBJEXT) \
-	ICAP/ICAPInitiator.$(OBJEXT) ICAP/ICAPInitiate.$(OBJEXT) \
-	ICAP/ICAPLauncher.$(OBJEXT) ICAP/ICAPConfig.$(OBJEXT) \
-	ICAP/ICAPElements.$(OBJEXT) ICAP/ICAPModXact.$(OBJEXT) \
-	ICAP/ICAPOptions.$(OBJEXT) ICAP/ICAPOptXact.$(OBJEXT) \
-	ICAP/ICAPServiceRep.$(OBJEXT) ICAP/ICAPXaction.$(OBJEXT) \
-	ICAP/TextException.$(OBJEXT)
+	ICAP/ICAPClient.$(OBJEXT) ICAP/ICAPInitiator.$(OBJEXT) \
+	ICAP/ICAPInitiate.$(OBJEXT) ICAP/ICAPLauncher.$(OBJEXT) \
+	ICAP/ICAPConfig.$(OBJEXT) ICAP/ICAPElements.$(OBJEXT) \
+	ICAP/ICAPModXact.$(OBJEXT) ICAP/ICAPOptions.$(OBJEXT) \
+	ICAP/ICAPOptXact.$(OBJEXT) ICAP/ICAPServiceRep.$(OBJEXT) \
+	ICAP/ICAPXaction.$(OBJEXT)
 ICAP_libicap_a_OBJECTS = $(am_ICAP_libicap_a_OBJECTS)
 libAIO_a_AR = $(AR) $(ARFLAGS)
 libAIO_a_LIBADD =
@@ -198,7 +197,8 @@
 	AsyncCall.cc AsyncCall.h AsyncEngine.cc AsyncEngine.h \
 	authenticate.cc authenticate.h cache_cf.cc CacheDigest.cc \
 	cache_manager.cc CacheManager.h carp.cc cbdata.cc cbdata.h \
-	client_db.cc client_side.cc client_side.h client_side_reply.cc \
+	ChunkedCodingParser.cc ChunkedCodingParser.h client_db.cc \
+	client_side.cc client_side.h client_side_reply.cc \
 	client_side_reply.h client_side_request.cc \
 	client_side_request.h BodyPipe.cc BodyPipe.h \
 	ClientRequestContext.h clientStream.cc clientStream.h CommIO.h \
@@ -261,10 +261,11 @@
 	StoreMetaUnpacker.h StoreMetaURL.cc StoreMetaURL.h \
 	StoreMetaVary.cc StoreMetaVary.h StoreSearch.h \
 	StoreSwapLogData.cc StoreSwapLogData.h Server.cc Server.h \
-	structs.h SwapDir.cc SwapDir.h time.cc tools.cc tunnel.cc \
-	typedefs.h unlinkd.cc url.cc URL.h URLScheme.cc URLScheme.h \
-	urn.cc useragent.cc wccp.cc wccp2.cc whois.cc wordlist.cc \
-	wordlist.h win32.cc WinSvc.cc
+	structs.h SwapDir.cc SwapDir.h TextException.cc \
+	TextException.h time.cc tools.cc tunnel.cc typedefs.h \
+	unlinkd.cc url.cc URL.h URLScheme.cc URLScheme.h urn.cc \
+	useragent.cc wccp.cc wccp2.cc whois.cc wordlist.cc wordlist.h \
+	win32.cc WinSvc.cc
 am__objects_4 = ACLARP.$(OBJEXT)
 @ENABLE_ARP_ACL_TRUE@am__objects_5 = $(am__objects_4)
 am__objects_6 = $(am__objects_5) ACLASN.$(OBJEXT) ACLBrowser.$(OBJEXT) \
@@ -323,7 +324,8 @@
 	asn.$(OBJEXT) AsyncCall.$(OBJEXT) AsyncEngine.$(OBJEXT) \
 	authenticate.$(OBJEXT) cache_cf.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) cache_manager.$(OBJEXT) carp.$(OBJEXT) \
-	cbdata.$(OBJEXT) client_db.$(OBJEXT) client_side.$(OBJEXT) \
+	cbdata.$(OBJEXT) ChunkedCodingParser.$(OBJEXT) \
+	client_db.$(OBJEXT) client_side.$(OBJEXT) \
 	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
 	BodyPipe.$(OBJEXT) clientStream.$(OBJEXT) \
 	CompletionDispatcher.$(OBJEXT) $(am__objects_7) \
@@ -365,12 +367,12 @@
 	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
 	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
 	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	Server.$(OBJEXT) SwapDir.$(OBJEXT) time.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) $(am__objects_24) \
-	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
-	useragent.$(OBJEXT) wccp.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) wordlist.$(OBJEXT) $(am__objects_25) \
-	$(am__objects_26)
+	Server.$(OBJEXT) SwapDir.$(OBJEXT) TextException.$(OBJEXT) \
+	time.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
+	$(am__objects_24) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) useragent.$(OBJEXT) wccp.$(OBJEXT) \
+	wccp2.$(OBJEXT) whois.$(OBJEXT) wordlist.$(OBJEXT) \
+	$(am__objects_25) $(am__objects_26)
 am__EXTRA_squid_SOURCES_DIST = fs/aufs/StoreFSaufs.cc \
 	fs/coss/StoreFScoss.cc fs/diskd/StoreFSdiskd.cc \
 	fs/null/StoreFSnull.cc fs/ufs/StoreFSufs.cc \
@@ -467,28 +469,29 @@
 	ACLChecklist.cc ACLProxyAuth.cc ACLStringData.cc \
 	ACLRegexData.cc ACLUserData.cc AsyncCall.cc authenticate.cc \
 	BodyPipe.cc cache_manager.cc cache_cf.cc CacheDigest.cc \
-	carp.cc cbdata.cc client_db.cc client_side.cc \
-	client_side_reply.cc client_side_request.cc clientStream.cc \
-	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
-	comm_poll.h comm_epoll.cc comm_epoll.h comm_kqueue.cc \
-	comm_kqueue.h ConfigOption.cc ConfigParser.cc CommonPool.h \
-	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
-	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
-	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
-	DelaySpec.cc DelaySpec.h DelayTagged.cc DelayTagged.h \
-	DelayUser.cc DelayUser.h DelayVector.cc DelayVector.h \
-	NullDelayId.cc NullDelayId.h disk.cc dns_internal.cc dns.cc \
-	event.cc errorpage.cc ElementList.h ESI.cc ESI.h ESIAssign.cc \
-	ESIAssign.h ESIAttempt.h ESIContext.cc ESIContext.h \
-	ESICustomParser.cc ESICustomParser.h ESIElement.h ESIExcept.h \
-	ESIExpatParser.cc ESIExpatParser.h ESIExpression.cc \
-	ESIExpression.h ESIInclude.cc ESIInclude.h ESILiteral.h \
-	ESILibxml2Parser.cc ESILibxml2Parser.h ESIParser.cc \
-	ESIParser.h ESISegment.cc ESISegment.h ESISequence.cc \
-	ESISequence.h ESIVar.h ESIVarState.cc ESIVarState.h ETag.cc \
-	external_acl.cc ExternalACLEntry.cc fd.cc fde.cc forward.cc \
-	fqdncache.cc ftp.cc gopher.cc helper.cc htcp.cc htcp.h http.cc \
-	HttpBody.cc HttpHeader.cc HttpHeaderTools.cc HttpHdrCc.cc \
+	carp.cc cbdata.cc ChunkedCodingParser.cc client_db.cc \
+	client_side.cc client_side_reply.cc client_side_request.cc \
+	clientStream.cc comm_select.cc comm_select.h \
+	comm_select_win32.cc comm_poll.cc comm_poll.h comm_epoll.cc \
+	comm_epoll.h comm_kqueue.cc comm_kqueue.h ConfigOption.cc \
+	ConfigParser.cc CommonPool.h CompositePoolNode.h \
+	delay_pools.cc DelayId.cc DelayId.h DelayIdComposite.h \
+	DelayBucket.cc DelayBucket.h DelayConfig.cc DelayConfig.h \
+	DelayPool.cc DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
+	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
+	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
+	disk.cc dns_internal.cc dns.cc event.cc errorpage.cc \
+	ElementList.h ESI.cc ESI.h ESIAssign.cc ESIAssign.h \
+	ESIAttempt.h ESIContext.cc ESIContext.h ESICustomParser.cc \
+	ESICustomParser.h ESIElement.h ESIExcept.h ESIExpatParser.cc \
+	ESIExpatParser.h ESIExpression.cc ESIExpression.h \
+	ESIInclude.cc ESIInclude.h ESILiteral.h ESILibxml2Parser.cc \
+	ESILibxml2Parser.h ESIParser.cc ESIParser.h ESISegment.cc \
+	ESISegment.h ESISequence.cc ESISequence.h ESIVar.h \
+	ESIVarState.cc ESIVarState.h ETag.cc external_acl.cc \
+	ExternalACLEntry.cc fd.cc fde.cc forward.cc fqdncache.cc \
+	ftp.cc gopher.cc helper.cc htcp.cc htcp.h http.cc HttpBody.cc \
+	HttpHeader.cc HttpHeaderTools.cc HttpHdrCc.cc \
 	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
 	HttpHdrScTarget.cc HttpMsg.cc HttpReply.cc HttpStatusLine.cc \
 	icmp.cc icp_v2.cc icp_v3.cc ACLIdent.cc ACLIdent.h ident.cc \
@@ -506,9 +509,9 @@
 	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
 	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
-	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
-	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
-	whois.cc win32.cc wordlist.cc
+	StoreMetaVary.cc StoreSwapLogData.cc TextException.cc tools.cc \
+	tunnel.cc SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc \
+	wccp2.cc whois.cc win32.cc wordlist.cc
 am_tests_testCacheManager_OBJECTS = debug.$(OBJEXT) globals.$(OBJEXT) \
 	HttpRequest.$(OBJEXT) HttpRequestMethod.$(OBJEXT) \
 	mem.$(OBJEXT) String.$(OBJEXT) \
@@ -520,12 +523,13 @@
 	AsyncCall.$(OBJEXT) authenticate.$(OBJEXT) BodyPipe.$(OBJEXT) \
 	cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
-	client_db.$(OBJEXT) client_side.$(OBJEXT) \
-	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
-	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
-	ConfigParser.$(OBJEXT) $(am__objects_9) disk.$(OBJEXT) \
-	$(am__objects_11) event.$(OBJEXT) errorpage.$(OBJEXT) \
-	$(am__objects_13) ETag.$(OBJEXT) external_acl.$(OBJEXT) \
+	ChunkedCodingParser.$(OBJEXT) client_db.$(OBJEXT) \
+	client_side.$(OBJEXT) client_side_reply.$(OBJEXT) \
+	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
+	$(am__objects_7) ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
+	$(am__objects_9) disk.$(OBJEXT) $(am__objects_11) \
+	event.$(OBJEXT) errorpage.$(OBJEXT) $(am__objects_13) \
+	ETag.$(OBJEXT) external_acl.$(OBJEXT) \
 	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
 	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
 	gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_14) \
@@ -555,10 +559,11 @@
 	StoreMetaMD5.$(OBJEXT) StoreMetaSTD.$(OBJEXT) \
 	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
 	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
-	StoreSwapLogData.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
-	SwapDir.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
-	urn.$(OBJEXT) useragent.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) $(am__objects_25) wordlist.$(OBJEXT)
+	StoreSwapLogData.$(OBJEXT) TextException.$(OBJEXT) \
+	tools.$(OBJEXT) tunnel.$(OBJEXT) SwapDir.$(OBJEXT) \
+	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
+	useragent.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
+	$(am__objects_25) wordlist.$(OBJEXT)
 nodist_tests_testCacheManager_OBJECTS = repl_modules.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 tests_testCacheManager_OBJECTS = $(am_tests_testCacheManager_OBJECTS) \
@@ -700,11 +705,11 @@
 	ACLProxyAuth.cc ACLStringData.cc ACLRegexData.cc \
 	ACLUserData.cc AsyncCall.cc authenticate.cc BodyPipe.cc \
 	cache_manager.cc cache_cf.cc CacheDigest.cc carp.cc cbdata.cc \
-	client_db.cc client_side.cc client_side_reply.cc \
-	client_side_request.cc clientStream.cc comm_select.cc \
-	comm_select.h comm_select_win32.cc comm_poll.cc comm_poll.h \
-	comm_epoll.cc comm_epoll.h comm_kqueue.cc comm_kqueue.h \
-	ConfigOption.cc ConfigParser.cc CommonPool.h \
+	ChunkedCodingParser.cc client_db.cc client_side.cc \
+	client_side_reply.cc client_side_request.cc clientStream.cc \
+	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
+	comm_poll.h comm_epoll.cc comm_epoll.h comm_kqueue.cc \
+	comm_kqueue.h ConfigOption.cc ConfigParser.cc CommonPool.h \
 	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
 	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
 	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
@@ -739,9 +744,9 @@
 	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
 	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
 	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreSwapLogData.cc tools.cc tunnel.cc SwapDir.cc url.cc \
-	URLScheme.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
-	wordlist.cc
+	StoreSwapLogData.cc TextException.cc tools.cc tunnel.cc \
+	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
+	whois.cc win32.cc wordlist.cc
 am_tests_testEvent_OBJECTS = debug.$(OBJEXT) EventLoop.$(OBJEXT) \
 	globals.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) \
@@ -754,12 +759,13 @@
 	AsyncCall.$(OBJEXT) authenticate.$(OBJEXT) BodyPipe.$(OBJEXT) \
 	cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
-	client_db.$(OBJEXT) client_side.$(OBJEXT) \
-	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
-	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
-	ConfigParser.$(OBJEXT) $(am__objects_9) disk.$(OBJEXT) \
-	$(am__objects_11) event.$(OBJEXT) errorpage.$(OBJEXT) \
-	$(am__objects_13) ETag.$(OBJEXT) external_acl.$(OBJEXT) \
+	ChunkedCodingParser.$(OBJEXT) client_db.$(OBJEXT) \
+	client_side.$(OBJEXT) client_side_reply.$(OBJEXT) \
+	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
+	$(am__objects_7) ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
+	$(am__objects_9) disk.$(OBJEXT) $(am__objects_11) \
+	event.$(OBJEXT) errorpage.$(OBJEXT) $(am__objects_13) \
+	ETag.$(OBJEXT) external_acl.$(OBJEXT) \
 	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
 	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
 	gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_14) \
@@ -789,10 +795,10 @@
 	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
 	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
 	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) SwapDir.$(OBJEXT) \
-	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
-	useragent.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
-	$(am__objects_25) wordlist.$(OBJEXT)
+	TextException.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
+	SwapDir.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) useragent.$(OBJEXT) wccp2.$(OBJEXT) \
+	whois.$(OBJEXT) $(am__objects_25) wordlist.$(OBJEXT)
 nodist_tests_testEvent_OBJECTS = repl_modules.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 tests_testEvent_OBJECTS = $(am_tests_testEvent_OBJECTS) \
@@ -807,11 +813,12 @@
 	acl.cc acl_noncore.cc ACLChecklist.cc ACLProxyAuth.cc \
 	ACLStringData.cc ACLRegexData.cc ACLUserData.cc AsyncCall.cc \
 	authenticate.cc BodyPipe.cc cache_manager.cc cache_cf.cc \
-	CacheDigest.cc carp.cc cbdata.cc client_db.cc client_side.cc \
-	client_side_reply.cc client_side_request.cc clientStream.cc \
-	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
-	comm_poll.h comm_epoll.cc comm_epoll.h comm_kqueue.cc \
-	comm_kqueue.h ConfigOption.cc ConfigParser.cc CommonPool.h \
+	CacheDigest.cc carp.cc cbdata.cc ChunkedCodingParser.cc \
+	client_db.cc client_side.cc client_side_reply.cc \
+	client_side_request.cc clientStream.cc comm_select.cc \
+	comm_select.h comm_select_win32.cc comm_poll.cc comm_poll.h \
+	comm_epoll.cc comm_epoll.h comm_kqueue.cc comm_kqueue.h \
+	ConfigOption.cc ConfigParser.cc CommonPool.h \
 	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
 	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
 	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
@@ -846,9 +853,9 @@
 	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
 	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
 	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreSwapLogData.cc tools.cc tunnel.cc SwapDir.cc url.cc \
-	URLScheme.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
-	wordlist.cc
+	StoreSwapLogData.cc TextException.cc tools.cc tunnel.cc \
+	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
+	whois.cc win32.cc wordlist.cc
 am_tests_testEventLoop_OBJECTS = debug.$(OBJEXT) EventLoop.$(OBJEXT) \
 	globals.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) \
@@ -861,12 +868,13 @@
 	AsyncCall.$(OBJEXT) authenticate.$(OBJEXT) BodyPipe.$(OBJEXT) \
 	cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
-	client_db.$(OBJEXT) client_side.$(OBJEXT) \
-	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
-	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
-	ConfigParser.$(OBJEXT) $(am__objects_9) disk.$(OBJEXT) \
-	$(am__objects_11) event.$(OBJEXT) errorpage.$(OBJEXT) \
-	$(am__objects_13) ETag.$(OBJEXT) external_acl.$(OBJEXT) \
+	ChunkedCodingParser.$(OBJEXT) client_db.$(OBJEXT) \
+	client_side.$(OBJEXT) client_side_reply.$(OBJEXT) \
+	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
+	$(am__objects_7) ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
+	$(am__objects_9) disk.$(OBJEXT) $(am__objects_11) \
+	event.$(OBJEXT) errorpage.$(OBJEXT) $(am__objects_13) \
+	ETag.$(OBJEXT) external_acl.$(OBJEXT) \
 	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
 	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
 	gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_14) \
@@ -896,10 +904,10 @@
 	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
 	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
 	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) SwapDir.$(OBJEXT) \
-	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
-	useragent.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
-	$(am__objects_25) wordlist.$(OBJEXT)
+	TextException.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
+	SwapDir.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) useragent.$(OBJEXT) wccp2.$(OBJEXT) \
+	whois.$(OBJEXT) $(am__objects_25) wordlist.$(OBJEXT)
 nodist_tests_testEventLoop_OBJECTS = repl_modules.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 tests_testEventLoop_OBJECTS = $(am_tests_testEventLoop_OBJECTS) \
@@ -943,28 +951,29 @@
 	ACLChecklist.cc ACLProxyAuth.cc ACLStringData.cc \
 	ACLRegexData.cc ACLUserData.cc AsyncCall.cc authenticate.cc \
 	BodyPipe.cc cache_manager.cc cache_cf.cc CacheDigest.cc \
-	carp.cc cbdata.cc client_db.cc client_side.cc \
-	client_side_reply.cc client_side_request.cc clientStream.cc \
-	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
-	comm_poll.h comm_epoll.cc comm_epoll.h comm_kqueue.cc \
-	comm_kqueue.h ConfigOption.cc ConfigParser.cc CommonPool.h \
-	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
-	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
-	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
-	DelaySpec.cc DelaySpec.h DelayTagged.cc DelayTagged.h \
-	DelayUser.cc DelayUser.h DelayVector.cc DelayVector.h \
-	NullDelayId.cc NullDelayId.h disk.cc dns_internal.cc dns.cc \
-	event.cc errorpage.cc ElementList.h ESI.cc ESI.h ESIAssign.cc \
-	ESIAssign.h ESIAttempt.h ESIContext.cc ESIContext.h \
-	ESICustomParser.cc ESICustomParser.h ESIElement.h ESIExcept.h \
-	ESIExpatParser.cc ESIExpatParser.h ESIExpression.cc \
-	ESIExpression.h ESIInclude.cc ESIInclude.h ESILiteral.h \
-	ESILibxml2Parser.cc ESILibxml2Parser.h ESIParser.cc \
-	ESIParser.h ESISegment.cc ESISegment.h ESISequence.cc \
-	ESISequence.h ESIVar.h ESIVarState.cc ESIVarState.h ETag.cc \
-	external_acl.cc ExternalACLEntry.cc fd.cc fde.cc forward.cc \
-	fqdncache.cc ftp.cc gopher.cc helper.cc htcp.cc htcp.h http.cc \
-	HttpBody.cc HttpHeader.cc HttpHeaderTools.cc HttpHdrCc.cc \
+	carp.cc cbdata.cc ChunkedCodingParser.cc client_db.cc \
+	client_side.cc client_side_reply.cc client_side_request.cc \
+	clientStream.cc comm_select.cc comm_select.h \
+	comm_select_win32.cc comm_poll.cc comm_poll.h comm_epoll.cc \
+	comm_epoll.h comm_kqueue.cc comm_kqueue.h ConfigOption.cc \
+	ConfigParser.cc CommonPool.h CompositePoolNode.h \
+	delay_pools.cc DelayId.cc DelayId.h DelayIdComposite.h \
+	DelayBucket.cc DelayBucket.h DelayConfig.cc DelayConfig.h \
+	DelayPool.cc DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
+	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
+	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
+	disk.cc dns_internal.cc dns.cc event.cc errorpage.cc \
+	ElementList.h ESI.cc ESI.h ESIAssign.cc ESIAssign.h \
+	ESIAttempt.h ESIContext.cc ESIContext.h ESICustomParser.cc \
+	ESICustomParser.h ESIElement.h ESIExcept.h ESIExpatParser.cc \
+	ESIExpatParser.h ESIExpression.cc ESIExpression.h \
+	ESIInclude.cc ESIInclude.h ESILiteral.h ESILibxml2Parser.cc \
+	ESILibxml2Parser.h ESIParser.cc ESIParser.h ESISegment.cc \
+	ESISegment.h ESISequence.cc ESISequence.h ESIVar.h \
+	ESIVarState.cc ESIVarState.h ETag.cc external_acl.cc \
+	ExternalACLEntry.cc fd.cc fde.cc forward.cc fqdncache.cc \
+	ftp.cc gopher.cc helper.cc htcp.cc htcp.h http.cc HttpBody.cc \
+	HttpHeader.cc HttpHeaderTools.cc HttpHdrCc.cc \
 	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
 	HttpHdrScTarget.cc HttpMsg.cc HttpReply.cc HttpStatusLine.cc \
 	icmp.cc icp_v2.cc icp_v3.cc ACLIdent.cc ACLIdent.h ident.cc \
@@ -982,9 +991,9 @@
 	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
 	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
-	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
-	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
-	whois.cc win32.cc wordlist.cc
+	StoreMetaVary.cc StoreSwapLogData.cc TextException.cc tools.cc \
+	tunnel.cc SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc \
+	wccp2.cc whois.cc win32.cc wordlist.cc
 am_tests_testHttpRequest_OBJECTS = debug.$(OBJEXT) globals.$(OBJEXT) \
 	HttpRequest.$(OBJEXT) HttpRequestMethod.$(OBJEXT) \
 	mem.$(OBJEXT) String.$(OBJEXT) tests/testHttpRequest.$(OBJEXT) \
@@ -996,12 +1005,13 @@
 	AsyncCall.$(OBJEXT) authenticate.$(OBJEXT) BodyPipe.$(OBJEXT) \
 	cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
-	client_db.$(OBJEXT) client_side.$(OBJEXT) \
-	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
-	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
-	ConfigParser.$(OBJEXT) $(am__objects_9) disk.$(OBJEXT) \
-	$(am__objects_11) event.$(OBJEXT) errorpage.$(OBJEXT) \
-	$(am__objects_13) ETag.$(OBJEXT) external_acl.$(OBJEXT) \
+	ChunkedCodingParser.$(OBJEXT) client_db.$(OBJEXT) \
+	client_side.$(OBJEXT) client_side_reply.$(OBJEXT) \
+	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
+	$(am__objects_7) ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
+	$(am__objects_9) disk.$(OBJEXT) $(am__objects_11) \
+	event.$(OBJEXT) errorpage.$(OBJEXT) $(am__objects_13) \
+	ETag.$(OBJEXT) external_acl.$(OBJEXT) \
 	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
 	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
 	gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_14) \
@@ -1031,10 +1041,11 @@
 	StoreMetaMD5.$(OBJEXT) StoreMetaSTD.$(OBJEXT) \
 	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
 	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
-	StoreSwapLogData.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
-	SwapDir.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
-	urn.$(OBJEXT) useragent.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) $(am__objects_25) wordlist.$(OBJEXT)
+	StoreSwapLogData.$(OBJEXT) TextException.$(OBJEXT) \
+	tools.$(OBJEXT) tunnel.$(OBJEXT) SwapDir.$(OBJEXT) \
+	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
+	useragent.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
+	$(am__objects_25) wordlist.$(OBJEXT)
 nodist_tests_testHttpRequest_OBJECTS = repl_modules.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 tests_testHttpRequest_OBJECTS = $(am_tests_testHttpRequest_OBJECTS) \
@@ -1140,11 +1151,11 @@
 	ACLProxyAuth.cc ACLStringData.cc ACLRegexData.cc \
 	ACLUserData.cc AsyncCall.cc authenticate.cc BodyPipe.cc \
 	cache_manager.cc cache_cf.cc CacheDigest.cc carp.cc cbdata.cc \
-	client_db.cc client_side.cc client_side_reply.cc \
-	client_side_request.cc clientStream.cc comm_select.cc \
-	comm_select.h comm_select_win32.cc comm_poll.cc comm_poll.h \
-	comm_epoll.cc comm_epoll.h comm_kqueue.cc comm_kqueue.h \
-	ConfigOption.cc ConfigParser.cc CommonPool.h \
+	ChunkedCodingParser.cc client_db.cc client_side.cc \
+	client_side_reply.cc client_side_request.cc clientStream.cc \
+	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
+	comm_poll.h comm_epoll.cc comm_epoll.h comm_kqueue.cc \
+	comm_kqueue.h ConfigOption.cc ConfigParser.cc CommonPool.h \
 	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
 	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
 	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
@@ -1179,8 +1190,9 @@
 	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
 	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
 	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreSwapLogData.cc tools.cc tunnel.cc SwapDir.cc urn.cc \
-	useragent.cc wccp2.cc whois.cc win32.cc wordlist.cc
+	StoreSwapLogData.cc TextException.cc tools.cc tunnel.cc \
+	SwapDir.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
+	wordlist.cc
 am_tests_testURL_OBJECTS = debug.$(OBJEXT) url.$(OBJEXT) \
 	URLScheme.$(OBJEXT) globals.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) \
@@ -1193,12 +1205,13 @@
 	AsyncCall.$(OBJEXT) authenticate.$(OBJEXT) BodyPipe.$(OBJEXT) \
 	cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
-	client_db.$(OBJEXT) client_side.$(OBJEXT) \
-	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
-	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
-	ConfigParser.$(OBJEXT) $(am__objects_9) disk.$(OBJEXT) \
-	$(am__objects_11) event.$(OBJEXT) errorpage.$(OBJEXT) \
-	$(am__objects_13) ETag.$(OBJEXT) external_acl.$(OBJEXT) \
+	ChunkedCodingParser.$(OBJEXT) client_db.$(OBJEXT) \
+	client_side.$(OBJEXT) client_side_reply.$(OBJEXT) \
+	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
+	$(am__objects_7) ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
+	$(am__objects_9) disk.$(OBJEXT) $(am__objects_11) \
+	event.$(OBJEXT) errorpage.$(OBJEXT) $(am__objects_13) \
+	ETag.$(OBJEXT) external_acl.$(OBJEXT) \
 	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
 	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
 	gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_14) \
@@ -1228,9 +1241,10 @@
 	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
 	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
 	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) SwapDir.$(OBJEXT) \
-	urn.$(OBJEXT) useragent.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) $(am__objects_25) wordlist.$(OBJEXT)
+	TextException.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
+	SwapDir.$(OBJEXT) urn.$(OBJEXT) useragent.$(OBJEXT) \
+	wccp2.$(OBJEXT) whois.$(OBJEXT) $(am__objects_25) \
+	wordlist.$(OBJEXT)
 nodist_tests_testURL_OBJECTS = repl_modules.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 tests_testURL_OBJECTS = $(am_tests_testURL_OBJECTS) \
@@ -1285,29 +1299,30 @@
 	ACLProxyAuth.cc ACLStringData.cc ACLRegexData.cc \
 	ACLUserData.cc AsyncCall.cc authenticate.cc BodyPipe.cc \
 	cache_cf.cc cache_manager.cc CacheDigest.cc carp.cc cbdata.cc \
-	client_db.cc client_side.cc client_side_reply.cc \
-	client_side_request.cc clientStream.cc comm_select.cc \
-	comm_select.h comm_select_win32.cc comm_poll.cc comm_poll.h \
-	comm_epoll.cc comm_epoll.h comm_kqueue.cc comm_kqueue.h \
-	ConfigOption.cc ConfigParser.cc debug.cc CommonPool.h \
-	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
-	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
-	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
-	DelaySpec.cc DelaySpec.h DelayTagged.cc DelayTagged.h \
-	DelayUser.cc DelayUser.h DelayVector.cc DelayVector.h \
-	NullDelayId.cc NullDelayId.h disk.cc dns_internal.cc dns.cc \
-	event.cc errorpage.cc ElementList.h ESI.cc ESI.h ESIAssign.cc \
-	ESIAssign.h ESIAttempt.h ESIContext.cc ESIContext.h \
-	ESICustomParser.cc ESICustomParser.h ESIElement.h ESIExcept.h \
-	ESIExpatParser.cc ESIExpatParser.h ESIExpression.cc \
-	ESIExpression.h ESIInclude.cc ESIInclude.h ESILiteral.h \
-	ESILibxml2Parser.cc ESILibxml2Parser.h ESIParser.cc \
-	ESIParser.h ESISegment.cc ESISegment.h ESISequence.cc \
-	ESISequence.h ESIVar.h ESIVarState.cc ESIVarState.h ETag.cc \
-	external_acl.cc ExternalACLEntry.cc fd.cc fde.cc forward.cc \
-	fqdncache.cc ftp.cc globals.cc gopher.cc helper.cc htcp.cc \
-	htcp.h http.cc HttpBody.cc HttpHdrCc.cc HttpHdrContRange.cc \
-	HttpHdrRange.cc HttpHdrSc.cc HttpHdrScTarget.cc HttpHeader.cc \
+	ChunkedCodingParser.cc client_db.cc client_side.cc \
+	client_side_reply.cc client_side_request.cc clientStream.cc \
+	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
+	comm_poll.h comm_epoll.cc comm_epoll.h comm_kqueue.cc \
+	comm_kqueue.h ConfigOption.cc ConfigParser.cc debug.cc \
+	CommonPool.h CompositePoolNode.h delay_pools.cc DelayId.cc \
+	DelayId.h DelayIdComposite.h DelayBucket.cc DelayBucket.h \
+	DelayConfig.cc DelayConfig.h DelayPool.cc DelayPool.h \
+	DelayPools.h DelaySpec.cc DelaySpec.h DelayTagged.cc \
+	DelayTagged.h DelayUser.cc DelayUser.h DelayVector.cc \
+	DelayVector.h NullDelayId.cc NullDelayId.h disk.cc \
+	dns_internal.cc dns.cc event.cc errorpage.cc ElementList.h \
+	ESI.cc ESI.h ESIAssign.cc ESIAssign.h ESIAttempt.h \
+	ESIContext.cc ESIContext.h ESICustomParser.cc \
+	ESICustomParser.h ESIElement.h ESIExcept.h ESIExpatParser.cc \
+	ESIExpatParser.h ESIExpression.cc ESIExpression.h \
+	ESIInclude.cc ESIInclude.h ESILiteral.h ESILibxml2Parser.cc \
+	ESILibxml2Parser.h ESIParser.cc ESIParser.h ESISegment.cc \
+	ESISegment.h ESISequence.cc ESISequence.h ESIVar.h \
+	ESIVarState.cc ESIVarState.h ETag.cc external_acl.cc \
+	ExternalACLEntry.cc fd.cc fde.cc forward.cc fqdncache.cc \
+	ftp.cc globals.cc gopher.cc helper.cc htcp.cc htcp.h http.cc \
+	HttpBody.cc HttpHdrCc.cc HttpHdrContRange.cc HttpHdrRange.cc \
+	HttpHdrSc.cc HttpHdrScTarget.cc HttpHeader.cc \
 	HttpHeaderTools.cc HttpMsg.cc HttpReply.cc HttpRequest.cc \
 	HttpRequestMethod.cc HttpStatusLine.cc icmp.cc icp_v2.cc \
 	icp_v3.cc ACLIdent.cc ACLIdent.h ident.cc int.cc internal.cc \
@@ -1325,9 +1340,9 @@
 	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
 	StoreMetaVary.cc StoreSwapLogData.cc String.cc SwapDir.cc \
-	time.cc tools.cc tunnel.cc url.cc URLScheme.cc urn.cc \
-	useragent.cc wccp2.cc whois.cc win32.cc wordlist.cc Packer.cc \
-	MemBuf.cc
+	TextException.cc time.cc tools.cc tunnel.cc url.cc \
+	URLScheme.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
+	wordlist.cc Packer.cc MemBuf.cc
 am_tests_test_http_range_OBJECTS = tests/test_http_range.$(OBJEXT) \
 	access_log.$(OBJEXT) acl.$(OBJEXT) acl_noncore.$(OBJEXT) \
 	ACLChecklist.$(OBJEXT) ACLProxyAuth.$(OBJEXT) \
@@ -1335,7 +1350,8 @@
 	ACLUserData.$(OBJEXT) AsyncCall.$(OBJEXT) \
 	authenticate.$(OBJEXT) BodyPipe.$(OBJEXT) cache_cf.$(OBJEXT) \
 	cache_manager.$(OBJEXT) CacheDigest.$(OBJEXT) carp.$(OBJEXT) \
-	cbdata.$(OBJEXT) client_db.$(OBJEXT) client_side.$(OBJEXT) \
+	cbdata.$(OBJEXT) ChunkedCodingParser.$(OBJEXT) \
+	client_db.$(OBJEXT) client_side.$(OBJEXT) \
 	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
 	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
 	ConfigParser.$(OBJEXT) debug.$(OBJEXT) $(am__objects_9) \
@@ -1373,10 +1389,11 @@
 	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
 	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
 	StoreSwapLogData.$(OBJEXT) String.$(OBJEXT) SwapDir.$(OBJEXT) \
-	time.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) url.$(OBJEXT) \
-	URLScheme.$(OBJEXT) urn.$(OBJEXT) useragent.$(OBJEXT) \
-	wccp2.$(OBJEXT) whois.$(OBJEXT) $(am__objects_25) \
-	wordlist.$(OBJEXT) Packer.$(OBJEXT) MemBuf.$(OBJEXT)
+	TextException.$(OBJEXT) time.$(OBJEXT) tools.$(OBJEXT) \
+	tunnel.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) useragent.$(OBJEXT) wccp2.$(OBJEXT) \
+	whois.$(OBJEXT) $(am__objects_25) wordlist.$(OBJEXT) \
+	Packer.$(OBJEXT) MemBuf.$(OBJEXT)
 nodist_tests_test_http_range_OBJECTS = repl_modules.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 tests_test_http_range_OBJECTS = $(am_tests_test_http_range_OBJECTS) \
@@ -1393,7 +1410,8 @@
 	StoreSwapLogData.cc StoreSwapLogData.h access_log.cc acl.cc \
 	acl_noncore.cc ACLChecklist.cc ACLProxyAuth.cc ACLUserData.cc \
 	ACLRegexData.cc ACLStringData.cc authenticate.cc cache_cf.cc \
-	cache_manager.cc CacheDigest.cc carp.cc cbdata.cc client_db.cc \
+	cache_manager.cc CacheDigest.cc carp.cc cbdata.cc \
+	ChunkedCodingParser.cc ChunkedCodingParser.h client_db.cc \
 	client_side.cc client_side_reply.cc client_side_request.cc \
 	client_side_request.h clientStream.cc clientStream.h CommIO.h \
 	comm_select.cc comm_select.h comm_select_win32.cc comm_poll.cc \
@@ -1435,8 +1453,9 @@
 	StoreIOState.cc store_client.cc StoreClient.h store_digest.cc \
 	store_dir.cc store_log.cc store_rebuild.cc store_swapin.cc \
 	store_swapmeta.cc store_swapout.cc structs.h SwapDir.cc \
-	tools.cc typedefs.h unlinkd.cc URLScheme.cc urn.cc \
-	useragent.cc wccp.cc wccp2.cc whois.cc wordlist.cc win32.cc
+	TextException.cc TextException.h tools.cc typedefs.h \
+	unlinkd.cc URLScheme.cc urn.cc useragent.cc wccp.cc wccp2.cc \
+	whois.cc wordlist.cc win32.cc
 am_ufsdump_OBJECTS = debug.$(OBJEXT) int.$(OBJEXT) mem.$(OBJEXT) \
 	store_key_md5.$(OBJEXT) StoreMeta.$(OBJEXT) \
 	StoreMetaMD5.$(OBJEXT) StoreMetaSTD.$(OBJEXT) \
@@ -1452,17 +1471,18 @@
 	ACLStringData.$(OBJEXT) authenticate.$(OBJEXT) \
 	cache_cf.$(OBJEXT) cache_manager.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
-	client_db.$(OBJEXT) client_side.$(OBJEXT) \
-	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
-	clientStream.$(OBJEXT) $(am__objects_7) ConfigOption.$(OBJEXT) \
-	$(am__objects_9) disk.$(OBJEXT) $(am__objects_11) \
-	errorpage.$(OBJEXT) $(am__objects_13) ETag.$(OBJEXT) \
-	event.$(OBJEXT) external_acl.$(OBJEXT) \
-	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
-	filemap.$(OBJEXT) forward.$(OBJEXT) fqdncache.$(OBJEXT) \
-	ftp.$(OBJEXT) gopher.$(OBJEXT) helper.$(OBJEXT) \
-	$(am__objects_14) http.$(OBJEXT) HttpStatusLine.$(OBJEXT) \
-	HttpHdrCc.$(OBJEXT) HttpHdrRange.$(OBJEXT) HttpHdrSc.$(OBJEXT) \
+	ChunkedCodingParser.$(OBJEXT) client_db.$(OBJEXT) \
+	client_side.$(OBJEXT) client_side_reply.$(OBJEXT) \
+	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
+	$(am__objects_7) ConfigOption.$(OBJEXT) $(am__objects_9) \
+	disk.$(OBJEXT) $(am__objects_11) errorpage.$(OBJEXT) \
+	$(am__objects_13) ETag.$(OBJEXT) event.$(OBJEXT) \
+	external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) \
+	fde.$(OBJEXT) filemap.$(OBJEXT) forward.$(OBJEXT) \
+	fqdncache.$(OBJEXT) ftp.$(OBJEXT) gopher.$(OBJEXT) \
+	helper.$(OBJEXT) $(am__objects_14) http.$(OBJEXT) \
+	HttpStatusLine.$(OBJEXT) HttpHdrCc.$(OBJEXT) \
+	HttpHdrRange.$(OBJEXT) HttpHdrSc.$(OBJEXT) \
 	HttpHdrScTarget.$(OBJEXT) HttpHdrContRange.$(OBJEXT) \
 	HttpHeader.$(OBJEXT) HttpHeaderTools.$(OBJEXT) \
 	HttpBody.$(OBJEXT) HttpMsg.$(OBJEXT) HttpReply.$(OBJEXT) \
@@ -1485,10 +1505,10 @@
 	store_digest.$(OBJEXT) store_dir.$(OBJEXT) store_log.$(OBJEXT) \
 	store_rebuild.$(OBJEXT) store_swapin.$(OBJEXT) \
 	store_swapmeta.$(OBJEXT) store_swapout.$(OBJEXT) \
-	SwapDir.$(OBJEXT) tools.$(OBJEXT) $(am__objects_24) \
-	URLScheme.$(OBJEXT) urn.$(OBJEXT) useragent.$(OBJEXT) \
-	wccp.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
-	wordlist.$(OBJEXT) $(am__objects_25)
+	SwapDir.$(OBJEXT) TextException.$(OBJEXT) tools.$(OBJEXT) \
+	$(am__objects_24) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
+	useragent.$(OBJEXT) wccp.$(OBJEXT) wccp2.$(OBJEXT) \
+	whois.$(OBJEXT) wordlist.$(OBJEXT) $(am__objects_25)
 nodist_ufsdump_OBJECTS = repl_modules.$(OBJEXT) globals.$(OBJEXT) \
 	string_arrays.$(OBJEXT)
 ufsdump_OBJECTS = $(am_ufsdump_OBJECTS) $(nodist_ufsdump_OBJECTS)
@@ -2083,6 +2103,8 @@
 	carp.cc \
 	cbdata.cc \
 	cbdata.h \
+	ChunkedCodingParser.cc \
+	ChunkedCodingParser.h \
 	client_db.cc \
 	client_side.cc \
 	client_side.h \
@@ -2262,6 +2284,8 @@
 	structs.h \
 	SwapDir.cc \
 	SwapDir.h \
+	TextException.cc \
+	TextException.h \
 	time.cc \
 	tools.cc \
 	tunnel.cc \
@@ -2335,8 +2359,6 @@
 ICAP_libicap_a_SOURCES = \
 	ICAP/AsyncJob.cc \
 	ICAP/AsyncJob.h \
- 	ICAP/ChunkedCodingParser.cc \
- 	ICAP/ChunkedCodingParser.h \
 	ICAP/ICAPClient.cc \
 	ICAP/ICAPClient.h \
 	ICAP/ICAPInitiator.cc \
@@ -2359,9 +2381,7 @@
 	ICAP/ICAPServiceRep.cc \
 	ICAP/ICAPServiceRep.h \
 	ICAP/ICAPXaction.cc \
-	ICAP/ICAPXaction.h \
-	ICAP/TextException.cc \
-	ICAP/TextException.h
+	ICAP/ICAPXaction.h
 
 unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc
 pinger_SOURCES = \
@@ -2411,6 +2431,8 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
+	ChunkedCodingParser.h \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -2515,6 +2537,8 @@
 	store_swapout.cc \
 	structs.h \
 	SwapDir.cc \
+	TextException.cc \
+	TextException.h \
 	tools.cc \
 	typedefs.h \
 	$(UNLINKDSOURCE) \
@@ -2809,6 +2833,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -2901,6 +2926,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -2981,6 +3007,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -3072,6 +3099,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -3137,6 +3165,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -3228,6 +3257,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -3314,6 +3344,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -3411,6 +3442,7 @@
 	StoreSwapLogData.cc \
 	String.cc \
 	SwapDir.cc \
+	TextException.cc \
 	time.cc \
 	tools.cc \
 	tunnel.cc \
@@ -3476,6 +3508,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -3568,6 +3601,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -3826,6 +3860,7 @@
 	CacheDigest.cc \
 	carp.cc \
 	cbdata.cc \
+	ChunkedCodingParser.cc \
 	client_db.cc \
 	client_side.cc \
 	client_side_reply.cc \
@@ -3917,6 +3952,7 @@
 	StoreMetaURL.cc \
 	StoreMetaVary.cc \
 	StoreSwapLogData.cc \
+	TextException.cc \
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
@@ -3995,8 +4031,6 @@
 	@: > ICAP/$(DEPDIR)/$(am__dirstamp)
 ICAP/AsyncJob.$(OBJEXT): ICAP/$(am__dirstamp) \
 	ICAP/$(DEPDIR)/$(am__dirstamp)
-ICAP/ChunkedCodingParser.$(OBJEXT): ICAP/$(am__dirstamp) \
-	ICAP/$(DEPDIR)/$(am__dirstamp)
 ICAP/ICAPClient.$(OBJEXT): ICAP/$(am__dirstamp) \
 	ICAP/$(DEPDIR)/$(am__dirstamp)
 ICAP/ICAPInitiator.$(OBJEXT): ICAP/$(am__dirstamp) \
@@ -4019,8 +4053,6 @@
 	ICAP/$(DEPDIR)/$(am__dirstamp)
 ICAP/ICAPXaction.$(OBJEXT): ICAP/$(am__dirstamp) \
 	ICAP/$(DEPDIR)/$(am__dirstamp)
-ICAP/TextException.$(OBJEXT): ICAP/$(am__dirstamp) \
-	ICAP/$(DEPDIR)/$(am__dirstamp)
 ICAP/libicap.a: $(ICAP_libicap_a_OBJECTS) $(ICAP_libicap_a_DEPENDENCIES) ICAP/$(am__dirstamp)
 	-rm -f ICAP/libicap.a
 	$(ICAP_libicap_a_AR) ICAP/libicap.a $(ICAP_libicap_a_OBJECTS) $(ICAP_libicap_a_LIBADD)
@@ -4548,7 +4580,6 @@
 	-rm -f DiskIO/ReadRequest.$(OBJEXT)
 	-rm -f DiskIO/WriteRequest.$(OBJEXT)
 	-rm -f ICAP/AsyncJob.$(OBJEXT)
-	-rm -f ICAP/ChunkedCodingParser.$(OBJEXT)
 	-rm -f ICAP/ICAPClient.$(OBJEXT)
 	-rm -f ICAP/ICAPConfig.$(OBJEXT)
 	-rm -f ICAP/ICAPElements.$(OBJEXT)
@@ -4560,7 +4591,6 @@
 	-rm -f ICAP/ICAPOptions.$(OBJEXT)
 	-rm -f ICAP/ICAPServiceRep.$(OBJEXT)
 	-rm -f ICAP/ICAPXaction.$(OBJEXT)
-	-rm -f ICAP/TextException.$(OBJEXT)
 	-rm -f auth/basic/basicScheme.$(OBJEXT)
 	-rm -f auth/digest/digestScheme.$(OBJEXT)
 	-rm -f auth/negotiate/negotiateScheme.$(OBJEXT)
@@ -4689,6 +4719,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthUserRequest.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BodyPipe.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CacheDigest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedCodingParser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CompletionDispatcher.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigOption.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigParser.Po@am__quote@
@@ -4752,6 +4783,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StoreSwapLogData.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/String.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SwapDir.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TextException.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URLScheme.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WinSvc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/access_log.Po@am__quote@
@@ -4877,7 +4909,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@DiskIO/DiskThreads/$(DEPDIR)/aiops_win32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@DiskIO/DiskThreads/$(DEPDIR)/async_io.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/AsyncJob.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ChunkedCodingParser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ICAPClient.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ICAPConfig.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ICAPElements.Po@am__quote@
@@ -4889,7 +4920,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ICAPOptions.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ICAPServiceRep.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/ICAPXaction.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@ICAP/$(DEPDIR)/TextException.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@auth/basic/$(DEPDIR)/basicScheme.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@auth/digest/$(DEPDIR)/digestScheme.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@auth/negotiate/$(DEPDIR)/negotiateScheme.Po@am__quote@
diff -u -r -N squid-3.0.STABLE15/src/structs.h squid-3.0.STABLE16-RC1/src/structs.h
--- squid-3.0.STABLE15/src/structs.h	2009-05-06 23:11:42.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/structs.h	2009-05-16 00:47:58.000000000 +1200
@@ -255,6 +255,7 @@
     Timeout;
     size_t maxRequestHeaderSize;
     int64_t maxRequestBodySize;
+    int64_t maxChunkedRequestBodySize;
     size_t maxReplyHeaderSize;
     acl_size_t *ReplyBodySize;
 
@@ -924,6 +925,8 @@
 
 unsigned int consume_body_data:
     1;
+
+unsigned int chunked:1;
 };
 
 struct _ipcache_addrs
diff -u -r -N squid-3.0.STABLE15/src/TextException.cc squid-3.0.STABLE16-RC1/src/TextException.cc
--- squid-3.0.STABLE15/src/TextException.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/TextException.cc	2009-05-16 00:47:57.000000000 +1200
@@ -0,0 +1,27 @@
+#include "squid.h"
+#include "TextException.h"
+
+TextException::TextException(const char *aMsg, const char *aFileName, int aLineNo):
+        message(xstrdup(aMsg)), theFileName(aFileName), theLineNo(aLineNo)
+{}
+
+TextException::~TextException()
+{
+    xfree(message);
+}
+
+void Throw(const char *message, const char *fileName, int lineNo)
+{
+
+    // or should we let the exception recepient print the exception instead?
+
+    if (fileName) {
+        debugs(0, 3, fileName << ':' << lineNo << ": exception" <<
+               (message ? ": " : ".") << (message ? message : ""));
+    } else {
+        debugs(0, 3, "exception" <<
+               (message ? ": " : ".") << (message ? message : ""));
+    }
+
+    throw TextException(message, fileName, lineNo);
+}
diff -u -r -N squid-3.0.STABLE15/src/TextException.h squid-3.0.STABLE16-RC1/src/TextException.h
--- squid-3.0.STABLE15/src/TextException.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE16-RC1/src/TextException.h	2009-05-16 00:47:57.000000000 +1200
@@ -0,0 +1,46 @@
+#ifndef SQUID__TEXTEXCEPTION_H
+#define SQUID__TEXTEXCEPTION_H
+
+// Origin: xstd/TextException
+
+
+// simple exception to report custom errors
+// we may want to change the interface to be able to report system errors
+
+class TextException
+{
+
+public:
+    TextException(const char *aMessage, const char *aFileName = 0, int aLineNo = -1);
+    ~TextException();
+
+    // ostream &print(ostream &os) const;
+
+public:
+    char *message; // read-only
+
+protected:
+    // optional location information
+    const char *theFileName;
+    int theLineNo;
+};
+
+//inline
+//ostream &operator <<(ostream &os, const TextException &exx) {
+//    return exx.print(os);
+//}
+
+#if !defined(TexcHere)
+#    define TexcHere(msg) TextException((msg), __FILE__, __LINE__)
+#endif
+
+extern void Throw(const char *message, const char *fileName, int lineNo);
+
+// Must(condition) is like assert(condition) but throws an exception instead
+#if !defined(Must)
+#   define Must(cond) ((cond) ? \
+        (void)0 : \
+        (void)Throw(#cond, __FILE__, __LINE__))
+#endif
+
+#endif /* SQUID__TEXTEXCEPTION_H */
