diff -u -r -N squid-3.0.STABLE24/ChangeLog squid-3.0.STABLE25/ChangeLog
--- squid-3.0.STABLE24/ChangeLog	2010-02-13 02:52:58.000000000 +1300
+++ squid-3.0.STABLE25/ChangeLog	2010-03-14 18:45:39.000000000 +1300
@@ -1,3 +1,11 @@
+Changes to squid-3.0.STABLE25 (14 Mar 2010):
+
+	- Bug 2845: Rework the http digest auth parser
+	- Bug 2787: unknown/unexpected status code messages
+	- Bug 2507: squid_ldap_group: Strip Domain name separated by +
+	- Bug 2367: stale=true on digest requests with unknown nonce
+	- ... and several other minor corrections
+
 Changes to squid-3.0.STABLE24 (13 Feb 2010):
 
 	- Bug 2858: Segment violation in HTCP
diff -u -r -N squid-3.0.STABLE24/configure squid-3.0.STABLE25/configure
--- squid-3.0.STABLE24/configure	2010-02-13 02:53:20.000000000 +1300
+++ squid-3.0.STABLE25/configure	2010-03-14 18:45:43.000000000 +1300
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.0.STABLE24.
+# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.0.STABLE25.
 #
 # 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.STABLE24'
-PACKAGE_STRING='Squid Web Proxy 3.0.STABLE24'
+PACKAGE_VERSION='3.0.STABLE25'
+PACKAGE_STRING='Squid Web Proxy 3.0.STABLE25'
 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.STABLE24 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.0.STABLE25 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.STABLE24:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE25:";;
    esac
   cat <<\_ACEOF
 
@@ -2047,7 +2047,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.0.STABLE24
+Squid Web Proxy configure 3.0.STABLE25
 generated by GNU Autoconf 2.62
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -2061,7 +2061,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.STABLE24, which was
+It was created by Squid Web Proxy $as_me 3.0.STABLE25, which was
 generated by GNU Autoconf 2.62.  Invocation command line was
 
   $ $0 $@
@@ -2779,7 +2779,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.0.STABLE24'
+ VERSION='3.0.STABLE25'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -48207,7 +48207,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.STABLE24, which was
+This file was extended by Squid Web Proxy $as_me 3.0.STABLE25, which was
 generated by GNU Autoconf 2.62.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -48260,7 +48260,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-Squid Web Proxy config.status 3.0.STABLE24
+Squid Web Proxy config.status 3.0.STABLE25
 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.STABLE24/configure.in squid-3.0.STABLE25/configure.in
--- squid-3.0.STABLE24/configure.in	2010-02-13 02:53:20.000000000 +1300
+++ squid-3.0.STABLE25/configure.in	2010-03-14 18:45:43.000000000 +1300
@@ -1,7 +1,7 @@
 dnl  Configuration input file for Squid
 dnl
 dnl
