From: wessels <> Date: Tue, 24 Jan 2006 03:04:24 +0000 (+0000) Subject: Moved HttpRequest lock/link counter to the base HttpMsg class. This X-Git-Tag: SQUID_3_0_PRE4~355 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a56ee8d19d728fc0895ce9bf665acfbb82e9c05;p=thirdparty%2Fsquid.git Moved HttpRequest lock/link counter to the base HttpMsg class. This makes it easy to also lock-count HttpReply instances. Removed HttpReply::swapOut(), which was a trivial wrapper around StoreEntry::storeEntryReplaceObject(). Just call storeEntryReplaceObject() instead. Removed HttpReply::absorb() which was a hack to deal with the fact that HttpReply's were not lock-counted. --- diff --git a/src/HttpMsg.cc b/src/HttpMsg.cc index b9112b4a54..920e4ba586 100644 --- a/src/HttpMsg.cc +++ b/src/HttpMsg.cc @@ -1,6 +1,6 @@ /* - * $Id: HttpMsg.cc,v 1.23 2006/01/09 20:38:44 wessels Exp $ + * $Id: HttpMsg.cc,v 1.24 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 74 HTTP Message * AUTHOR: Alex Rousskov @@ -41,9 +41,14 @@ HttpMsg::HttpMsg(http_hdr_owner_type owner): header(owner), cache_control(NULL), hdr_sz(0), content_length(0), protocol(PROTO_NONE), - pstate(psReadyToParseStartLine) + pstate(psReadyToParseStartLine), lock_count(0) {} +HttpMsg::~HttpMsg() +{ + assert(lock_count == 0); +} + HttpMsgParseState &operator++ (HttpMsgParseState &aState) { int tmp = (int)aState; @@ -354,3 +359,21 @@ void HttpMsg::firstLineBuf(MemBuf& mb) packFirstLineInto(&p, true); packerClean(&p); } + +HttpMsg * + +HttpMsg::lock() +{ + lock_count++; + return this; +} + +void +HttpMsg::unlock() +{ + assert(lock_count > 0); + --lock_count; + + if (0 == lock_count) + delete this; +} diff --git a/src/HttpMsg.h b/src/HttpMsg.h index 3fdd7a9d87..853953ad76 100644 --- a/src/HttpMsg.h +++ b/src/HttpMsg.h @@ -1,6 +1,6 @@ /* - * $Id: HttpMsg.h,v 1.6 2006/01/09 20:38:44 wessels Exp $ + * $Id: HttpMsg.h,v 1.7 2006/01/23 20:04:24 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -45,14 +45,20 @@ class HttpMsg public: HttpMsg(http_hdr_owner_type owner); - virtual ~HttpMsg() {}; + virtual ~HttpMsg(); virtual void reset() = 0; // will have body when http*Clean()s are gone void packInto(Packer * p, bool full_uri) const; + virtual HttpMsg *lock() + + ; + virtual void unlock(); + public: HttpVersion http_ver; + HttpHeader header; HttpHdrCc *cache_control; @@ -63,28 +69,37 @@ public: int hdr_sz; int content_length; + protocol_t protocol; HttpMsgParseState pstate; /* the current parsing state */ + // returns true and sets hdr_sz on success // returns false and sets *error to zero when needs more data // returns false and sets *error to a positive http_status code on error bool parse(MemBuf *buf, bool eol, http_status *error); + bool parseCharBuf(const char *buf, ssize_t end); + int httpMsgParseStep(const char *buf, int atEnd); + int httpMsgParseError(); + virtual bool expectingBody(method_t, ssize_t&) const = 0; + void firstLineBuf(MemBuf&); protected: virtual bool sanityCheckStartLine(MemBuf *buf, http_status *error) = 0; + virtual void packFirstLineInto(Packer * p, bool full_uri) const = 0; + virtual bool parseFirstLine(const char *blk_start, const char *blk_end) = 0; + virtual void hdrCacheInit(); -public: + int lock_count; - void firstLineBuf(MemBuf&); }; diff --git a/src/HttpReply.cc b/src/HttpReply.cc index 6b44915c35..e7e66127c6 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -1,6 +1,6 @@ /* - * $Id: HttpReply.cc,v 1.81 2005/12/26 11:35:22 serassio Exp $ + * $Id: HttpReply.cc,v 1.82 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 58 HTTP Reply (Response) * AUTHOR: Alex Rousskov @@ -102,6 +102,7 @@ HttpReply::clean() httpStatusLineClean(&sline); } +#if OLD /* absorb: copy the contents of a new reply to the old one, destroy new one */ void HttpReply::absorb(HttpReply * new_rep) @@ -116,6 +117,8 @@ HttpReply::absorb(HttpReply * new_rep) delete new_rep; } +#endif + void HttpReply::packHeadersInto(Packer * p) const { @@ -145,18 +148,6 @@ HttpReply::pack() return mb; } -/* - * swap: create swap-based packer, pack, destroy packer - * This eats the reply. - */ -void -HttpReply::swapOut(StoreEntry * e) -{ - assert(e); - - storeEntryReplaceObject(e, this); -} - MemBuf * httpPackedReply(HttpVersion ver, http_status status, const char *ctype, int clen, time_t lmt, time_t expires) diff --git a/src/HttpReply.h b/src/HttpReply.h index 1970d510dc..041c2f3902 100644 --- a/src/HttpReply.h +++ b/src/HttpReply.h @@ -1,6 +1,6 @@ /* - * $Id: HttpReply.h,v 1.14 2005/11/21 22:49:04 wessels Exp $ + * $Id: HttpReply.h,v 1.15 2006/01/23 20:04:24 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -55,6 +55,17 @@ public: virtual void reset(); + virtual HttpReply *lock() + + { + + return static_cast(HttpMsg::lock()) + + ; + } ; + + //virtual void unlock(); // only needed for debugging + // returns true on success // returns false and sets *error to zero when needs more data // returns false and sets *error to a positive http_status code on error @@ -62,55 +73,76 @@ public: /* public, readable; never update these or their .hdr equivalents directly */ time_t date; + time_t last_modified; + time_t expires; + String content_type; + HttpHdrSc *surrogate_control; + HttpHdrContRange *content_range; + short int keep_alive; /* public, writable, but use httpReply* interfaces when possible */ HttpStatusLine sline; + HttpBody body; /* for small constant memory-resident text bodies only */ String protoPrefix; // e.g., "HTTP/" + bool do_clean; public: virtual bool expectingBody(method_t, ssize_t&) const; + void updateOnNotModified(HttpReply const *other); + /* absorb: copy the contents of a new reply to the old one, destroy new one */ void absorb(HttpReply * new_rep); + /* set commonly used info with one call */ void setHeaders(HttpVersion ver, http_status status, const char *reason, const char *ctype, int clen, time_t lmt, time_t expires); + /* mem-pack: returns a ready to use mem buffer with a packed reply */ MemBuf *pack(); - /* swap: create swap-based packer, pack, destroy packer */ - void swapOut(StoreEntry * e); + /* construct a 304 reply and return it */ HttpReply *make304() const; void redirect(http_status, const char *); + int bodySize(method_t) const; + int validatorsMatch (HttpReply const *other) const; + void packHeadersInto(Packer * p) const; private: /* initialize */ void init(); + void clean(); + void hdrCacheClean(); + void packInto(Packer * p); + /* ez-routines */ /* construct 304 reply and pack it into MemBuf, return MemBuf */ MemBuf *packed304Reply(); + /* header manipulation */ time_t hdrExpirationTime(); protected: virtual void packFirstLineInto(Packer * p, bool) const; + virtual bool parseFirstLine(const char *start, const char *end); + virtual void hdrCacheInit(); }; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 89f4820511..be794e9a65 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.cc,v 1.58 2006/01/19 18:50:36 wessels Exp $ + * $Id: HttpRequest.cc,v 1.59 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 73 HTTP Request * AUTHOR: Duane Wessels @@ -40,12 +40,12 @@ #include "HttpHeaderRange.h" #include "MemBuf.h" -HttpRequest::HttpRequest() : HttpMsg(hoRequest), link_count(0) +HttpRequest::HttpRequest() : HttpMsg(hoRequest) { init(); } -HttpRequest::HttpRequest(method_t aMethod, protocol_t aProtocol, const char *aUrlpath) : HttpMsg(hoRequest),link_count(0) +HttpRequest::HttpRequest(method_t aMethod, protocol_t aProtocol, const char *aUrlpath) : HttpMsg(hoRequest) { init(); initHTTP(aMethod, aProtocol, aUrlpath); @@ -53,7 +53,6 @@ HttpRequest::HttpRequest(method_t aMethod, protocol_t aProtocol, const char *aUr HttpRequest::~HttpRequest() { - assert(link_count == 0); clean(); } @@ -68,9 +67,6 @@ HttpRequest::initHTTP(method_t aMethod, protocol_t aProtocol, const char *aUrlpa void HttpRequest::init() { - /* - * NOTE: init() and clean() do NOT touch link_count! - */ method = METHOD_NONE; protocol = PROTO_NONE; urlpath = NULL; @@ -104,10 +100,6 @@ HttpRequest::init() void HttpRequest::clean() { - /* - * NOTE: init() and clean() do NOT touch link_count! - */ - if (body_connection.getRaw() != NULL) fatal ("request being destroyed with body connection intact\n"); @@ -216,8 +208,10 @@ HttpRequest * requestLink(HttpRequest * request) { assert(request); - request->link_count++; - return request; + + return request->lock() + + ; } void @@ -226,12 +220,7 @@ requestUnlink(HttpRequest * request) if (!request) return; - assert(request->link_count > 0); - - if (--request->link_count > 0) - return; - - delete request; + request->unlock(); } int diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 1423cda187..53f0f11ec3 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.h,v 1.17 2006/01/19 18:50:36 wessels Exp $ + * $Id: HttpRequest.h,v 1.18 2006/01/23 20:04:24 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -57,55 +57,95 @@ public: HttpRequest(method_t aMethod, protocol_t aProtocol, const char *aUrlpath); ~HttpRequest(); virtual void reset(); + + virtual HttpRequest *lock() + + { + + return static_cast(HttpMsg::lock()) + + ; + }; + void initHTTP(method_t aMethod, protocol_t aProtocol, const char *aUrlpath); protected: void clean(); - void init(); -public: - int link_count; /* free when zero */ + void init(); public: method_t method; + char login[MAX_LOGIN_SZ]; + char host[SQUIDHOSTNAMELEN + 1]; + auth_user_request_t *auth_user_request; + u_short port; + String urlpath; + char *canonical; + request_flags flags; + HttpHdrRange *range; + time_t ims; + int imslen; + int max_forwards; + /* these in_addr's could probably be sockaddr_in's */ struct IN_ADDR client_addr; struct IN_ADDR my_addr; + unsigned short my_port; + unsigned short client_port; + ConnStateData::Pointer body_connection; /* used by clientReadBody() */ + HierarchyLogEntry hier; + err_type errType; + char *peer_login; /* Configured peer login:password */ + time_t lastmod; /* Used on refreshes */ + const char *vary_headers; /* Used when varying entities are detected. Changes how the store key is calculated */ + char *peer_domain; /* Configured peer forceddomain */ + String tag; /* Internal tag for this request */ + String extacl_user; /* User name returned by extacl lookup */ + String extacl_passwd; /* Password returned by extacl lookup */ + String extacl_log; /* String to be used for access.log purposes */ public: bool multipartRangeRequest() const; + bool parseFirstLine(const char *start, const char *end); + int parseHeader(const char *parse_start); + virtual bool expectingBody(method_t unused, ssize_t&) const; + int prefixLen(); + void swapOut(StoreEntry * e); + void pack(Packer * p); + static void httpRequestPack(void *obj, Packer *p); private: @@ -113,7 +153,9 @@ private: protected: virtual void packFirstLineInto(Packer * p, bool full_uri) const; + virtual bool sanityCheckStartLine(MemBuf *buf, http_status *error); + virtual void hdrCacheInit(); }; diff --git a/src/ICAP/MsgPipeData.h b/src/ICAP/MsgPipeData.h index 99d4fee826..cbc56589a0 100644 --- a/src/ICAP/MsgPipeData.h +++ b/src/ICAP/MsgPipeData.h @@ -1,6 +1,6 @@ /* - * $Id: MsgPipeData.h,v 1.4 2006/01/11 22:40:39 wessels Exp $ + * $Id: MsgPipeData.h,v 1.5 2006/01/23 20:04:25 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -65,17 +65,19 @@ public: void setCause(HttpRequest *r) { - cause = requestLink(r); + + cause = r->lock() + + ; }; void setHeader(HttpMsg *msg) { clearHeader(); - if (HttpRequest *req = dynamic_cast(msg)) - header = requestLink(req); - else if (HttpReply *rep = dynamic_cast(msg)) - header = rep; + header = msg->lock() + + ; }; public: @@ -91,20 +93,9 @@ public: private: - void clearCause() - { - requestUnlink(cause); - cause = NULL; - }; - - void clearHeader() - { - if (HttpRequest *req = dynamic_cast(header)) - requestUnlink(req); - - header = NULL; - }; + void clearCause() { cause->unlock(); cause = NULL; }; + void clearHeader() { header->unlock(); header = NULL; }; }; #endif /* SQUID_MSGPIPEDATA_H */ diff --git a/src/MemObject.cc b/src/MemObject.cc index 2dc9fcede9..d7d460d06b 100644 --- a/src/MemObject.cc +++ b/src/MemObject.cc @@ -1,6 +1,6 @@ /* - * $Id: MemObject.cc,v 1.20 2006/01/11 22:24:40 wessels Exp $ + * $Id: MemObject.cc,v 1.21 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 19 Store Memory Primitives * AUTHOR: Robert Collins @@ -76,15 +76,23 @@ MemObject::inUseCount() MemObject::MemObject(char const *aUrl, char const *aLog_url) { debugs(20, 3, HERE << "new MemObject " << this); - _reply = new HttpReply; + HttpReply *rep = new HttpReply; + + _reply = rep->lock() + + ; url = xstrdup(aUrl); + #if URL_CHECKSUM_DEBUG chksum = url_checksum(url); + #endif log_url = xstrdup(aLog_url); + object_sz = -1; + /* XXX account log_url */ } @@ -111,7 +119,7 @@ MemObject::~MemObject() #endif - delete _reply; + _reply->unlock(); requestUnlink(request); @@ -187,6 +195,17 @@ MemObject::getReply() const return _reply; } +void +MemObject::replaceHttpReply(HttpReply *newrep) +{ + if (_reply) + _reply->unlock(); + + _reply = newrep->lock() + + ; +} + struct LowestMemReader : public unary_function { LowestMemReader(off_t seed):current(seed){} diff --git a/src/MemObject.h b/src/MemObject.h index 9330660602..7b4f5f3158 100644 --- a/src/MemObject.h +++ b/src/MemObject.h @@ -1,6 +1,6 @@ /* - * $Id: MemObject.h,v 1.10 2004/12/27 11:04:36 serassio Exp $ + * $Id: MemObject.h,v 1.11 2006/01/23 20:04:24 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -59,6 +59,7 @@ public: void write(StoreIOBuffer, STMCB *, void *); void unlinkRequest(); HttpReply const *getReply() const; + void replaceHttpReply(HttpReply *newrep); void stat (MemBuf * mb) const; off_t endOffset () const; size_t size() const; @@ -140,9 +141,15 @@ public: void kickReads(); private: +#if OLD /* Read only - this reply must be preserved by store clients */ /* The original reply. possibly with updated metadata. */ HttpReply const *_reply; +#else + + HttpReply *_reply; +#endif + DeferredReadManager deferredReads; }; diff --git a/src/Store.h b/src/Store.h index b1ac95ef78..f4b4bd4ac3 100644 --- a/src/Store.h +++ b/src/Store.h @@ -1,6 +1,6 @@ /* - * $Id: Store.h,v 1.16 2005/11/21 22:20:12 wessels Exp $ + * $Id: Store.h,v 1.17 2006/01/23 20:04:24 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -71,6 +71,7 @@ public: virtual void complete(); virtual store_client_t storeClientType() const; virtual char const *getSerialisedMetaData(); + virtual void replaceHttpReply(HttpReply *); virtual bool swapoutPossible(); virtual void trimMemory(); void unlink(); diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 0e0514a184..dc45a9d9f5 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -1,6 +1,6 @@ /* - * $Id: cache_manager.cc,v 1.34 2005/11/05 00:08:32 wessels Exp $ + * $Id: cache_manager.cc,v 1.35 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 16 Cache Manager Objects * AUTHOR: Duane Wessels @@ -295,7 +295,7 @@ cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) httpHeaderPutAuth(&rep->header, "Basic", mgr->action); /* store the reply */ - rep->swapOut(entry); + storeEntryReplaceObject(entry, rep); entry->expires = squid_curtime; @@ -325,7 +325,7 @@ cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) -1, /* C-Len */ squid_curtime, /* LMT */ squid_curtime); - rep->swapOut(entry); + storeEntryReplaceObject(entry, rep); } a->handler(entry); diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 02fac2e008..ec26263383 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side_reply.cc,v 1.93 2006/01/19 18:40:28 wessels Exp $ + * $Id: client_side_reply.cc,v 1.94 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 88 Client-side Reply Routines * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c) @@ -742,7 +742,7 @@ clientReplyContext::cacheHit(StoreIOBuffer result) * reply has a meaningful Age: header. */ e->timestamp = timestamp; - temprep->swapOut(e); + storeEntryReplaceObject(e, temprep); e->complete(); /* TODO: why put this in the store and then serialise it and then parse it again. * Simply mark the request complete in our context and @@ -829,7 +829,7 @@ clientReplyContext::processMiss() storeReleaseRequest(http->storeEntry()); rep->redirect(http->redirect.status, http->redirect.location); - rep->swapOut(http->storeEntry()); + storeEntryReplaceObject(http->storeEntry(), rep); http->storeEntry()->complete(); return; } @@ -1036,7 +1036,7 @@ clientReplyContext::purgeDoPurgeHead(StoreEntry *newEntry) r->setHeaders(version, purgeStatus, NULL, NULL, 0, 0, -1); - r->swapOut(http->storeEntry()); + storeEntryReplaceObject(http->storeEntry(), r); http->storeEntry()->complete(); } @@ -1060,7 +1060,7 @@ clientReplyContext::traceReply(clientStreamNode * node) HttpVersion version(1,0); rep->setHeaders(version, HTTP_OK, NULL, "text/plain", http->request->prefixLen(), 0, squid_curtime); - rep->swapOut(http->storeEntry()); + storeEntryReplaceObject(http->storeEntry(), rep); http->request->swapOut(http->storeEntry()); http->storeEntry()->complete(); } diff --git a/src/errorpage.cc b/src/errorpage.cc index 5c86fa4b43..d219cd8d9b 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -1,6 +1,6 @@ /* - * $Id: errorpage.cc,v 1.205 2005/11/05 00:08:32 wessels Exp $ + * $Id: errorpage.cc,v 1.206 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -376,7 +376,7 @@ errorAppendEntry(StoreEntry * entry, ErrorState * err) * on 407/401 responses, and do not check the accel state on 401/407 responses */ authenticateFixHeader(rep, err->auth_user_request, err->request, 0, 1); - rep->swapOut(entry); + storeEntryReplaceObject(entry, rep); EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); storeBufferFlush(entry); entry->complete(); diff --git a/src/ftp.cc b/src/ftp.cc index 78064361c6..70610c825d 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.374 2006/01/03 17:22:31 wessels Exp $ + * $Id: ftp.cc,v 1.375 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -247,7 +247,7 @@ static void ftpLoginParser(const char *, FtpStateData *, int escaped); static wordlist *ftpParseControlReply(char *, size_t, int *, int *); static int ftpRestartable(FtpStateData * ftpState); static void ftpAppendSuccessHeader(FtpStateData * ftpState); -static void ftpAuthRequired(HttpReply * reply, HttpRequest * request, const char *realm); +static HttpReply *ftpAuthRequired(HttpRequest * request, const char *realm); static void ftpHackShortcut(FtpStateData * ftpState, FTPSM * nextState); static void ftpUnhack(FtpStateData * ftpState); static void ftpScheduleReadControlReply(FtpStateData *, int); @@ -1397,7 +1397,6 @@ ftpStart(FwdState * fwd) LOCAL_ARRAY(char, realm, 8192); const char *url = storeUrl(entry); FtpStateData *ftpState; - HttpReply *reply; ftpState = new FtpStateData; debug(9, 3) ("ftpStart: '%s'\n", url); @@ -1433,15 +1432,10 @@ ftpStart(FwdState * fwd) ftpState->user, request->port); } - /* create reply */ - reply = new HttpReply; - - assert(reply != NULL); - /* create appropriate reply */ - ftpAuthRequired(reply, request, realm); + HttpReply *reply = ftpAuthRequired(request, realm); - reply->swapOut(entry); + storeEntryReplaceObject(entry, reply); ftpState->fwd->complete(); @@ -3122,7 +3116,7 @@ ftpAppendSuccessHeader(FtpStateData * ftpState) if (mime_enc) httpHeaderPutStr(&reply->header, HDR_CONTENT_ENCODING, mime_enc); - reply->swapOut(e); + storeEntryReplaceObject(e, reply); storeTimestampsSet(e); @@ -3138,18 +3132,16 @@ ftpAppendSuccessHeader(FtpStateData * ftpState) } } -static void -ftpAuthRequired(HttpReply * old_reply, HttpRequest * request, const char *realm) +static HttpReply * +ftpAuthRequired(HttpRequest * request, const char *realm) { ErrorState *err = errorCon(ERR_CACHE_ACCESS_DENIED, HTTP_UNAUTHORIZED); - HttpReply *rep; err->request = requestLink(request); - rep = errorBuildReply(err); + HttpReply *newrep = errorBuildReply(err); errorStateFree(err); /* add Authenticate header */ - httpHeaderPutAuth(&rep->header, "Basic", realm); - /* move new reply to the old one */ - old_reply->absorb(rep); + httpHeaderPutAuth(&newrep->header, "Basic", realm); + return newrep; } char * diff --git a/src/http.cc b/src/http.cc index 29df0f7f1f..9cc390508a 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.482 2006/01/19 18:40:28 wessels Exp $ + * $Id: http.cc,v 1.483 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -168,7 +168,7 @@ HttpStateData::~HttpStateData() fwd = NULL; // refcounted if (reply) - delete reply; + reply->unlock(); #if ICAP_CLIENT @@ -766,7 +766,7 @@ HttpStateData::processReplyHeader() /* Creates a blank header. If this routine is made incremental, this will * not do */ - reply = new HttpReply; + HttpReply *newrep = new HttpReply; Ctx ctx = ctx_enter(entry->mem_obj->url); debug(11, 3) ("processReplyHeader: key '%s'\n", entry->getMD5Text()); @@ -774,14 +774,13 @@ HttpStateData::processReplyHeader() http_status error = HTTP_STATUS_NONE; - const bool parsed = reply->parse(readBuf, eof, &error); + const bool parsed = newrep->parse(readBuf, eof, &error); if (!parsed && error > 0) { // unrecoverable parsing error debugs(11, 3, "processReplyHeader: Non-HTTP-compliant header: '" << readBuf->content() << "'"); flags.headers_parsed = 1; // negated result yields http_status - failReply (reply, error); // consumes reply - reply = NULL; + failReply (newrep, error); ctx_exit(ctx); return; } @@ -789,16 +788,20 @@ HttpStateData::processReplyHeader() if (!parsed) { // need more data assert(!error); assert(!eof); - delete reply; - reply = NULL; + delete newrep; ctx_exit(ctx); return; } + reply = newrep->lock() + + ; + debug(11, 9) ("GOT HTTP REPLY HDR:\n---------\n%s\n----------\n", readBuf->content()); readBuf->consume(headersEnd(readBuf->content(), readBuf->contentSize())); + flags.headers_parsed = 1; keepaliveAccounting(reply); @@ -827,9 +830,6 @@ HttpStateData::processReplyHeader() storeEntryReplaceObject(entry, reply); - /* Note storeEntryReplaceObject() consumes reply, so we cannot use it */ - reply = NULL; - haveParsedReplyHeaders(); if (eof == 1) { @@ -975,7 +975,6 @@ HttpStateData::statusIfComplete() const HttpStateData::ConnectionStatus HttpStateData::persistentConnStatus() const { - HttpReply const *reply = getReply(); int clen; debug(11, 3) ("persistentConnStatus: FD %d\n", fd); ConnectionStatus result = statusIfComplete(); @@ -2017,9 +2016,6 @@ HttpStateData::icapAclCheckDone(ICAPServiceRep::Pointer service) // handle case where no service is selected; storeEntryReplaceObject(entry, reply); - /* Note storeEntryReplaceObject() consumes reply, so we cannot use it */ - reply = NULL; - haveParsedReplyHeaders(); processReplyBody(); @@ -2084,12 +2080,11 @@ HttpStateData::takeAdaptedHeaders(HttpReply *rep) assert (rep); storeEntryReplaceObject(entry, rep); + reply->unlock(); - /* - * After calling storeEntryReplaceObject() we give up control - * of the rep and this->reply pointers. - */ - rep = NULL; + reply = rep->lock() + + ; haveParsedReplyHeaders(); diff --git a/src/http.h b/src/http.h index 3b4e5d249c..cd9dc822b4 100644 --- a/src/http.h +++ b/src/http.h @@ -1,6 +1,6 @@ /* - * $Id: http.h,v 1.18 2006/01/04 20:29:15 wessels Exp $ + * $Id: http.h,v 1.19 2006/01/23 20:04:24 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -106,13 +106,18 @@ public: * getReply() public only because it is called from a static function * as httpState->getReply() */ +#if OLD const HttpReply * getReply() const { return reply ? reply : entry->getReply(); } +#else + const HttpReply * getReply() const { assert(reply); return reply; } + +#endif + private: /* - * This HttpReply will be owned by HttpStateData until it is given to the - * StoreEntry. This is necessary/usefulr for ESI/ICAP. Use this class' getReply() - * method to get the reply either directly from this class or from the StoreEntry + * HttpReply is now shared (locked) among multiple classes, + * including HttpStateData, StoreEntry, and ICAP. */ HttpReply *reply; diff --git a/src/internal.cc b/src/internal.cc index b59b5991df..a61565ad49 100644 --- a/src/internal.cc +++ b/src/internal.cc @@ -1,6 +1,6 @@ /* - * $Id: internal.cc,v 1.34 2005/11/05 00:08:32 wessels Exp $ + * $Id: internal.cc,v 1.35 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 76 Internal Squid Object handling * AUTHOR: Duane, Alex, Henrik @@ -70,7 +70,7 @@ internalStart(HttpRequest * request, StoreEntry * entry) strlen(msgbuf), squid_curtime, -2); - reply->swapOut(entry); + storeEntryReplaceObject(entry, reply); storeAppend(entry, msgbuf, strlen(msgbuf)); entry->complete(); } else { diff --git a/src/mime.cc b/src/mime.cc index affa8f536b..bc37447688 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -1,6 +1,6 @@ /* - * $Id: mime.cc,v 1.120 2005/11/05 00:08:32 wessels Exp $ + * $Id: mime.cc,v 1.121 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 25 MIME Parsing * AUTHOR: Harvest Derived @@ -620,7 +620,7 @@ MimeIcon::created (StoreEntry *newEntry) httpHeaderPutCc(&reply->header, reply->cache_control); - reply->swapOut(e); + storeEntryReplaceObject(e, reply); /* read the file into the buffer and append it to store */ buf = (char *)memAllocate(MEM_4K_BUF); diff --git a/src/net_db.cc b/src/net_db.cc index 87836d0e0a..b633d19a37 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -1,6 +1,6 @@ /* - * $Id: net_db.cc,v 1.180 2006/01/03 21:13:27 wessels Exp $ + * $Id: net_db.cc,v 1.181 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 38 Network Measurement Database * AUTHOR: Duane Wessels @@ -1210,7 +1210,7 @@ netdbBinaryExchange(StoreEntry * s) storeBuffer(s); HttpVersion version(1, 0); reply->setHeaders(version, HTTP_OK, "OK", NULL, -1, squid_curtime, -2); - reply->swapOut(s); + storeEntryReplaceObject(s, reply); rec_sz = 0; rec_sz += 1 + sizeof(addr.s_addr); rec_sz += 1 + sizeof(int); @@ -1270,7 +1270,7 @@ netdbBinaryExchange(StoreEntry * s) HttpVersion version(1,0); reply->setHeaders(version, HTTP_BAD_REQUEST, "Bad Request", NULL, -1, squid_curtime, -2); - reply->swapOut(s); + storeEntryReplaceObject(s, reply); storeAppendPrintf(s, "NETDB support not compiled into this Squid cache.\n"); #endif diff --git a/src/store.cc b/src/store.cc index 3e49e41eb8..866d7bdb35 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.582 2006/01/11 21:10:56 wessels Exp $ + * $Id: store.cc,v 1.583 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 20 Storage Manager * AUTHOR: Harvest Derived @@ -1754,40 +1754,49 @@ storeSwapFileNumberSet(StoreEntry * e, sfileno filn) #endif + /* Replace a store entry with * a new reply. This eats the reply. */ void storeEntryReplaceObject(StoreEntry * e, HttpReply * rep) { - MemObject * const mem = e->mem_obj; - HttpReply *myrep; + e->replaceHttpReply(rep); +} + +void +StoreEntry::replaceHttpReply(HttpReply *rep) +{ + debug(20, 3) ("storeEntryReplaceObject: %s\n", storeUrl(this)); Packer p; - debug(20, 3) ("storeEntryReplaceObject: %s\n", storeUrl(e)); - if (!mem) { + if (!mem_obj) { debug (20,0)("Attempt to replace object with no in-memory representation\n"); return; } + mem_obj->replaceHttpReply(rep); + +#if OLD /* TODO: check that there is at most 1 store client ? */ - myrep = (HttpReply *)e->getReply(); /* we are allowed to do this */ + HttpReply *myrep = (HttpReply *)e->getReply(); /* we are allowed to do this */ /* move info to the mem_obj->reply */ myrep->absorb(rep); +#endif /* TODO: when we store headers serparately remove the header portion */ /* TODO: mark the length of the headers ? */ /* We ONLY want the headers */ - packerToStoreInit(&p, e); + packerToStoreInit(&p, this); - assert (e->isEmpty()); + assert (isEmpty()); - e->getReply()->packHeadersInto(&p); + getReply()->packHeadersInto(&p); - myrep->hdr_sz = e->mem_obj->endOffset(); + rep->hdr_sz = mem_obj->endOffset(); - httpBodyPackInto(&e->getReply()->body, &p); + httpBodyPackInto(&getReply()->body, &p); packerClean(&p); } diff --git a/src/store_digest.cc b/src/store_digest.cc index 85f823647d..f8ee6646f4 100644 --- a/src/store_digest.cc +++ b/src/store_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: store_digest.cc,v 1.60 2005/11/05 00:08:33 wessels Exp $ + * $Id: store_digest.cc,v 1.61 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 71 Store Digest Manager * AUTHOR: Alex Rousskov @@ -430,7 +430,7 @@ storeDigestRewriteResume(void) debug(71, 3) ("storeDigestRewrite: entry expires on %ld (%+d)\n", (long int) rep->expires, (int) (rep->expires - squid_curtime)); storeBuffer(e); - rep->swapOut(e); + storeEntryReplaceObject(e, rep); storeDigestCBlockSwapOut(e); storeBufferFlush(e); eventAdd("storeDigestSwapOutStep", storeDigestSwapOutStep, sd_state.rewrite_lock, 0.0, 1); diff --git a/src/urn.cc b/src/urn.cc index 610caf4894..0c3c8330b6 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -1,6 +1,6 @@ /* - * $Id: urn.cc,v 1.93 2006/01/03 17:22:31 wessels Exp $ + * $Id: urn.cc,v 1.94 2006/01/23 20:04:24 wessels Exp $ * * DEBUG: section 52 URN Parsing * AUTHOR: Kostas Anagnostakis @@ -370,8 +370,7 @@ urnHandleReply(void *data, StoreIOBuffer result) assert(urlres_e->getReply()); rep = new HttpReply; rep->parseCharBuf(buf, k); - debug(52, 3) ("reply exists, code=%d.\n", - rep->sline.status); + debug(52, 3) ("reply exists, code=%d.\n", rep->sline.status); if (rep->sline.status != HTTP_OK) { debug(52, 3) ("urnHandleReply: failed.\n"); @@ -449,7 +448,7 @@ urnHandleReply(void *data, StoreIOBuffer result) httpBodySet(&rep->body, mb); /* don't clean or delete mb; rep->body owns it now */ - rep->swapOut(e); + storeEntryReplaceObject(e, rep); e->complete(); for (i = 0; i < urlcnt; i++) {