=== modified file 'src/anyp/PortCfg.cc' --- src/anyp/PortCfg.cc 2013-06-03 14:05:16 +0000 +++ src/anyp/PortCfg.cc 2013-07-22 15:35:19 +0000 @@ -1,12 +1,15 @@ #include "squid.h" #include "anyp/PortCfg.h" #include "comm.h" +#include "fatal.h" +#if USE_SSL +#include "ssl/support.h" +#endif + +#include #if HAVE_LIMITS #include #endif -#if USE_SSL -#include "ssl/support.h" -#endif CBDATA_NAMESPACED_CLASS_INIT(AnyP, PortCfg); @@ -15,7 +18,18 @@ AnyP::PortCfg::PortCfg(const char *aProtocol) : next(NULL), - protocol(xstrdup(aProtocol)), + name(NULL), + defaultsite(NULL) +#if USE_SSL + ,dynamicCertMemCacheSize(std::numeric_limits::max()) +#endif +{ + setTransport(aProtocol); +} + +AnyP::PortCfg::PortCfg(const AnyP::ProtocolVersion &ptv) : + next(NULL), + transport(ptv), name(NULL), defaultsite(NULL) #if USE_SSL @@ -32,7 +46,6 @@ safe_free(name); safe_free(defaultsite); - safe_free(protocol); #if USE_SSL safe_free(cert); @@ -50,7 +63,7 @@ AnyP::PortCfg * AnyP::PortCfg::clone() const { - AnyP::PortCfg *b = new AnyP::PortCfg(protocol); + AnyP::PortCfg *b = new AnyP::PortCfg(transport); b->s = s; if (name) @@ -99,18 +112,18 @@ if (!signingCert) { char buf[128]; - fatalf("No valid signing SSL certificate configured for %s_port %s", protocol, s.toUrl(buf, sizeof(buf))); + fatalf("No valid signing SSL certificate configured for %s_port %s", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf))); } if (!signPkey) - debugs(3, DBG_IMPORTANT, "No SSL private key configured for " << protocol << "_port " << s); + debugs(3, DBG_IMPORTANT, "No SSL private key configured for " << AnyP::ProtocolType_str[transport.protocol] << "_port " << s); Ssl::generateUntrustedCert(untrustedSigningCert, untrustedSignPkey, signingCert, signPkey); if (!untrustedSigningCert) { char buf[128]; - fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", protocol, s.toUrl(buf, sizeof(buf))); + fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf))); } if (crlfile) @@ -139,8 +152,23 @@ if (!staticSslContext) { char buf[128]; - fatalf("%s_port %s initialization error", protocol, s.toUrl(buf, sizeof(buf))); + fatalf("%s_port %s initialization error", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf))); } } #endif +void +AnyP::PortCfg::setTransport(const char *aProtocol) +{ + // HTTP/1.0 not supported because we are version 1.1 which contains a superset of 1.0 + // and RFC 2616 requires us to upgrade 1.0 to 1.1 + + if (strcasecmp("http", aProtocol) != 0 || strcmp("HTTP/1.1", aProtocol) != 0) + transport = AnyP::ProtocolVersion(AnyP::PROTO_HTTP, 1,1); + + else if (strcasecmp("https", aProtocol) != 0 || strcmp("HTTPS/1.1", aProtocol) != 0) + transport = AnyP::ProtocolVersion(AnyP::PROTO_HTTPS, 1,1); + + else + fatalf("http(s)_port protocol=%s is not supported\n", aProtocol); +} === modified file 'src/anyp/PortCfg.h' --- src/anyp/PortCfg.h 2013-06-13 11:08:58 +0000 +++ src/anyp/PortCfg.h 2013-07-22 15:34:18 +0000 @@ -2,6 +2,7 @@ #define SQUID_ANYP_PORTCFG_H #include "anyp/forward.h" +#include "anyp/ProtocolVersion.h" #include "anyp/TrafficMode.h" #include "comm/Connection.h" @@ -15,7 +16,8 @@ class PortCfg { public: - PortCfg(const char *aProtocol); + explicit PortCfg(const char *aProtocol); + explicit PortCfg(const AnyP::ProtocolVersion &aProtocol); ~PortCfg(); AnyP::PortCfg *clone() const; #if USE_SSL @@ -23,10 +25,17 @@ void configureSslServerContext(); #endif + /** + * Set this ports transport type from a string representation. + * Unknown transport type representations will halt Squid. + * Supports: HTTP, HTTP/1.1, HTTPS, HTTPS/1.1. + */ + void setTransport(const char *aProtocol); + PortCfg *next; Ip::Address s; - char *protocol; /* protocol name */ + AnyP::ProtocolVersion transport; ///< transport protocol and version received by this port char *name; /* visible name */ char *defaultsite; /* default web site */ === modified file 'src/anyp/ProtocolVersion.h' --- src/anyp/ProtocolVersion.h 2013-03-17 12:19:16 +0000 +++ src/anyp/ProtocolVersion.h 2013-07-18 04:59:21 +0000 @@ -87,7 +87,7 @@ inline std::ostream & operator << (std::ostream &os, const AnyP::ProtocolVersion &v) { - return (os << AnyP::ProtocolType_str[v.protocol] << v.major << '.' << v.minor); + return (os << AnyP::ProtocolType_str[v.protocol] << '/' << v.major << '.' << v.minor); } #endif /* SQUID_ANYP_PROTOCOLVERSION_H */ === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2013-07-21 19:24:35 +0000 +++ src/cache_cf.cc 2013-07-22 15:24:09 +0000 @@ -79,6 +79,7 @@ #include "wordlist.h" #include "neighbors.h" #include "tools.h" +#include "URLScheme.h" /* wccp2 has its own conditional definitions */ #include "wccp2.h" #if USE_ADAPTATION @@ -3512,22 +3513,24 @@ s->name = xstrdup(token); s->connection_auth_disabled = false; + const char *portType = URLScheme(s->transport.protocol).const_str(); + if (*token == '[') { /* [ipv6]:port */ host = token + 1; t = strchr(host, ']'); if (!t) { - debugs(3, DBG_CRITICAL, s->protocol << "_port: missing ']' on IPv6 address: " << token); + debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: missing ']' on IPv6 address: " << token); self_destruct(); } *t = '\0'; ++t; if (*t != ':') { - debugs(3, DBG_CRITICAL, s->protocol << "_port: missing Port in: " << token); + debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: missing Port in: " << token); self_destruct(); } if (!Ip::EnableIpv6) { - debugs(3, DBG_CRITICAL, "FATAL: " << s->protocol << "_port: IPv6 is not available."); + debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: IPv6 is not available."); self_destruct(); } port = xatos(t + 1); @@ -3540,14 +3543,14 @@ } else if (strtol(token, &junk, 10) && !*junk) { port = xatos(token); - debugs(3, 3, s->protocol << "_port: found Listen on Port: " << port); + debugs(3, 3, portType << "_port: found Listen on Port: " << port); } else { - debugs(3, DBG_CRITICAL, s->protocol << "_port: missing Port: " << token); + debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: missing Port: " << token); self_destruct(); } if (port == 0 && host != NULL) { - debugs(3, DBG_CRITICAL, s->protocol << "_port: Port cannot be 0: " << token); + debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: Port cannot be 0: " << token); self_destruct(); } @@ -3556,21 +3559,21 @@ s->s.port(port); if (!Ip::EnableIpv6) s->s.setIPv4(); - debugs(3, 3, s->protocol << "_port: found Listen on wildcard address: *:" << s->s.port() ); + debugs(3, 3, portType << "_port: found Listen on wildcard address: *:" << s->s.port()); } else if ( (s->s = host) ) { /* check/parse numeric IPA */ s->s.port(port); if (!Ip::EnableIpv6) s->s.setIPv4(); - debugs(3, 3, s->protocol << "_port: Listen on Host/IP: " << host << " --> " << s->s); + debugs(3, 3, portType << "_port: Listen on Host/IP: " << host << " --> " << s->s); } else if ( s->s.GetHostByName(host) ) { /* check/parse for FQDN */ /* dont use ipcache */ s->defaultsite = xstrdup(host); s->s.port(port); if (!Ip::EnableIpv6) s->s.setIPv4(); - debugs(3, 3, s->protocol << "_port: found Listen as Host " << s->defaultsite << " on IP: " << s->s); + debugs(3, 3, portType << "_port: found Listen as Host " << s->defaultsite << " on IP: " << s->s); } else { - debugs(3, DBG_CRITICAL, s->protocol << "_port: failed to resolve Host/IP: " << host); + debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: failed to resolve Host/IP: " << host); self_destruct(); } } @@ -3647,7 +3650,7 @@ debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: protocol option requires Acceleration mode flag."); self_destruct(); } - s->protocol = xstrdup(token + 9); + s->setTransport(token + 9); } else if (strcmp(token, "allow-direct") == 0) { if (!s->flags.accelSurrogate) { debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: allow-direct option requires Acceleration mode flag."); @@ -3809,7 +3812,7 @@ } #if USE_SSL - if (strcmp(protocol, "https") == 0) { + if (transport.protocol == AnyP::PROTO_HTTPS) { /* ssl-bump on https_port configuration requires either tproxy or intercept, and vice versa */ const bool hijacked = s->flags.isIntercepted(); if (s->flags.tunnelSslBumping && !hijacked) { @@ -3827,7 +3830,7 @@ // 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); + debugs(3, 3, URLScheme(s->transport.protocol) << "_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s); } while (*head) @@ -3866,8 +3869,9 @@ if (s->defaultsite) storeAppendPrintf(e, " defaultsite=%s", s->defaultsite); - if (s->protocol && strcmp(s->protocol,"http") != 0) - storeAppendPrintf(e, " protocol=%s", s->protocol); + // TODO: compare against prefix of 'n' instead of assuming http_port + if (s->transport.protocol != AnyP::PROTO_HTTP) + storeAppendPrintf(e, " protocol=%s", URLScheme(s->transport.protocol).const_str()); if (s->allow_direct) storeAppendPrintf(e, " allow-direct"); === modified file 'src/cf.data.pre' --- src/cf.data.pre 2013-07-21 19:24:35 +0000 +++ src/cf.data.pre 2013-07-21 22:36:01 +0000 @@ -1627,9 +1627,10 @@ no-vhost Disable using HTTP/1.1 Host header for virtual domain support. - protocol= Protocol to reconstruct accelerated requests with. - Defaults to http for http_port and https for - https_port + protocol= Protocol to reconstruct accelerated and intercepted + requests with. Defaults to HTTP/1.1 for http_port and + HTTPS/1.1 for https_port. + Values: HTTP or HTTP/1.1, HTTPS or HTTPS/1.1 vport Virtual host port support. Using the http_port number instead of the port passed on Host: headers. === modified file 'src/client_side.cc' --- src/client_side.cc 2013-07-18 05:02:23 +0000 +++ src/client_side.cc 2013-07-22 15:27:50 +0000 @@ -2148,7 +2148,7 @@ strlen(host); http->uri = (char *)xcalloc(url_sz, 1); const char *protocol = switchedToHttps ? - "https" : conn->port->protocol; + "https" : URLScheme(conn->port->transport.protocol).const_str(); snprintf(http->uri, url_sz, "%s://%s%s", protocol, host, url); debugs(33, 5, "ACCEL VHOST REWRITE: '" << http->uri << "'"); } else if (conn->port->defaultsite /* && !vhost */) { @@ -2162,7 +2162,7 @@ snprintf(vportStr, sizeof(vportStr),":%d",vport); } snprintf(http->uri, url_sz, "%s://%s%s%s", - conn->port->protocol, conn->port->defaultsite, vportStr, url); + URLScheme(conn->port->transport.protocol).const_str(), conn->port->defaultsite, vportStr, url); debugs(33, 5, "ACCEL DEFAULTSITE REWRITE: '" << http->uri <<"'"); } else if (vport > 0 /* && (!vhost || no Host:) */) { debugs(33, 5, "ACCEL VPORT REWRITE: http_port IP + vport=" << vport); @@ -2171,7 +2171,7 @@ http->uri = (char *)xcalloc(url_sz, 1); http->getConn()->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN); snprintf(http->uri, url_sz, "%s://%s:%d%s", - http->getConn()->port->protocol, + URLScheme(conn->port->transport.protocol).const_str(), ipbuf, vport, url); debugs(33, 5, "ACCEL VPORT REWRITE: '" << http->uri << "'"); } @@ -2192,7 +2192,7 @@ int url_sz = strlen(url) + 32 + Config.appendDomainLen + strlen(host); http->uri = (char *)xcalloc(url_sz, 1); - snprintf(http->uri, url_sz, "%s://%s%s", conn->port->protocol, host, url); + snprintf(http->uri, url_sz, "%s://%s%s", URLScheme(conn->port->transport.protocol).const_str(), host, url); debugs(33, 5, "TRANSPARENT HOST REWRITE: '" << http->uri <<"'"); } else { /* Put the local socket IP address as the hostname. */ @@ -2200,7 +2200,7 @@ http->uri = (char *)xcalloc(url_sz, 1); http->getConn()->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN); snprintf(http->uri, url_sz, "%s://%s:%d%s", - http->getConn()->port->protocol, + URLScheme(http->getConn()->port->transport.protocol).const_str(), ipbuf, http->getConn()->clientConnection->local.port(), url); debugs(33, 5, "TRANSPARENT REWRITE: '" << http->uri << "'"); } @@ -2294,7 +2294,7 @@ /* deny CONNECT via accelerated ports */ if (*method_p == Http::METHOD_CONNECT && csd->port && csd->port->flags.accelSurrogate) { - debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << csd->port->protocol << " Accelerator port " << csd->port->s.port() ); + debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << csd->port->transport.protocol << " Accelerator port " << csd->port->s.port()); /* XXX need a way to say "this many character length string" */ debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->buf); hp->request_parse_status = Http::scMethodNotAllowed;