-AC_INIT(Squid Web Proxy, 3.0.STABLE24, http://www.squid-cache.org/bugs/, squid)
+AC_INIT(Squid Web Proxy, 3.0.STABLE25, 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.STABLE24/helpers/external_acl/ldap_group/squid_ldap_group.c squid-3.0.STABLE25/helpers/external_acl/ldap_group/squid_ldap_group.c
--- squid-3.0.STABLE24/helpers/external_acl/ldap_group/squid_ldap_group.c	2010-02-13 02:53:08.000000000 +1300
+++ squid-3.0.STABLE25/helpers/external_acl/ldap_group/squid_ldap_group.c	2010-03-14 18:45:40.000000000 +1300
@@ -475,6 +475,8 @@
 	    char *u = strrchr(user, '\\');
 	    if (!u)
 		u = strrchr(user, '/');
+            if (!u)
+                u = strrchr(user, '+');
 	    if (u && u[1])
 		user = u + 1;
 	}
diff -u -r -N squid-3.0.STABLE24/include/version.h squid-3.0.STABLE25/include/version.h
--- squid-3.0.STABLE24/include/version.h	2010-02-13 02:53:20.000000000 +1300
+++ squid-3.0.STABLE25/include/version.h	2010-03-14 18:45:43.000000000 +1300
@@ -9,5 +9,5 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1265982776
+#define SQUID_RELEASE_TIME 1268545528
 #endif
diff -u -r -N squid-3.0.STABLE24/src/auth/digest/auth_digest.cc squid-3.0.STABLE25/src/auth/digest/auth_digest.cc
--- squid-3.0.STABLE24/src/auth/digest/auth_digest.cc	2010-02-13 02:53:16.000000000 +1300
+++ squid-3.0.STABLE25/src/auth/digest/auth_digest.cc	2010-03-14 18:45:43.000000000 +1300
@@ -67,6 +67,33 @@
 
 CBDATA_TYPE(DigestAuthenticateStateData);
 
+enum http_digest_attr_type {
+    DIGEST_USERNAME,
+    DIGEST_REALM,
+    DIGEST_QOP,
+    DIGEST_ALGORITHM,
+    DIGEST_URI,
+    DIGEST_NONCE,
+    DIGEST_NC,
+    DIGEST_CNONCE,
+    DIGEST_RESPONSE,
+    DIGEST_ENUM_END
+};
+
+static const HttpHeaderFieldAttrs DigestAttrs[DIGEST_ENUM_END] = {
+    {"username",  (http_hdr_type)DIGEST_USERNAME},
+    {"realm", (http_hdr_type)DIGEST_REALM},
+    {"qop", (http_hdr_type)DIGEST_QOP},
+    {"algorithm", (http_hdr_type)DIGEST_ALGORITHM},
+    {"uri", (http_hdr_type)DIGEST_URI},
+    {"nonce", (http_hdr_type)DIGEST_NONCE},
+    {"nc", (http_hdr_type)DIGEST_NC},
+    {"cnonce", (http_hdr_type)DIGEST_CNONCE},
+    {"response", (http_hdr_type)DIGEST_RESPONSE},
+};
+
+static HttpHeaderFieldInfo *DigestFieldsInfo = NULL;
+
 /*
  *
  * Nonce Functions
@@ -507,6 +534,11 @@
     if (digestauthenticators)
         helperShutdown(digestauthenticators);
 
+    if (DigestFieldsInfo) {
+	httpHeaderDestroyFieldsInfo(DigestFieldsInfo, DIGEST_ENUM_END);
+	DigestFieldsInfo = NULL;
+    }
+
     authdigest_initialised = 0;
 
     if (!shutting_down) {
@@ -642,6 +674,7 @@
 
             if (strcasecmp(digest_request->response, Response)) {
                 credentials(Failed);
+                digest_request->flags.invalid_password = 1;
                 digest_request->setDenyMessage("Incorrect password");
                 return;
             } else {
@@ -871,6 +904,7 @@
 AuthDigestConfig::init(AuthConfig * scheme)
 {
     if (authenticate) {
+        DigestFieldsInfo = httpHeaderBuildFieldsInfo(DigestAttrs, DIGEST_ENUM_END);
         authenticateDigestNonceSetup();
         authdigest_initialised = 1;
 
@@ -1093,124 +1127,84 @@
     String temp(proxy_auth);
 
     while (strListGetItem(&temp, ',', &item, &ilen, &pos)) {
-        if ((p = strchr(item, '=')) && (p - item < ilen))
-            ilen = p++ - item;
-
-        if (!strncmp(item, "username", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
+        String value;
+        size_t nlen;
+        /* isolate directive name */
+        if ((p = (const char *)memchr(item, '=', ilen)) && (p - item < ilen)) {
+            nlen = p++ - item;
+            if (!httpHeaderParseQuotedString(p, &value))
+                value.limitInit(p, ilen - (p - item));
+        } else
+            nlen = ilen;
+
+        if (!value.buf()) {
+            debugs(29, 9, "authDigestDecodeAuth: Failed to parse attribute '" << item << "' in '" << temp << "'");
+            continue;
+        }
 
-            /* quote mark */
-            p++;
+        /* find type */
+        http_digest_attr_type type = (http_digest_attr_type)httpHeaderIdByName(item, nlen, DigestFieldsInfo, DIGEST_ENUM_END);
 
+        switch (type) {
+        case DIGEST_USERNAME:
             safe_free(username);
-            username = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            username = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found Username '" << username << "'");
-        } else if (!strncmp(item, "realm", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+            break;
 
+        case DIGEST_REALM:
             safe_free(digest_request->realm);
-            digest_request->realm = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->realm = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found realm '" << digest_request->realm << "'");
-        } else if (!strncmp(item, "qop", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            if (*p == '\"')
-                /* quote mark */
-                p++;
+            break;
 
+        case DIGEST_QOP:
             safe_free(digest_request->qop);
-            digest_request->qop = xstrndup(p, strcspn(p, "\" \t\r\n()<>@,;:\\/[]?={}") + 1);
-
+            digest_request->qop = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found qop '" << digest_request->qop << "'");
-        } else if (!strncmp(item, "algorithm", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            if (*p == '\"')
-                /* quote mark */
-                p++;
+            break;
 
+        case DIGEST_ALGORITHM:
             safe_free(digest_request->algorithm);
-            digest_request->algorithm = xstrndup(p, strcspn(p, "\" \t\r\n()<>@,;:\\/[]?={}") + 1);
-
+            digest_request->algorithm = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found algorithm '" << digest_request->algorithm << "'");
-        } else if (!strncmp(item, "uri", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+            break;
 
+        case DIGEST_URI:
             safe_free(digest_request->uri);
-            digest_request->uri = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->uri = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found uri '" << digest_request->uri << "'");
-        } else if (!strncmp(item, "nonce", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+            break;
 
+        case DIGEST_NONCE:
             safe_free(digest_request->nonceb64);
-            digest_request->nonceb64 = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->nonceb64 = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found nonce '" << digest_request->nonceb64 << "'");
-        } else if (!strncmp(item, "nc", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            xstrncpy(digest_request->nc, p, 9);
+            break;
 
+        case DIGEST_NC:
+            if (value.size() != 8) {
+                debugs(29, 9, "authDigestDecodeAuth: Invalid nc '" << value << "' in '" << temp << "'");
+            }
+            xstrncpy(digest_request->nc, value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found noncecount '" << digest_request->nc << "'");
-        } else if (!strncmp(item, "cnonce", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+            break;
 
+        case DIGEST_CNONCE:
             safe_free(digest_request->cnonce);
-            digest_request->cnonce = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->cnonce = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found cnonce '" << digest_request->cnonce << "'");
-        } else if (!strncmp(item, "response", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+            break;
 
+        case DIGEST_RESPONSE:
             safe_free(digest_request->response);
-            digest_request->response = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->response = xstrndup(value.buf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found response '" << digest_request->response << "'");
+            break;
+
+        default:
+            debugs(29, 3, "authDigestDecodeAuth: Unknown attribute '" << item << "' in '" << temp << "'");
+            break;
         }
     }
 
@@ -1228,69 +1222,103 @@
      * correct values - 400/401/407
      */
 
-    /* first the NONCE count */
+    /* 2069 requirements */
 
-    if (digest_request->cnonce && strlen(digest_request->nc) != 8) {
-        debugs(29, 4, "authenticateDigestDecode: nonce count length invalid");
+    /* do we have a username ? */
+    if (!username || username[0] == '\0') {
+        debugs(29, 2, "authenticateDigestDecode: Empty or not present username");
         return authDigestLogUsername(username, digest_request);
     }
 
-    /* now the nonce */
-    nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);
-
-    if (!nonce) {
-        /* we couldn't find a matching nonce! */
-        debugs(29, 4, "authenticateDigestDecode: Unexpected or invalid nonce received");
+    /* Sanity check of the username.
+     * " can not be allowed in usernames until * the digest helper protocol
+     * have been redone
+     */
+    if (strchr(username, '"')) {
+        debugs(29, 2, "authenticateDigestDecode: Unacceptable username '" << username << "'");
         return authDigestLogUsername(username, digest_request);
     }
 
-    digest_request->nonce = nonce;
-    authDigestNonceLink(nonce);
-
-    /* check the qop is what we expected. Note that for compatability with
-     * RFC 2069 we should support a missing qop. Tough. */
+    /* do we have a realm ? */
+    if (!digest_request->realm || digest_request->realm[0] == '\0') {
+        debugs(29, 2, "authenticateDigestDecode: Empty or not present realm");
+        return authDigestLogUsername(username, digest_request);
+    }
 
-    if (digest_request->qop && strcmp(digest_request->qop, QOP_AUTH) != 0) {
-        /* we received a qop option we didn't send */
-        debugs(29, 4, "authenticateDigestDecode: Invalid qop option received");
+    /* and a nonce? */
+    if (!digest_request->nonceb64 || digest_request->nonceb64[0] == '\0') {
+        debugs(29, 2, "authenticateDigestDecode: Empty or not present nonce");
         return authDigestLogUsername(username, digest_request);
     }
 
     /* we can't check the URI just yet. We'll check it in the
-     * authenticate phase */
+     * authenticate phase, but needs to be given */
+    if (!digest_request->uri || digest_request->uri[0] == '\0') {
+        debugs(29, 2, "authenticateDigestDecode: Missing URI field");
+        return authDigestLogUsername(username, digest_request);
+    }
 
     /* is the response the correct length? */
-
     if (!digest_request->response || strlen(digest_request->response) != 32) {
-        debugs(29, 4, "authenticateDigestDecode: Response length invalid");
+        debugs(29, 2, "authenticateDigestDecode: Response length invalid");
         return authDigestLogUsername(username, digest_request);
     }
 
-    /* do we have a username ? */
-    if (!username || username[0] == '\0') {
-        debugs(29, 4, "authenticateDigestDecode: Empty or not present username");
+    /* check the algorithm is present and supported */
+    if (!digest_request->algorithm)
+        digest_request->algorithm = xstrndup("MD5", 4);
+    else if (strcmp(digest_request->algorithm, "MD5")
+             && strcmp(digest_request->algorithm, "MD5-sess")) {
+        debugs(29, 2, "authenticateDigestDecode: invalid algorithm specified!");
         return authDigestLogUsername(username, digest_request);
     }
 
-    /* check that we're not being hacked / the username hasn't changed */
-    if (nonce->user && strcmp(username, nonce->user->username())) {
-        debugs(29, 4, "authenticateDigestDecode: Username for the nonce does not equal the username for the request");
-        return authDigestLogUsername(username, digest_request);
+    /* 2617 requirements, indicated by qop */
+    if (digest_request->qop) {
+
+        /* check the qop is what we expected. */
+        if (strcmp(digest_request->qop, QOP_AUTH) != 0) {
+            /* we received a qop option we didn't send */
+            debugs(29, 2, "authenticateDigestDecode: Invalid qop option received");
+            return authDigestLogUsername(username, digest_request);
+        }
+
+        /* check cnonce */
+        if (!digest_request->cnonce || digest_request->cnonce[0] == '\0') {
+            debugs(29, 2, "authenticateDigestDecode: Missing cnonce field");
+            return authDigestLogUsername(username, digest_request);
+        }
+
+        /* check nc */
+        if (strlen(digest_request->nc) != 8 || strspn(digest_request->nc, "0123456789abcdefABCDEF") != 8) {
+            debugs(29, 2, "authenticateDigestDecode: invalid nonce count");
+            return authDigestLogUsername(username, digest_request);
+        }
+    } else {
+        /* cnonce and nc both require qop */
+        if (digest_request->cnonce || digest_request->nc) {
+            debugs(29, 2, "authenticateDigestDecode: missing qop!");
+            return authDigestLogUsername(username, digest_request);
+        }
     }
 
-    /* if we got a qop, did we get a cnonce or did we get a cnonce wihtout a qop? */
-    if ((digest_request->qop && !digest_request->cnonce)
-            || (!digest_request->qop && digest_request->cnonce)) {
-        debugs(29, 4, "authenticateDigestDecode: qop without cnonce, or vice versa!");
+    /** below nonce state dependent **/
+
+    /* now the nonce */
+    nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);
+    if (!nonce) {
+        /* we couldn't find a matching nonce! */
+        debugs(29, 2, "authenticateDigestDecode: Unexpected or invalid nonce received");
+        digest_request->credentials(AuthDigestUserRequest::Failed);
         return authDigestLogUsername(username, digest_request);
     }
 
-    /* check the algorithm is present and supported */
-    if (!digest_request->algorithm)
-        digest_request->algorithm = xstrndup("MD5", 4);
-    else if (strcmp(digest_request->algorithm, "MD5")
-             && strcmp(digest_request->algorithm, "MD5-sess")) {
-        debugs(29, 4, "authenticateDigestDecode: invalid algorithm specified!");
+    digest_request->nonce = nonce;
+    authDigestNonceLink(nonce);
+
+    /* check that we're not being hacked / the username hasn't changed */
+    if (nonce->user && strcmp(username, nonce->user->username())) {
+        debugs(29, 2, "authenticateDigestDecode: Username for the nonce does not equal the username for the request");
         return authDigestLogUsername(username, digest_request);
     }
 
diff -u -r -N squid-3.0.STABLE24/src/cbdata.h squid-3.0.STABLE25/src/cbdata.h
--- squid-3.0.STABLE24/src/cbdata.h	2010-02-13 02:53:17.000000000 +1300
+++ squid-3.0.STABLE25/src/cbdata.h	2010-03-14 18:45:39.000000000 +1300
@@ -83,8 +83,7 @@
 		} \
   		void operator delete (void *address) { \
 		  if (address) cbdataInternalFreeDbg(address,__FILE__,__LINE__); \
-		} \
-#else
+		}
 #else /* CBDATA_DEBUG */
 #define cbdataAlloc(type) ((type *)cbdataInternalAlloc(CBDATA_##type))
 #define cbdataFree(var)		do {if (var) {cbdataInternalFree(var); var = NULL;}} while(0)
diff -u -r -N squid-3.0.STABLE24/src/cf.data.pre squid-3.0.STABLE25/src/cf.data.pre
--- squid-3.0.STABLE24/src/cf.data.pre	2010-02-13 02:53:17.000000000 +1300
+++ squid-3.0.STABLE25/src/cf.data.pre	2010-03-14 18:45:43.000000000 +1300
@@ -1595,7 +1595,7 @@
 
 	The syntax is identical to 'http_access' and the other lists of
 	ACL elements.  See the comments for 'http_access' below, or
-	the Squid FAQ (http://www.squid-cache.org/FAQ/FAQ-10.html).
+	the Squid FAQ (http://wiki.squid-cache.org/SquidFaq/SquidAcl).
 DOC_END
 
 NAME: neighbor_type_domain
diff -u -r -N squid-3.0.STABLE24/src/http.cc squid-3.0.STABLE25/src/http.cc
--- squid-3.0.STABLE24/src/http.cc	2010-02-13 02:53:18.000000000 +1300
+++ squid-3.0.STABLE25/src/http.cc	2010-03-14 18:45:41.000000000 +1300
@@ -569,8 +569,9 @@
 
         return 0;
 
-    default:			/* Unknown status code */
-        debugs (11, DBG_IMPORTANT, "WARNING: Unexpected http status code " << rep->sline.status);
+    default:
+        /* RFC 2616 section 6.1.1: an unrecognized response MUST NOT be cached. */
+        debugs (11, 3, HERE << "Unknown HTTP status code " << rep->sline.status << ". Not cacheable.");
 
         return 0;
 
@@ -747,6 +748,19 @@
 	 readBuf->consume(header_bytes_read);
     }
 
+    /* Skip 1xx messages for now. Advertised in Via as an internal 1.0 hop */
+    if (newrep->sline.status >= 100 && newrep->sline.status < 200) {
+        delete newrep;
+        debugs(11, 2, HERE << "1xx headers consume " << header_bytes_read << " bytes header.");
+        header_bytes_read = 0;
+        if (reply_bytes_read > 0)
+            debugs(11, 2, HERE << "1xx headers consume " << reply_bytes_read << " bytes reply.");
+        reply_bytes_read = 0;
+        ctx_exit(ctx);
+        processReplyHeader();
+        return;
+    }
+
     flags.chunked = 0;
     if (newrep->header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',')) {
 	 flags.chunked = 1;
diff -u -r -N squid-3.0.STABLE24/src/HttpHeaderTools.cc squid-3.0.STABLE25/src/HttpHeaderTools.cc
--- squid-3.0.STABLE24/src/HttpHeaderTools.cc	2010-02-13 02:53:15.000000000 +1300
+++ squid-3.0.STABLE25/src/HttpHeaderTools.cc	2010-03-14 18:45:43.000000000 +1300
@@ -353,25 +353,29 @@
 {
     const char *end, *pos;
     val->clean();
-    assert (*start == '"');
+    if (*start != '"') {
+        debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
+        return 0;
+    }
     pos = start + 1;
 
-    while (1) {
-        if (!(end = index (pos,'"'))) {
+    while (*pos != '"') {
+	bool quoted = (*pos == '\\');
+	if (quoted)
+	    pos++;
+        if (!*pos) {
             debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
+            val->clean();
             return 0;
         }
-
-        /* check for quoted-chars */
-        if (*(end - 1) != '\\') {
-            /* done */
-            val->append(start + 1, end-start-1);
-            return 1;
-        }
-
-        /* try for the end again */
-        pos = end + 1;
+	end = pos + strcspn(pos + quoted, "\"\\") + quoted;
+        val->append(pos, end-pos);
+        pos = end;
     }
+    /* Make sure it's defined even if empty "" */
+    if (!val->buf())
+        val->limitInit("", 0);
+    return 1;
 }
 
 /*
