=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc	2012-06-19 16:08:52 +0000
+++ src/cache_cf.cc	2012-07-16 14:52:13 +0000
@@ -38,40 +38,41 @@
 #include "acl/Gadgets.h"
 #include "acl/MethodData.h"
 #if USE_ADAPTATION
 #include "adaptation/Config.h"
 #endif
 #if ICAP_CLIENT
 #include "adaptation/icap/Config.h"
 #endif
 #if USE_ECAP
 #include "adaptation/ecap/Config.h"
 #endif
 #include "anyp/PortCfg.h"
 #if USE_SSL
 #include "ssl/support.h"
 #include "ssl/Config.h"
 #endif
 #if USE_AUTH
 #include "auth/Config.h"
 #include "auth/Scheme.h"
 #endif
+#include "base/RunnersRegistry.h"
 #include "ConfigParser.h"
 #include "CpuAffinityMap.h"
 #include "DiskIO/DiskIOModule.h"
 #include "eui/Config.h"
 #if USE_SQUID_ESI
 #include "esi/Parser.h"
 #endif
 #include "format/Format.h"
 #include "HttpRequestMethod.h"
 #include "ident/Config.h"
 #include "ip/Intercept.h"
 #include "ip/QosConfig.h"
 #include "ip/tools.h"
 #include "log/Config.h"
 #include "MemBuf.h"
 #include "mgr/Registration.h"
 #include "Parsing.h"
 #include "rfc1738.h"
 #if SQUID_SNMP
 #include "snmp.h"
@@ -3791,48 +3792,48 @@
         return;
     }
 
     char *token = strtok(NULL, w_space);
 
     if (!token) {
         self_destruct();
         return;
     }
 
     AnyP::PortCfg *s = new AnyP::PortCfg(protocol);
     parsePortSpecification(s, token);
 
     /* parse options ... */
     while ((token = strtok(NULL, w_space))) {
         parse_port_option(s, token);
     }
 
 #if USE_SSL
     if (strcasecmp(protocol, "https") == 0) {
-        /* ssl-bump on https_port configuration requires either tproxy or intercepted, and vice versa */
+        /* ssl-bump on https_port configuration requires either tproxy or intercept, and vice versa */
         const bool hijacked = s->spoof_client_ip || s->intercepted;
         if (s->sslBump && !hijacked) {
-            debugs(3, DBG_CRITICAL, "FATAL: ssl-bump on https_port requires tproxy/intercepted which is missing.");
+            debugs(3, DBG_CRITICAL, "FATAL: ssl-bump on https_port requires tproxy/intercept which is missing.");
             self_destruct();
         }
         if (hijacked && !s->sslBump) {
-            debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercepted on https_port requires ssl-bump which is missing.");
+            debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercept on https_port requires ssl-bump which is missing.");
             self_destruct();
         }
     }
 #endif
 
     if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && s->s.IsAnyAddr()) {
         // clone the port options from *s to *(s->next)
         s->next = cbdataReference(s->clone());
         s->next->s.SetIPv4();
         debugs(3, 3, protocol << "_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s);
     }
 
     while (*head)
         head = &(*head)->next;
 
     *head = cbdataReference(s);
 }
 
 static void
 dump_generic_port(StoreEntry * e, const char *n, const AnyP::PortCfg * s)
@@ -4520,70 +4521,137 @@
         storeAppendPrintf(entry, "%s ", Ssl::certSignAlgorithm(cs->alg));
         if (cs->aclList)
             dump_acl_list(entry, cs->aclList);
         storeAppendPrintf(entry, "\n");
     }
 }
 
 static void free_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign)
 {
     while(*cert_sign) {
         sslproxy_cert_sign *cs = *cert_sign;
         *cert_sign = cs->next;
 
         if (cs->aclList)
             aclDestroyAclList(&cs->aclList);
 
         safe_free(cs);
     }
 }
 
