From: Amos Jeffries Date: Tue, 31 Dec 2013 15:51:51 +0000 (-0800) Subject: Make URI request-line field accessor for Http1Parser X-Git-Tag: merge-candidate-3-v1~506^2~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5f3cc9a2cc100e836a8754c112acf081ed1927c3;p=thirdparty%2Fsquid.git Make URI request-line field accessor for Http1Parser Also, convert the client-side parseHttpRequest() sub-functions to make use of it. Removing several strlen() and a memory allocation. --- diff --git a/src/client_side.cc b/src/client_side.cc index 10fa4e961d..f937d20f11 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2080,7 +2080,7 @@ setLogUri(ClientHttpRequest * http, char const *uri, bool cleanUrl) } static void -prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, char *url, const Http::Http1ParserPointer &hp) +prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, const Http::Http1ParserPointer &hp) { int vhost = conn->port->vhost; int vport = conn->port->vport; @@ -2091,9 +2091,11 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, char *url, /* BUG: Squid cannot deal with '*' URLs (RFC2616 5.1.2) */ - if (strncasecmp(url, "cache_object://", 15) == 0) + static const SBuf cache_object("cache_object://"); + if (hp->requestUri().startsWith(cache_object)) return; /* already in good shape */ + const char *url = hp->requestUri().c_str(); if (*url != '/') { if (conn->port->vhost) return; /* already in good shape */ @@ -2145,7 +2147,7 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, char *url, debugs(33, 5, "ACCEL VHOST REWRITE: '" << http->uri << "'"); } else if (conn->port->defaultsite /* && !vhost */) { debugs(33, 5, "ACCEL DEFAULTSITE REWRITE: defaultsite=" << conn->port->defaultsite << " + vport=" << vport); - int url_sz = strlen(url) + 32 + Config.appendDomainLen + + int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen + strlen(conn->port->defaultsite); http->uri = (char *)xcalloc(url_sz, 1); char vportStr[32]; @@ -2159,7 +2161,7 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, char *url, } else if (vport > 0 /* && (!vhost || no Host:) */) { debugs(33, 5, "ACCEL VPORT REWRITE: http_port IP + vport=" << vport); /* Put the local socket IP address as the hostname, with whatever vport we found */ - int url_sz = strlen(url) + 32 + Config.appendDomainLen; + int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen; http->uri = (char *)xcalloc(url_sz, 1); http->getConn()->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN); snprintf(http->uri, url_sz, "%s://%s:%d%s", @@ -2170,30 +2172,30 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, char *url, } static void -prepareTransparentURL(ConnStateData * conn, ClientHttpRequest *http, char *url, const Http::Http1ParserPointer &hp) +prepareTransparentURL(ConnStateData * conn, ClientHttpRequest *http, const Http::Http1ParserPointer &hp) { char *host; char ipbuf[MAX_IPSTRLEN]; - if (*url != '/') + if (hp->requestUri()[0] != '/') return; /* already in good shape */ /* BUG: Squid cannot deal with '*' URLs (RFC2616 5.1.2) */ if ((host = hp->getHeaderField("Host")) != NULL) { - int url_sz = strlen(url) + 32 + Config.appendDomainLen + + int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen + strlen(host); http->uri = (char *)xcalloc(url_sz, 1); - snprintf(http->uri, url_sz, "%s://%s%s", URLScheme(conn->port->transport.protocol).const_str(), host, url); + snprintf(http->uri, url_sz, "%s://%s%s", URLScheme(conn->port->transport.protocol).const_str(), host, hp->requestUri().c_str()); 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; + int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen; http->uri = (char *)xcalloc(url_sz, 1); http->getConn()->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN); snprintf(http->uri, url_sz, "%s://%s:%d%s", URLScheme(http->getConn()->port->transport.protocol).const_str(), - ipbuf, http->getConn()->clientConnection->local.port(), url); + ipbuf, http->getConn()->clientConnection->local.port(), hp->requestUri().c_str()); debugs(33, 5, "TRANSPARENT REWRITE: '" << http->uri << "'"); } } @@ -2300,22 +2302,7 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp) debugs(33, 5, "parseHttpRequest: Request Header is\n" << hp->rawHeaderBuf()); /* 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->req.u_end - hp->req.u_start + 16); - - memcpy(url, hp->buf + hp->req.u_start, hp->req.u_end - hp->req.u_start + 1); - - url[hp->req.u_end - hp->req.u_start + 1] = '\0'; - -#if THIS_VIOLATES_HTTP_SPECS_ON_URL_TRANSFORMATION - - if ((t = strchr(url, '#'))) /* remove HTML anchors */ - *t = '\0'; - -#endif + const char *url = hp->requestUri().c_str(); debugs(33,5, HERE << "repare absolute URL from " << (csd->transparent()?"intercept":(csd->port->flags.accelSurrogate ? "accel":""))); @@ -2332,7 +2319,7 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp) */ if (csd->transparent()) { /* intercept or transparent mode, properly working with no failures */ - prepareTransparentURL(csd, http, url, hp); + prepareTransparentURL(csd, http, hp); } else if (internalCheck(url)) { /* internal URL mode */ @@ -2344,7 +2331,7 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp) } else if (csd->port->flags.accelSurrogate || csd->switchedToHttps()) { /* accelerator mode */ - prepareAcceleratedURL(csd, http, url, hp); + prepareAcceleratedURL(csd, http, hp); } if (!http->uri) { @@ -2362,7 +2349,6 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp) debugs(11, 2, "HTTP Client REQUEST:\n---------\n" << (hp->buf) + hp->req.m_start << "\n----------"); result->flags.parsed_ok = 1; - xfree(url); return result; } diff --git a/src/http/Http1Parser.cc b/src/http/Http1Parser.cc index c1a4a0b976..b73f205d31 100644 --- a/src/http/Http1Parser.cc +++ b/src/http/Http1Parser.cc @@ -229,6 +229,7 @@ Http::Http1Parser::parseRequestFirstLine() request_parse_status = Http::scBadRequest; // missing URI return -1; } + uri_.assign(&buf[req.u_start], req.u_end - req.u_start + 1); // Last whitespace SP = before start of protocol/version if (last_whitespace >= line_end) { @@ -328,7 +329,7 @@ Http::Http1Parser::parseRequest() int retcode = parseRequestFirstLine(); debugs(74, 5, "request-line: retval " << retcode << ": from " << req.start << "->" << req.end << " " << Raw("line", &buf[req.start], req.end-req.start)); debugs(74, 5, "request-line: method " << req.m_start << "->" << req.m_end << " (" << *method_ << ")"); - debugs(74, 5, "request-line: url " << req.u_start << "->" << req.u_end << " " << Raw("field", &buf[req.u_start], req.u_end-req.u_start)); + debugs(74, 5, "request-line: url " << req.u_start << "->" << req.u_end << " (" << uri_ << ")"); debugs(74, 5, "request-line: proto " << req.v_start << "->" << req.v_end << " (" << msgProtocol_ << ")"); debugs(74, 5, "Parser: parse-offset=" << parseOffset_); PROF_stop(HttpParserParseReqLine); diff --git a/src/http/Http1Parser.h b/src/http/Http1Parser.h index d78fad0ec7..f981e1049b 100644 --- a/src/http/Http1Parser.h +++ b/src/http/Http1Parser.h @@ -97,6 +97,9 @@ public: /// the HTTP method if this is a request method const HttpRequestMethodPointer & method() const {return method_;} + /// the request-line URI if this is a request, or an empty string. + SBuf requestUri() const {return uri_;} + // TODO: Offsets for pieces of the (HTTP reply) Status-Line as per RFC 2616 /** HTTP status code to be used on the invalid-request error page @@ -120,6 +123,9 @@ private: /// what request method has been found on the first line HttpRequestMethodPointer method_; + /// raw copy of the origina client reqeust-line URI field + SBuf uri_; + /// buffer holding the mime headers SBuf mimeHeaderBlock_; };