From: Christos Tsantilas Date: Sat, 21 Jul 2012 03:50:06 +0000 (-0600) Subject: Bug 2976: squid reports ERR_INVALID_URL for transparently captured requests when... X-Git-Tag: SQUID_3_1_21~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cd6a1dd4ea748f557a607c93a303d16aa2766c5;p=thirdparty%2Fsquid.git Bug 2976: squid reports ERR_INVALID_URL for transparently captured requests when reconfiguring During reconfigure the configured port config objects in http_port_list may deleted so it is not safe to use them while processing Http requests. For this reason inside prepareTransparentURL (file client_side.cc) function the protocol was hard-coded to "http" instead of read it from the related port config object. But this is breaks the intercepted https traffic. This patch: 1. Inside prepareTransparentURL read the protocol from the related port config object 2. add_http_port() locks the new port pointer before linking it. 3. parse_*() locks the new port pointer before linking it. 4. free_*() unlocks the old port pointer before unlinking it. It does not delete the old pointer. This patch also discussed in squid-dev user mailing list in "Re: [PATCH] Squid host rewrite for intercepted https requests" thread. This is a Measurement Factory project --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 87f458b489..d6d456468b 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -3312,8 +3312,9 @@ add_http_port(char *portspec) http_port_list *s = create_http_port(portspec); // we may need to merge better of the above returns a list with clones assert(s->next == NULL); - s->next = Config.Sockaddr.http; - Config.Sockaddr.http = s; + s->next = cbdataReference(Config.Sockaddr.http); + cbdataReferenceDone(Config.Sockaddr.http); + Config.Sockaddr.http = cbdataReference(s); } http_port_list * @@ -3385,7 +3386,7 @@ parse_http_port_list(http_port_list ** head) if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && s->s.IsAnyAddr()) { // clone the port options from *s to *(s->next) - s->next = clone_http_port_list(s); + s->next = cbdataReference(clone_http_port_list(s)); s->next->s.SetIPv4(); debugs(3, 3, "http(s)_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s); } @@ -3393,7 +3394,7 @@ parse_http_port_list(http_port_list ** head) while (*head) head = &(*head)->next; - *head = s; + *head = cbdataReference(s); } static void @@ -3531,7 +3532,7 @@ free_http_port_list(http_port_list ** head) while ((s = *head) != NULL) { *head = s->next; - delete s; + cbdataReferenceDone(s); } } diff --git a/src/client_side.cc b/src/client_side.cc index 596e6ea2ea..e5fe4106fd 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1950,21 +1950,20 @@ prepareTransparentURL(ConnStateData * conn, ClientHttpRequest *http, char *url, return; /* already in good shape */ /* BUG: Squid cannot deal with '*' URLs (RFC2616 5.1.2) */ - // BUG 2976: Squid only accepts intercepted HTTP. if ((host = mime_get_header(req_hdr, "Host")) != NULL) { int url_sz = strlen(url) + 32 + Config.appendDomainLen + strlen(host); http->uri = (char *)xcalloc(url_sz, 1); - snprintf(http->uri, url_sz, "http://%s%s", /*conn->port->protocol,*/ host, url); + snprintf(http->uri, url_sz, "%s://%s%s", conn->port->protocol, host, url); debugs(33, 5, "TRANSPARENT HOST REWRITE: '" << http->uri <<"'"); } else { /* Put the local socket IP address as the hostname. */ int url_sz = strlen(url) + 32 + Config.appendDomainLen; http->uri = (char *)xcalloc(url_sz, 1); http->getConn()->me.ToHostname(ipbuf,MAX_IPSTRLEN), - snprintf(http->uri, url_sz, "http://%s:%d%s", - // http->getConn()->port->protocol, + snprintf(http->uri, url_sz, "%s://%s:%d%s", + http->getConn()->port->protocol, ipbuf, http->getConn()->me.GetPort(), url); debugs(33, 5, "TRANSPARENT REWRITE: '" << http->uri << "'"); }