+class sslBumpCfgRr: public ::RegisteredRunner
+{
+public:
+    static Ssl::BumpMode lastDeprecatedRule;
+    /* RegisteredRunner API */
+    virtual void run(const RunnerRegistry &);
+};
+
+Ssl::BumpMode sslBumpCfgRr::lastDeprecatedRule = Ssl::bumpEnd;
+
+RunnerRegistrationEntry(rrFinalizeConfig, sslBumpCfgRr);
+
+void sslBumpCfgRr::run(const RunnerRegistry &r)
+{
+    if (lastDeprecatedRule != Ssl::bumpEnd) {
+        assert( lastDeprecatedRule == Ssl::bumpClientFirst || lastDeprecatedRule == Ssl::bumpNone);
+        static char buf[1024];
+        if (lastDeprecatedRule == Ssl::bumpClientFirst) {
+            strcpy(buf, "ssl_bump deny all");
+            debugs(3, DBG_CRITICAL, "WARNING: auto-converting deprecated implicit "
+                   "\"ssl_bump deny all\" to \"ssl_bump none all\". New ssl_bump configurations "
+                   "must not use implicit rules. Update your ssl_bump rules.");
+        } else {
+            strcpy(buf, "ssl_bump allow all");
+            debugs(3, DBG_CRITICAL, "WARNING: auto-converting deprecated implicit "
+                   "\"ssl_bump allow all\" to \"ssl_bump client-first all\" which is usually "
+                   "inferior to the newer server-first bumping mode. New ssl_bump"
+                   " configurations must not use implicit rules. Update your ssl_bump rules.");
+        }
+        parse_line(buf);
+    }
+}
+
 static void parse_sslproxy_ssl_bump(acl_access **ssl_bump)
 {
+    typedef const char *BumpCfgStyle;
+    BumpCfgStyle bcsNone = NULL;
+    BumpCfgStyle bcsNew = "new client/server-first/none";
+    BumpCfgStyle bcsOld = "deprecated allow/deny";
+    static BumpCfgStyle bumpCfgStyleLast = bcsNone;
+    BumpCfgStyle bumpCfgStyleNow = bcsNone;
     char *bm;
     if ((bm = strtok(NULL, w_space)) == NULL) {
         self_destruct();
         return;
     }
 
+    // if this is the first rule proccessed
+    if (*ssl_bump == NULL) {
+        bumpCfgStyleLast = bcsNone;
+        sslBumpCfgRr::lastDeprecatedRule = Ssl::bumpEnd;
+    }
+
     acl_access *A = new acl_access;
     A->allow = allow_t(ACCESS_ALLOWED);
 
-    if (strcmp(bm, Ssl::BumpModeStr[Ssl::bumpClientFirst]) == 0)
+    if (strcmp(bm, Ssl::BumpModeStr[Ssl::bumpClientFirst]) == 0) {
         A->allow.kind = Ssl::bumpClientFirst;
-    else if (strcmp(bm, Ssl::BumpModeStr[Ssl::bumpServerFirst]) == 0)
+        bumpCfgStyleNow = bcsNew;
+    } else if (strcmp(bm, Ssl::BumpModeStr[Ssl::bumpServerFirst]) == 0) {
         A->allow.kind = Ssl::bumpServerFirst;
-    else if (strcmp(bm, Ssl::BumpModeStr[Ssl::bumpNone]) == 0)
+        bumpCfgStyleNow = bcsNew;
+    } else if (strcmp(bm, Ssl::BumpModeStr[Ssl::bumpNone]) == 0) {
         A->allow.kind = Ssl::bumpNone;
-    else if (strcmp(bm, "allow") == 0 || strcmp(bm, "deny") == 0) {
-        // allow/deny rule sets may rely on an implicit "negate the last one"
-        // rule which we cannot support due to multuple "allow" keywords
-        debugs(3, DBG_CRITICAL, "FATAL: ssl_bump allow/deny rule(s) " <<
-               "must be CAREFULLY converted to specify bump mode(s).");
-        self_destruct();
-        return;
+        bumpCfgStyleNow = bcsNew;
+    } else if (strcmp(bm, "allow") == 0) {
+        if (sslBumpCfgRr::lastDeprecatedRule == Ssl::bumpEnd)
+            debugs(3, DBG_CRITICAL, "WARNING: auto-converting deprecated "
+                   "\"ssl_bump allow <acl>\" to \"ssl_bump client-first <acl>\" which "
+                   "is usually inferior to the newer server-first "
+                   "bumping mode. Update your ssl_bump rules.");
+        A->allow.kind = Ssl::bumpClientFirst;
+        bumpCfgStyleNow = bcsOld;
+        sslBumpCfgRr::lastDeprecatedRule = Ssl::bumpClientFirst;
+    } else if (strcmp(bm, "deny") == 0) {
+        if (sslBumpCfgRr::lastDeprecatedRule == Ssl::bumpEnd)
+            debugs(3, DBG_CRITICAL, "WARNING: auto-converting deprecated "
+                   "\"ssl_bump deny <acl>\" to \"ssl_bump none <acl>\". Update "
+                   "your ssl_bump rules.");
+        A->allow.kind = Ssl::bumpNone;
+        bumpCfgStyleNow = bcsOld;
+        sslBumpCfgRr::lastDeprecatedRule = Ssl::bumpNone;
     } else {
         debugs(3, DBG_CRITICAL, "FATAL: unknown ssl_bump mode: " << bm);
         self_destruct();
         return;
     }
 
+    if (bumpCfgStyleLast != bcsNone && bumpCfgStyleNow != bumpCfgStyleLast) {
+        debugs(3, DBG_CRITICAL, "FATAL: do not mix " << bumpCfgStyleNow << " actions with " << 
+               bumpCfgStyleLast << " actions. Update your ssl_bump rules.");
+        self_destruct();
+        return;
+    }
+
+    bumpCfgStyleLast = bumpCfgStyleNow;
+
     aclParseAclList(LegacyParser, &A->aclList);
 
     acl_access *B, **T;
     for (B = *ssl_bump, T = ssl_bump; B; T = &B->next, B = B->next);
     *T = A;
 }
 
 static void dump_sslproxy_ssl_bump(StoreEntry *entry, const char *name, acl_access *ssl_bump)
 {
     acl_access *sb;
     for (sb = ssl_bump; sb != NULL; sb = sb->next) {
         storeAppendPrintf(entry, "%s ", name);
         storeAppendPrintf(entry, "%s ", Ssl::bumpMode(sb->allow.kind));
         if (sb->aclList)
             dump_acl_list(entry, sb->aclList);
         storeAppendPrintf(entry, "\n");
     }
 }
 
 static void free_sslproxy_ssl_bump(acl_access **ssl_bump)

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2012-07-01 03:55:21 +0000
+++ src/cf.data.pre	2012-07-12 13:35:52 +0000
@@ -630,41 +630,41 @@
 	  tag=		Apply a tag to a request (for both ERR and OK results)
 	  		Only sets a tag, does not alter existing tags.
 	  log=		String to be logged in access.log. Available as
 	  		%ea in logformat specifications
 
 	If protocol=3.0 (the default) then URL escaping is used to protect
 	each value in both requests and responses.
 
 	If using protocol=2.5 then all values need to be enclosed in quotes
 	if they may contain whitespace, or the whitespace escaped using \.
 	And quotes or \ characters within the keyword value must be \ escaped.
 
 	When using the concurrency= option the protocol is changed by
 	introducing a query channel tag infront of the request/response.
 	The query channel tag is a number between 0 and concurrency-1.
 DOC_END
 
 NAME: acl
 TYPE: acl
 LOC: Config.aclList
-IFDEF USE_SSL
+IF USE_SSL
 DEFAULT: ssl::certHasExpired ssl_error X509_V_ERR_CERT_HAS_EXPIRED
 DEFAULT: ssl::certNotYetValid ssl_error X509_V_ERR_CERT_NOT_YET_VALID
 DEFAULT: ssl::certDomainMismatch ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH
 DEFAULT: ssl::certUntrusted ssl_error X509_V_ERR_INVALID_CA X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY X509_V_ERR_CERT_UNTRUSTED
 DEFAULT: ssl::certSelfSigned ssl_error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
 ENDIF
 DEFAULT: all src all
 DEFAULT: manager url_regex -i ^cache_object:// +i ^https?://[^/]+/squid-internal-mgr/
 DEFAULT: localhost src 127.0.0.1/32 ::1
 DEFAULT: to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
 DEFAULT_DOC: ACLs all, manager, localhost, and to_localhost are predefined.
 DOC_START
 	Defining an Access List
 
 	Every access list definition must begin with an aclname and acltype, 
 	followed by either type-specific arguments or a quoted filename that
 	they are read from.
 
 	   acl aclname acltype argument ...
 	   acl aclname acltype "file" ...
@@ -861,41 +861,41 @@
 	acl aclname ca_cert attribute values...
 	  # match against attributes a users issuing CA SSL certificate
 	  # attribute is one of DN/C/O/CN/L/ST [fast]
 
 	acl aclname ext_user username ...
 	acl aclname ext_user_regex [-i] pattern ...
 	  # string match on username returned by external acl helper [slow]
 	  # use REQUIRED to accept any non-null user name.
 
 	acl aclname tag tagvalue ...
 	  # string match on tag returned by external acl helper [slow]
 
 	acl aclname hier_code codename ...
 	  # string match against squid hierarchy code(s); [fast]
 	  #  e.g., DIRECT, PARENT_HIT, NONE, etc.
 	  #
 	  # NOTE: This has no effect in http_access rules. It only has
 	  # effect in rules that affect the reply data stream such as
 	  # http_reply_access.
 
-IFDEF USE_SSL
+IF USE_SSL
 	acl aclname ssl_error errorname
 	  # match against SSL certificate validation error [fast]
 	  #
 	  # For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt
 	  # template file.
 	  #
 	  # The following can be used as shortcuts for certificate properties:
 	  #  [ssl::]certHasExpired: the "not after" field is in the past
 	  #  [ssl::]certNotYetValid: the "not before" field is in the future
 	  #  [ssl::]certUntrusted: The certificate issuer is not to be trusted.
 	  #  [ssl::]certSelfSigned: The certificate is self signed.
 	  #  [ssl::]certDomainMismatch: The certificate CN domain does not
 	  #         match the name the name of the host we are connecting to.
 	  #
 	  # The ssl::certHasExpired, ssl::certNotYetValid, ssl::certDomainMismatch,
 	  # ssl::certUntrusted, and ssl::certSelfSigned can also be used as
 	  # predefined ACLs, just like the 'all' ACL.
 	  #
 	  # NOTE: The ssl_error ACL is only supported with sslproxy_cert_error,
 	  # sslproxy_cert_sign, and sslproxy_cert_adapt options.
@@ -1545,54 +1545,58 @@
 IFDEF: USE_SSL
 TYPE: PortCfg
 DEFAULT: none
 LOC: Config.Sockaddr.https
 DOC_START
 	Usage:  [ip:]port cert=certificate.pem [key=key.pem] [mode] [options...]
 
 	The socket address where Squid will listen for client requests made
 	over TLS or SSL connections. Commonly referred to as HTTPS.
 
 	This is most useful for situations where you are running squid in
 	accelerator mode and you want to do the SSL work at the accelerator level.
 
 	You may specify multiple socket addresses on multiple lines,
 	each with their own SSL certificate and/or options.
 
 	Modes:
 
 	   accel	Accelerator / reverse proxy mode
 
+	   intercept	Support for IP-Layer interception of
+			outgoing requests without browser settings.
+			NP: disables authentication and IPv6 on the port.
+
 	   tproxy	Support Linux TPROXY for spoofing outgoing
 			connections using the client IP address.
 			NP: disables authentication and maybe IPv6 on the port.
 
 	   ssl-bump	For each intercepted connection allowed by ssl_bump
 			ACLs, establish a secure connection with the client and with
 			the server, decrypt HTTPS messages as they pass through
 			Squid, and treat them as unencrypted HTTP messages,
 			becoming the man-in-the-middle.
 
 			An "ssl_bump server-first" match is required to
 			fully enable bumping of intercepted SSL	connections.
 
-			Requires tproxy.
+			Requires tproxy or intercept.
 
 	Omitting the mode flag causes default forward proxy mode to be used.
 
 
 	See http_port for a list of generic options
 
 
 	SSL Options:
 
 	   cert=	Path to SSL certificate (PEM format).
 
 	   key=		Path to SSL private key file (PEM format)
 			if not specified, the certificate file is
 			assumed to be a combined certificate and
 			key file.
 
 	   version=	The version of SSL/TLS supported
 			    1	automatic (default)
 			    2	SSLv2 only
 			    3	SSLv3 only

=== modified file 'src/cf_gen.cc'
--- src/cf_gen.cc	2012-02-24 18:47:57 +0000
+++ src/cf_gen.cc	2012-07-12 13:30:59 +0000
@@ -242,50 +242,50 @@
      *-------------------------------------------------------------------*/
 
     /* Open input file */
     fp.open(input_filename, std::ifstream::in);
     if (fp.fail()) {
         std::cerr << "error while opening input file '" <<
                   input_filename << "': " << strerror(errno) << std::endl;
         exit(1);
     }
 
     state = sSTART;
 
     while (fp.getline(buff,MAX_LINE), fp.good() && state != sEXIT) {
         char *t;
 
         linenum++;
 
         if ((t = strchr(buff, '\n')))
             *t = '\0';
 
-        if(strncmp(buff, "IFDEF ", 6) == 0) {
-            if ((ptr = strtok(buff + 6, WS)) == NULL) {
-                std::cerr << "Missing IFDEF parameter on line" << linenum << std::endl;
+        if(strncmp(buff, "IF ", 3) == 0) {
+            if ((ptr = strtok(buff + 3, WS)) == NULL) {
+                std::cerr << "Missing IF parameter on line" << linenum << std::endl;
                 exit(1);
             }
             IFDEFS.push(ptr);
             continue;
         } else if (strcmp(buff, "ENDIF") == 0) {
             if (IFDEFS.size() == 0) {
-                std::cerr << "ENDIF without IFDEF before on line " << linenum << std::endl;
+                std::cerr << "ENDIF without IF before on line " << linenum << std::endl;
                 exit(1);
             }
             IFDEFS.pop();
         }
         else if (!IFDEFS.size() || isDefined(IFDEFS.top()))
         switch (state) {
 
         case sSTART:
 
             if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) {
                 /* ignore empty and comment lines */
                 (void) 0;
             } else if (!strncmp(buff, "NAME:", 5)) {
                 char *name, *aliasname;
 
                 if ((name = strtok(buff + 5, WS)) == NULL) {
                     std::cerr << "Error in input file\n";
                     exit(1);
                 }
 

=== modified file 'src/client_side.cc'
--- src/client_side.cc	2012-07-01 03:55:21 +0000
+++ src/client_side.cc	2012-07-12 13:37:54 +0000
@@ -3631,41 +3631,41 @@
     fd_note(params.conn->fd, "client https connect");
 
     if (s->tcp_keepalive.enabled) {
         commSetTcpKeepalive(params.conn->fd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
     }
 
     incoming_sockets_accepted++;
 
     // Socket is ready, setup the connection manager to start using it
     ConnStateData *connState = connStateCreate(params.conn, s);
 
     if (s->sslBump) {
         debugs(33, 5, "httpsAccept: accept transparent connection: " << params.conn);
 
         if (!Config.accessList.ssl_bump) {
             httpsSslBumpAccessCheckDone(ACCESS_DENIED, connState);
             return;
         }
   
         // Create a fake HTTP request for ssl_bump ACL check,
-        // using tproxy-provided destination IP and port.
+        // using tproxy/intercept provided destination IP and port.
         HttpRequest *request = new HttpRequest();
         static char ip[MAX_IPSTRLEN];
         assert(params.conn->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION));
         request->SetHost(params.conn->local.NtoA(ip, sizeof(ip)));
         request->port = params.conn->local.GetPort();
         request->myportname = s->name;
  
         ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL);
         acl_checklist->src_addr = params.conn->remote;
         acl_checklist->my_addr = s->s;
         acl_checklist->nonBlockingCheck(httpsSslBumpAccessCheckDone, connState);
         return;
     } else {
         SSL_CTX *sslContext = s->staticSslContext.get();
         httpsEstablish(connState, sslContext, Ssl::bumpNone);
     }
 }
 
 void
 ConnStateData::sslCrtdHandleReplyWrapper(void *data, char *reply)

=== modified file 'src/client_side.h'
--- src/client_side.h	2012-07-01 03:55:21 +0000
+++ src/client_side.h	2012-07-13 18:33:40 +0000
@@ -326,41 +326,46 @@
 #if USE_SSL
     /// called by FwdState when it is done bumping the server
     void httpsPeeked(Comm::ConnectionPointer serverConnection);
 
     /// Start to create dynamic SSL_CTX for host or uses static port SSL context.
     void getSslContextStart();
     /**
      * Done create dynamic ssl certificate.
      *
      * \param[in] isNew if generated certificate is new, so we need to add this certificate to storage.
      */
     void getSslContextDone(SSL_CTX * sslContext, bool isNew = false);
     /// Callback function. It is called when squid receive message from ssl_crtd.
     static void sslCrtdHandleReplyWrapper(void *data, char *reply);
     /// Proccess response from ssl_crtd.
     void sslCrtdHandleReply(const char * reply);
 
     void switchToHttps(HttpRequest *request, Ssl::BumpMode bumpServerMode);
     bool switchedToHttps() const { return switchedToHttps_; }
     Ssl::ServerBump *serverBump() {return sslServerBump;}
-    void setServerBump(Ssl::ServerBump *srvBump) {if (!sslServerBump) sslServerBump = srvBump;}
+    inline void setServerBump(Ssl::ServerBump *srvBump) {
+        if (!sslServerBump)
+            sslServerBump = srvBump;
+        else
+            assert(sslServerBump == srvBump);
+    }
     /// Fill the certAdaptParams with the required data for certificate adaptation
     /// and create the key for storing/retrieve the certificate to/from the cache
     void buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties);
     /// Called when the client sends the first request on a bumped connection.
     /// Returns false if no [delayed] error should be written to the client.
     /// Otherwise, writes the error to the client and returns true. Also checks
     /// for SQUID_X509_V_ERR_DOMAIN_MISMATCH on bumped requests.
     bool serveDelayedError(ClientSocketContext *context);
 
     Ssl::BumpMode sslBumpMode; ///< ssl_bump decision (Ssl::bumpEnd if n/a).
 
 #else
     bool switchedToHttps() const { return false; }
 #endif
 
 protected:
     void startDechunkingRequest();
     void finishDechunkingRequest(bool withSuccess);
     void abortChunkedRequestBody(const err_type error);
     err_type handleChunkedRequestBody(size_t &putSize);

=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc	2012-07-01 03:55:21 +0000
+++ src/client_side_request.cc	2012-07-12 14:50:22 +0000
@@ -1506,99 +1506,101 @@
  * longer valid, it should call cbdataReferenceDone() so that
  * ClientHttpRequest's reference count goes to zero and it will get
  * deleted.  ClientHttpRequest will then delete ClientRequestContext.
  *
  * Note that we set the _done flags here before actually starting
  * the callout.  This is strictly for convenience.
  */
 
 extern tos_t aclMapTOS (acl_tos * head, ACLChecklist * ch);
 extern nfmark_t aclMapNfmark (acl_nfmark * head, ACLChecklist * ch);
 
 void
 ClientHttpRequest::doCallouts()
 {
     assert(calloutContext);
 
     /*Save the original request for logging purposes*/
     if (!calloutContext->http->al.request)
         calloutContext->http->al.request = HTTPMSGLOCK(request);
 
+    if (!calloutContext->error) {
     // CVE-2009-0801: verify the Host: header is consistent with other known details.
-    if (!calloutContext->error && !calloutContext->host_header_verify_done) {
-        debugs(83, 3, HERE << "Doing calloutContext->hostHeaderVerify()");
-        calloutContext->host_header_verify_done = true;
-        calloutContext->hostHeaderVerify();
-        return;
-    }
+        if (!calloutContext->host_header_verify_done) {
+            debugs(83, 3, HERE << "Doing calloutContext->hostHeaderVerify()");
+            calloutContext->host_header_verify_done = true;
+            calloutContext->hostHeaderVerify();
+            return;
+        }
 
-    if (!calloutContext->error && !calloutContext->http_access_done) {
-        debugs(83, 3, HERE << "Doing calloutContext->clientAccessCheck()");
-        calloutContext->http_access_done = true;
-        calloutContext->clientAccessCheck();
-        return;
-    }
+        if (!calloutContext->http_access_done) {
+            debugs(83, 3, HERE << "Doing calloutContext->clientAccessCheck()");
+            calloutContext->http_access_done = true;
+            calloutContext->clientAccessCheck();
+            return;
+        }
 
 #if USE_ADAPTATION
-    if (!calloutContext->error && !calloutContext->adaptation_acl_check_done) {
-        calloutContext->adaptation_acl_check_done = true;
-        if (Adaptation::AccessCheck::Start(
+        if (!calloutContext->adaptation_acl_check_done) {
+            calloutContext->adaptation_acl_check_done = true;
+            if (Adaptation::AccessCheck::Start(
                     Adaptation::methodReqmod, Adaptation::pointPreCache,
                     request, NULL, this))
-            return; // will call callback
-    }
+                return; // will call callback
+        }
 #endif
 
-    if (!calloutContext->error && !calloutContext->redirect_done) {
-        calloutContext->redirect_done = true;
-        assert(calloutContext->redirect_state == REDIRECT_NONE);
-
-        if (Config.Program.redirect) {
-            debugs(83, 3, HERE << "Doing calloutContext->clientRedirectStart()");
-            calloutContext->redirect_state = REDIRECT_PENDING;
-            calloutContext->clientRedirectStart();
-            return;
+        if (!calloutContext->redirect_done) {
+            calloutContext->redirect_done = true;
+            assert(calloutContext->redirect_state == REDIRECT_NONE);
+
+            if (Config.Program.redirect) {
+                debugs(83, 3, HERE << "Doing calloutContext->clientRedirectStart()");
+                calloutContext->redirect_state = REDIRECT_PENDING;
+                calloutContext->clientRedirectStart();
+                return;
+            }
         }
-    }
 
-    if (!calloutContext->error && !calloutContext->adapted_http_access_done) {
-        debugs(83, 3, HERE << "Doing calloutContext->clientAccessCheck2()");
-        calloutContext->adapted_http_access_done = true;
-        calloutContext->clientAccessCheck2();
-        return;
-    }
+        if (!calloutContext->adapted_http_access_done) {
+            debugs(83, 3, HERE << "Doing calloutContext->clientAccessCheck2()");
+            calloutContext->adapted_http_access_done = true;
+            calloutContext->clientAccessCheck2();
+            return;
+        }
 
-    if (!calloutContext->error && !calloutContext->interpreted_req_hdrs) {
-        debugs(83, 3, HERE << "Doing clientInterpretRequestHeaders()");
-        calloutContext->interpreted_req_hdrs = 1;
-        clientInterpretRequestHeaders(this);
-    }
+        if (!calloutContext->interpreted_req_hdrs) {
+            debugs(83, 3, HERE << "Doing clientInterpretRequestHeaders()");
+            calloutContext->interpreted_req_hdrs = 1;
+            clientInterpretRequestHeaders(this);
+        }
 
-    if (!calloutContext->error && !calloutContext->no_cache_done) {
-        calloutContext->no_cache_done = true;
+        if (!calloutContext->no_cache_done) {
+            calloutContext->no_cache_done = true;
 
-        if (Config.accessList.noCache && request->flags.cachable) {
-            debugs(83, 3, HERE << "Doing calloutContext->checkNoCache()");
-            calloutContext->checkNoCache();
-            return;
+            if (Config.accessList.noCache && request->flags.cachable) {
+                debugs(83, 3, HERE << "Doing calloutContext->checkNoCache()");
+                calloutContext->checkNoCache();
+                return;
+            }
         }
-    }
+    } //  if !calloutContext->error
 
     if (!calloutContext->tosToClientDone) {
         calloutContext->tosToClientDone = true;
         if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConnection)) {
             ACLFilledChecklist ch(NULL, request, NULL);
             ch.src_addr = request->client_addr;
             ch.my_addr = request->my_addr;
             tos_t tos = aclMapTOS(Ip::Qos::TheConfig.tosToClient, &ch);
             if (tos)
                 Ip::Qos::setSockTos(getConn()->clientConnection, tos);
         }
     }
 
     if (!calloutContext->nfmarkToClientDone) {
         calloutContext->nfmarkToClientDone = true;
         if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConnection)) {
             ACLFilledChecklist ch(NULL, request, NULL);
             ch.src_addr = request->client_addr;
             ch.my_addr = request->my_addr;
             nfmark_t mark = aclMapNfmark(Ip::Qos::TheConfig.nfmarkToClient, &ch);

=== modified file 'src/errorpage.cc'
--- src/errorpage.cc	2012-06-19 21:51:49 +0000
+++ src/errorpage.cc	2012-07-12 14:59:05 +0000
@@ -581,46 +581,40 @@
         request_hdrs(NULL),
         err_msg(NULL),
 #if USE_SSL
         detail(NULL),
 #endif
         detailCode(ERR_DETAIL_NONE)
 {
     memset(&flags, 0, sizeof(flags));
     memset(&ftp, 0, sizeof(ftp));
 
     if (page_id >= ERR_MAX && ErrorDynamicPages.items[page_id - ERR_MAX]->page_redirect != HTTP_STATUS_NONE)
         httpStatus = ErrorDynamicPages.items[page_id - ERR_MAX]->page_redirect;
 
     if (req != NULL) {
         request = HTTPMSGLOCK(req);
         src_addr = req->client_addr;
     }
 }
 
 void
-ErrorState::detailError(int detailCode)
-{
-    detailCode = detailCode;
-}
-
-void
 errorAppendEntry(StoreEntry * entry, ErrorState * err)
 {
     assert(entry->mem_obj != NULL);
     assert (entry->isEmpty());
     debugs(4, 4, "Creating an error page for entry " << entry <<
            " with errorstate " << err <<
            " page id " << err->page_id);
 
     if (entry->store_status != STORE_PENDING) {
         debugs(4, 2, "Skipping error page due to store_status: " << entry->store_status);
         /*
          * If the entry is not STORE_PENDING, then no clients
          * care about it, and we don't need to generate an
          * error message
          */
         assert(EBIT_TEST(entry->flags, ENTRY_ABORTED));
         assert(entry->mem_obj->nclients == 0);
         delete err;
         return;
     }

=== modified file 'src/errorpage.h'
--- src/errorpage.h	2012-06-19 21:51:49 +0000
+++ src/errorpage.h	2012-07-13 10:02:38 +0000
@@ -89,41 +89,41 @@
  \endverbatim
  */
 
 class HttpReply;
 class MemBuf;
 
 /// \ingroup ErrorPageAPI
 class ErrorState
 {
 public:
     ErrorState(err_type type, http_status, HttpRequest * request);
     ErrorState(); // not implemented.
     ~ErrorState();
 
     /**
      * Allocates and initializes an error response
      */
     HttpReply *BuildHttpReply(void);
 
     /// set error type-specific detail code
-    void detailError(int detailCode);
+    void detailError(int dCode) {detailCode = dCode;}
 
 private:
     /**
      * Locates error page template to be used for this error
      * and constructs the HTML page content from it.
      */
     MemBuf *BuildContent(void);
 
     /**
      * Convert the given template string into textual output
      *
      * \param text            The string to be converted
      * \param allowRecursion  Whether to convert codes which output may contain codes
      */
     MemBuf *ConvertText(const char *text, bool allowRecursion);
 
     /**
      * Generates the Location: header value for a deny_info error page
      * to be used for this error.
      */

=== modified file 'src/url.cc'
--- src/url.cc	2012-06-19 16:08:52 +0000
+++ src/url.cc	2012-07-12 15:42:23 +0000
@@ -445,40 +445,41 @@
 }
 
 /**
  * Update request with parsed URI data.  If the request arg is
  * non-NULL, put parsed values there instead of allocating a new
  * HttpRequest.
  */
 static HttpRequest *
 urlParseFinish(const HttpRequestMethod& method,
                const AnyP::ProtocolType protocol,
                const char *const urlpath,
                const char *const host,
                const char *const login,
                const int port,
                HttpRequest *request)
 {
     if (NULL == request)
         request = new HttpRequest(method, protocol, urlpath);
     else {
         request->initHTTP(method, protocol, urlpath);
+        safe_free(request->canonical);
     }
 
     request->SetHost(host);
     xstrncpy(request->login, login, MAX_LOGIN_SZ);
     request->port = (unsigned short) port;
     return request;
 }
 
 static HttpRequest *
 urnParse(const HttpRequestMethod& method, char *urn, HttpRequest *request)
 {
     debugs(50, 5, "urnParse: " << urn);
     if (request) {
         request->initHTTP(method, AnyP::PROTO_URN, urn + 4);
         safe_free(request->canonical);
         return request;
     }
 
     return new HttpRequest(method, AnyP::PROTO_URN, urn + 4);
 }