From: Alex Rousskov Date: Tue, 30 Sep 2008 16:59:13 +0000 (-0600) Subject: Added HttpRequest::clone, completing HttpMsg::clone API. When ICAP is X-Git-Tag: SQUID_3_1_0_1~45^2~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fa0e61149575ba9c162e378250e0109344463424;p=thirdparty%2Fsquid.git Added HttpRequest::clone, completing HttpMsg::clone API. When ICAP is converted to use this, it should work faster for a common "no modifications" case because it would not have to print and parse the headers. TODO: Consider renaming the method since it does not produce an exact, true replica. Some connection-related flags and peer settings are not cloned because the clone is not always "attached" or "coming from" the same connection (e.g., it is cloned for eCAP to modify). We may also #ifdef the method if it is not needed outside of adaptation code. The HttpMsg::body_pipe field is now copied when a message is cloned. I was not sure what the right thing to do there is. The field itself may be misplaced (it is not about the message structure or properties, but about the current body transfer state, but we lack a good place to store that...). To reduce the number of cloning exceptions, and since eCAP and probably ICAP code benefit from pipe copying, it is copied for now. It would not be too hard to change. --- diff --git a/src/HttpMsg.h b/src/HttpMsg.h index 842333bc08..7ecb1ed0f9 100644 --- a/src/HttpMsg.h +++ b/src/HttpMsg.h @@ -55,6 +55,9 @@ public: virtual HttpMsg *_lock(); // please use HTTPMSGLOCK() virtual void _unlock(); // please use HTTPMSGUNLOCK() + ///< produce a message copy, except for a few connection-specific settings + virtual HttpMsg *clone() const = 0; ///< \todo rename: not a true copy? + public: HttpVersion http_ver; diff --git a/src/HttpReply.cc b/src/HttpReply.cc index 97e327313b..bfbd0b06fe 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -552,6 +552,7 @@ HttpReply::calcMaxBodySize(HttpRequest& request) } } +// XXX: check that this is sufficient for eCAP cloning HttpReply * HttpReply::clone() const { @@ -561,6 +562,8 @@ HttpReply::clone() const rep->hdr_sz = hdr_sz; rep->http_ver = http_ver; rep->pstate = pstate; + rep->body_pipe = body_pipe; + rep->protocol = protocol; rep->sline = sline; return rep; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index f099d6919f..3f17df12ec 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -143,6 +143,59 @@ HttpRequest::reset() init(); } +HttpRequest * +HttpRequest::clone() const +{ + HttpRequest *copy = new HttpRequest(method, protocol, urlpath.buf()); + // TODO: move common cloning clone to Msg::copyTo() or copy ctor + copy->header.append(&header); + copy->hdrCacheInit(); + copy->hdr_sz = hdr_sz; + copy->http_ver = http_ver; + copy->pstate = pstate; // TODO: should we assert a specific state here? + copy->body_pipe = body_pipe; + + strncpy(copy->login, login, sizeof(login)); // MAX_LOGIN_SZ + strncpy(copy->host, host, sizeof(host)); // SQUIDHOSTNAMELEN + copy->host_addr = host_addr; + + if (auth_user_request) { + copy->auth_user_request = auth_user_request; + AUTHUSERREQUESTLOCK(copy->auth_user_request, "HttpRequest::clone"); + } + + copy->port = port; + // urlPath handled in ctor + copy->canonical = canonical ? xstrdup(canonical) : NULL; + + // This may be too conservative for the 204 No Content case + // may eventually need cloneNullAdaptationImmune() for that. + copy->flags = flags.cloneAdaptationImmune(); + + copy->range = range ? new HttpHdrRange(*range) : NULL; + copy->ims = ims; + copy->imslen = imslen; + copy->max_forwards = max_forwards; + copy->client_addr = client_addr; + copy->my_addr = my_addr; + copy->hier = hier; // Is it safe to copy? Should we? + + copy->errType = errType; + + // XXX: what to do with copy->peer_login? + + copy->lastmod = lastmod; + copy->vary_headers = vary_headers ? xstrdup(vary_headers) : NULL; + // XXX: what to do with copy->peer_domain? + + copy->tag = tag; + copy->extacl_user = extacl_user; + copy->extacl_passwd = extacl_passwd; + copy->extacl_log = extacl_log; + + return copy; +} + bool HttpRequest::sanityCheckStartLine(MemBuf *buf, http_status *error) { diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 39a0694dc5..2dcec900a3 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -65,6 +65,8 @@ public: void initHTTP(const HttpRequestMethod& aMethod, protocol_t aProtocol, const char *aUrlpath); + virtual HttpRequest *clone() const; + /* are responses to this request potentially cachable */ bool cacheable() const;