--------------------- PatchSet 8925 Date: 2007/02/18 16:27:29 Author: hno Branch: storework-cutaway Tag: (none) Log: Remove the Vary & ETag code for now. Members: src/HttpReply.c:1.19->1.19.4.1 src/HttpRequest.c:1.17->1.17.4.1 src/client_side.c:1.168->1.168.4.1 src/http.c:1.56->1.56.4.1 src/protos.h:1.133->1.133.4.1 src/store.c:1.45->1.45.4.1 Index: squid/src/HttpReply.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpReply.c,v retrieving revision 1.19 retrieving revision 1.19.4.1 diff -u -r1.19 -r1.19.4.1 --- squid/src/HttpReply.c 26 Jan 2007 02:52:43 -0000 1.19 +++ squid/src/HttpReply.c 18 Feb 2007 16:27:29 -0000 1.19.4.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpReply.c,v 1.19 2007/01/26 02:52:43 squidadm Exp $ + * $Id: HttpReply.c,v 1.19.4.1 2007/02/18 16:27:29 hno Exp $ * * DEBUG: section 58 HTTP Reply (Response) * AUTHOR: Alex Rousskov @@ -183,20 +183,6 @@ rep->hdr_sz = e->mem_obj->inmem_hi - rep->body.mb.size; } -#if UNUSED_CODE -MemBuf -httpPackedReply(http_version_t ver, http_status status, const char *ctype, - squid_off_t clen, time_t lmt, time_t expires) -{ - HttpReply *rep = httpReplyCreate(); - MemBuf mb; - httpReplySetHeaders(rep, ver, status, ctype, NULL, clen, lmt, expires); - mb = httpReplyPack(rep); - httpReplyDestroy(rep); - return mb; -} -#endif - MemBuf httpPacked304Reply(const HttpReply * rep) { Index: squid/src/HttpRequest.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpRequest.c,v retrieving revision 1.17 retrieving revision 1.17.4.1 diff -u -r1.17 -r1.17.4.1 --- squid/src/HttpRequest.c 21 Jan 2007 14:03:34 -0000 1.17 +++ squid/src/HttpRequest.c 18 Feb 2007 16:27:30 -0000 1.17.4.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.c,v 1.17 2007/01/21 14:03:34 squidadm Exp $ + * $Id: HttpRequest.c,v 1.17.4.1 2007/02/18 16:27:30 hno Exp $ * * DEBUG: section 73 HTTP Request * AUTHOR: Duane Wessels @@ -60,9 +60,6 @@ if (req->auth_user_request) authenticateAuthUserRequestUnlock(req->auth_user_request); safe_free(req->canonical); - safe_free(req->vary_hdr); - safe_free(req->vary_headers); - stringClean(&req->vary_encoding); safe_free(req->urlgroup); safe_free(req->extacl_user); safe_free(req->extacl_passwd); @@ -73,13 +70,6 @@ if (req->range) httpHdrRangeDestroy(req->range); stringClean(&req->extacl_log); - if (req->vary) { - if (req->etags == &req->vary->etags) - req->etags = NULL; - storeLocateVaryDone(req->vary); - req->vary = NULL; - } - assert(req->etags == NULL); safe_free(req->etag); if (req->pinned_connection) cbdataUnlock(req->pinned_connection); Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.168 retrieving revision 1.168.4.1 diff -u -r1.168 -r1.168.4.1 --- squid/src/client_side.c 9 Feb 2007 13:55:14 -0000 1.168 +++ squid/src/client_side.c 18 Feb 2007 16:27:31 -0000 1.168.4.1 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.168 2007/02/09 13:55:14 squidadm Exp $ + * $Id: client_side.c,v 1.168.4.1 2007/02/18 16:27:31 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -162,7 +162,6 @@ #if USE_SSL static void httpsAcceptSSL(ConnStateData * connState, SSL_CTX * sslContext); #endif -static int varyEvaluateMatch(StoreEntry * entry, request_t * request); static int modifiedSince(StoreEntry *, request_t *); static StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); static inline int clientNatLookup(ConnStateData * conn); @@ -669,119 +668,6 @@ } static void -clientHandleETagMiss(clientHttpRequest * http) -{ - StoreEntry *entry = http->entry; - request_t *request = http->request; - - request->done_etag = 1; - if (request->vary) { - storeLocateVaryDone(request->vary); - request->vary = NULL; - request->etags = NULL; /* pointed into request->vary */ - } - safe_free(request->etag); - safe_free(request->vary_headers); - safe_free(request->vary_hdr); - storeClientUnregister(http->sc, entry, http); - storeUnlockObject(entry); - http->entry = NULL; - clientProcessRequest(http); -} - -static void -clientHandleETagReply(void *data, char *buf, ssize_t size) -{ - clientHttpRequest *http = data; - StoreEntry *entry = http->entry; - MemObject *mem; - const char *url = storeUrl(entry); - http_status status; - debug(33, 3) ("clientHandleETagReply: %s, %d bytes\n", url, (int) size); - if (entry == NULL) { - /* client aborted */ - return; - } - if (size < 0 && !EBIT_TEST(entry->flags, ENTRY_ABORTED)) { - clientHandleETagMiss(http); - return; - } - mem = entry->mem_obj; - status = mem->reply->sline.status; - if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) { - debug(33, 3) ("clientHandleETagReply: ABORTED '%s'\n", url); - clientHandleETagMiss(http); - return; - } - if (STORE_PENDING == entry->store_status && 0 == status) { - debug(33, 3) ("clientHandleETagReply: Incomplete headers for '%s'\n", url); - if (size >= CLIENT_SOCK_SZ) { - /* will not get any bigger than that */ - debug(33, 3) ("clientHandleETagReply: Reply is too large '%s'\n", url); - clientHandleETagMiss(http); - } else { - storeClientCopy(http->sc, entry, - http->out.offset + size, - http->out.offset, - CLIENT_SOCK_SZ, - buf, - clientHandleETagReply, - http); - } - return; - } - if (HTTP_NOT_MODIFIED == mem->reply->sline.status) { - /* Remember the ETag and restart */ - if (mem->reply) { - request_t *request = http->request; - const char *etag = httpHeaderGetStr(&mem->reply->header, HDR_ETAG); - const char *vary = request->vary_headers; - int has_vary = httpHeaderHas(&entry->mem_obj->reply->header, HDR_VARY); -#if X_ACCELERATOR_VARY - has_vary |= httpHeaderHas(&entry->mem_obj->reply->header, HDR_X_ACCELERATOR_VARY); -#endif - if (has_vary) - vary = httpMakeVaryMark(request, mem->reply); - - if (etag && vary) { - storeAddVary(mem->url, mem->method, NULL, httpHeaderGetStr(&mem->reply->header, HDR_ETAG), request->vary_hdr, request->vary_headers, strBuf(request->vary_encoding)); - } - } - clientHandleETagMiss(http); - return; - } - /* Send the new object to the client */ - clientSendMoreHeaderData(data, buf, size); - return; -} - -static void -clientProcessETag(clientHttpRequest * http) -{ - char *url = http->uri; - StoreEntry *entry = NULL; - debug(33, 3) ("clientProcessETag: '%s'\n", http->uri); - entry = storeCreateEntry(url, http->request->flags, http->request->method); - http->sc = storeClientRegister(entry, http); -#if DELAY_POOLS - /* delay_id is already set on original store client */ - delaySetStoreClient(http->sc, delayClient(http)); -#endif - http->entry = entry; - http->out.offset = 0; - fwdStart(http->conn->fd, http->entry, http->request); - /* Register with storage manager to receive updates when data comes in. */ - if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) - debug(33, 0) ("clientProcessETag: found ENTRY_ABORTED object\n"); - storeClientCopy(http->sc, entry, - http->out.offset, - http->out.offset, - CLIENT_SOCK_SZ, http->readbuf, - clientHandleETagReply, - http); -} - -static void clientProcessExpired(void *data) { clientHttpRequest *http = data; @@ -1130,23 +1016,6 @@ storeRelease(entry); status = HTTP_OK; } - /* And for Vary, release the base URI if none of the headers was included in the request */ - if (http->request->vary_headers && !strstr(http->request->vary_headers, "=")) { - entry = storeGetPublic(urlCanonical(http->request), METHOD_GET); - if (entry) { - debug(33, 4) ("clientPurgeRequest: Vary GET '%s'\n", - storeUrl(entry)); - storeRelease(entry); - status = HTTP_OK; - } - entry = storeGetPublic(urlCanonical(http->request), METHOD_HEAD); - if (entry) { - debug(33, 4) ("clientPurgeRequest: Vary HEAD '%s'\n", - storeUrl(entry)); - storeRelease(entry); - status = HTTP_OK; - } - } /* * Make a new entry to hold the reply to be written * to the client. @@ -2052,32 +1921,6 @@ } /* - * clientProcessVary is called when it is detected that a object - * varies and we need to get the correct variant - */ -static void -clientProcessVary(VaryData * vary, void *data) -{ - clientHttpRequest *http = data; - if (!vary) { - clientProcessRequest(http); - return; - } - if (vary->key) { - debug(33, 2) ("clientProcessVary: HIT key=%s etag=%s\n", - vary->key, vary->etag ? vary->etag : "NONE"); - } else { - int i; - debug(33, 2) ("clientProcessVary MISS\n"); - for (i = 0; i < vary->etags.count; i++) { - debug(33, 3) ("ETag: %s\n", (char *) vary->etags.items[i]); - } - } - http->request->vary = vary; - clientProcessRequest(http); -} - -/* * clientCacheHit should only be called until the HTTP reply headers * have been parsed. Normally this should be a single call, but * it might take more than one. As soon as we have the headers, @@ -2139,50 +1982,6 @@ * Got the headers, now grok them */ assert(http->log_type == LOG_TCP_HIT); - switch (varyEvaluateMatch(e, r)) { - case VARY_NONE: - /* No variance detected. Continue as normal */ - break; - case VARY_MATCH: - /* This is the correct entity for this request. Continue */ - debug(33, 2) ("clientProcessHit: Vary MATCH!\n"); - break; - case VARY_OTHER: - { - /* This is not the correct entity for this request. We need - * to requery the cache. - */ - store_client *sc = http->sc; - http->entry = NULL; /* saved in e */ - /* Warning: storeClientUnregister may abort the object so we must - * call storeLocateVary before unregistering, and - * storeLocateVary may complete immediately so we cannot - * rely on the http structure for this... - */ - http->sc = NULL; - storeLocateVary(e, e->mem_obj->reply->hdr_sz, r->vary_headers, r->vary_encoding, clientProcessVary, http); - storeClientUnregister(sc, e, http); - storeUnlockObject(e); - /* Note: varyEvalyateMatch updates the request with vary information - * so we only get here once. (it also takes care of cancelling loops) - */ - debug(33, 2) ("clientProcessHit: Vary detected!\n"); - return; - } - case VARY_RESTART: - /* Used on collapsed requests when the main request wasn't - * compatible. Resart processing from the beginning. - */ - safe_free(r->vary_hdr); - safe_free(r->vary_headers); - clientProcessRequest(http); - return; - case VARY_CANCEL: - /* varyEvaluateMatch found a object loop. Process as miss */ - debug(33, 1) ("clientProcessHit: Vary object loop!\n"); - clientProcessMiss(http); - return; - } if (r->method == METHOD_PURGE) { http->entry = NULL; storeClientUnregister(http->sc, e, http); @@ -3254,16 +3053,6 @@ if (NULL == e) { /* this object isn't in the cache */ debug(33, 3) ("clientProcessRequest2: storeGet() MISS\n"); - if (r->vary) { - if (r->done_etag) { - debug(33, 2) ("clientProcessRequest2: ETag loop\n"); - } else if (r->etags) { - debug(33, 2) ("clientProcessRequest2: ETag miss\n"); - r->etags = NULL; - } else if (r->vary->etags.count > 0) { - r->etags = &r->vary->etags; - } - } return LOG_TCP_MISS; } if (Config.onoff.offline) { @@ -3454,20 +3243,9 @@ storeComplete(http->entry); return; } - if (r->etags) { - clientProcessETag(http); - return; - } http->entry = clientCreateStoreEntry(http, r->method, r->flags); if (Config.onoff.collapsed_forwarding && r->flags.cachable && !r->flags.need_validation && (r->method = METHOD_GET || r->method == METHOD_HEAD)) { http->entry->mem_obj->refresh_timestamp = squid_curtime; - /* Set the vary object state */ - safe_free(http->entry->mem_obj->vary_headers); - if (r->vary_headers) - http->entry->mem_obj->vary_headers = xstrdup(r->vary_headers); - safe_free(http->entry->mem_obj->vary_encoding); - if (strBuf(r->vary_encoding)) - http->entry->mem_obj->vary_encoding = xstrdup(strBuf(r->vary_encoding)); http->entry->mem_obj->request = requestLink(r); EBIT_SET(http->entry->flags, KEY_EARLY_PUBLIC); storeSetPublicKey(http->entry); @@ -4920,54 +4698,6 @@ NHttpSockets = 0; } -static int -varyEvaluateMatch(StoreEntry * entry, request_t * request) -{ - const char *vary = request->vary_headers; - int has_vary = httpHeaderHas(&entry->mem_obj->reply->header, HDR_VARY); -#if X_ACCELERATOR_VARY - has_vary |= httpHeaderHas(&entry->mem_obj->reply->header, HDR_X_ACCELERATOR_VARY); -#endif - if (!has_vary || !entry->mem_obj->vary_headers) { - if (vary) { - /* Oops... something odd is going on here.. */ - debug(33, 1) ("varyEvaluateMatch: Oops. Not a Vary object on second attempt, '%s' '%s'\n", - entry->mem_obj->url, vary); - safe_free(request->vary_headers); - return VARY_CANCEL; - } - if (!has_vary) { - /* This is not a varying object */ - return VARY_NONE; - } - /* virtual "vary" object found. Calculate the vary key and - * continue the search - */ - vary = httpMakeVaryMark(request, entry->mem_obj->reply); - if (vary) { - return VARY_OTHER; - } else { - /* Ouch.. we cannot handle this kind of variance */ - /* XXX This cannot really happen, but just to be complete */ - return VARY_CANCEL; - } - } else { - if (!vary) - vary = httpMakeVaryMark(request, entry->mem_obj->reply); - if (!vary) { - /* Ouch.. we cannot handle this kind of variance */ - /* XXX This cannot really happen, but just to be complete */ - return VARY_CANCEL; - } else if (request->flags.collapsed) { - /* This request was merged before we knew the outcome. Don't trust the response */ - /* restart vary processing from the beginning */ - return VARY_RESTART; - } else { - return VARY_MATCH; - } - } -} - /* This is a handler normally called by comm_close() */ static void clientPinnedConnectionClosed(int fd, void *data) Index: squid/src/http.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/http.c,v retrieving revision 1.56 retrieving revision 1.56.4.1 diff -u -r1.56 -r1.56.4.1 --- squid/src/http.c 9 Feb 2007 13:55:15 -0000 1.56 +++ squid/src/http.c 18 Feb 2007 16:27:36 -0000 1.56.4.1 @@ -1,6 +1,6 @@ /* - * $Id: http.c,v 1.56 2007/02/09 13:55:15 squidadm Exp $ + * $Id: http.c,v 1.56.4.1 2007/02/18 16:27:36 hno Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -337,78 +337,6 @@ /* NOTREACHED */ } -/* - * For Vary, store the relevant request headers as - * virtual headers in the reply - * Returns false if the variance cannot be stored - */ -const char * -httpMakeVaryMark(request_t * request, HttpReply * reply) -{ - String vary = StringNull, hdr; - const char *pos = NULL; - const char *item; - const char *value; - int ilen; - String vstr = StringNull; - - stringClean(&vstr); - hdr = httpHeaderGetList(&reply->header, HDR_VARY); - if (strBuf(hdr)) - strListAdd(&vary, strBuf(hdr), ','); - stringClean(&hdr); -#if X_ACCELERATOR_VARY - hdr = httpHeaderGetList(&reply->header, HDR_X_ACCELERATOR_VARY); - if (strBuf(hdr)) - strListAdd(&vary, strBuf(hdr), ','); - stringClean(&hdr); -#endif - while (strListGetItem(&vary, ',', &item, &ilen, &pos)) { - char *name = xmalloc(ilen + 1); - xstrncpy(name, item, ilen + 1); - Tolower(name); - if (strcmp(name, "accept-encoding") == 0) { - aclCheck_t checklist; - memset(&checklist, 0, sizeof(checklist)); - checklist.request = request; - checklist.reply = reply; - if (Config.accessList.vary_encoding && aclCheckFast(Config.accessList.vary_encoding, &checklist)) { - stringClean(&request->vary_encoding); - request->vary_encoding = httpHeaderGetStrOrList(&request->header, HDR_ACCEPT_ENCODING); - strCat(request->vary_encoding, ""); - } - } - if (strcmp(name, "*") == 0) { - /* Can not handle "Vary: *" efficiently, bail out making the response not cached */ - safe_free(name); - stringClean(&vary); - stringClean(&vstr); - break; - } - strListAdd(&vstr, name, ','); - hdr = httpHeaderGetByName(&request->header, name); - safe_free(name); - value = strBuf(hdr); - if (value) { - value = rfc1738_escape_part(value); - stringAppend(&vstr, "=\"", 2); - stringAppend(&vstr, value, strlen(value)); - stringAppend(&vstr, "\"", 1); - } - stringClean(&hdr); - } - safe_free(request->vary_hdr); - safe_free(request->vary_headers); - if (strBuf(vary) && strBuf(vstr)) { - request->vary_hdr = xstrdup(strBuf(vary)); - request->vary_headers = xstrdup(strBuf(vstr)); - } - debug(11, 3) ("httpMakeVaryMark: %s\n", strBuf(vstr)); - stringClean(&vary); - stringClean(&vstr); - return request->vary_headers; -} - /* rewrite this later using new interfaces @?@ */ static size_t httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size) @@ -514,22 +442,6 @@ /* non-chunked. Handle as one single big chunk (-1 if terminated by EOF) */ httpState->chunk_size = httpReplyBodySize(httpState->orig_request->method, reply); } - if (httpHeaderHas(&reply->header, HDR_VARY) -#if X_ACCELERATOR_VARY - || httpHeaderHas(&reply->header, HDR_X_ACCELERATOR_VARY) -#endif - ) { - const char *vary = NULL; - if (Config.onoff.cache_vary) - vary = httpMakeVaryMark(httpState->orig_request, reply); - if (!vary) { - httpMakePrivate(entry); - goto no_cache; /* XXX Would be better if this was used by the swicht statement below */ - } - entry->mem_obj->vary_headers = xstrdup(vary); - if (strBuf(httpState->orig_request->vary_encoding)) - entry->mem_obj->vary_encoding = xstrdup(strBuf(httpState->orig_request->vary_encoding)); - } switch (httpCachableReply(httpState)) { case 1: httpMakePublic(entry); @@ -547,7 +459,6 @@ assert(0); break; } - no_cache: if (reply->cache_control) { if (EBIT_TEST(reply->cache_control->mask, CC_PROXY_REVALIDATE)) EBIT_SET(entry->flags, ENTRY_REVALIDATE); @@ -1033,12 +944,15 @@ if (request->etag) { etags = httpHeaderGetList(hdr_in, HDR_IF_NONE_MATCH); strListAddUnique(&etags, request->etag, ','); - } else if (request->etags) { + } +#if NOT_NOW + else if (request->etags) { int i; etags = httpHeaderGetList(hdr_in, HDR_IF_NONE_MATCH); for (i = 0; i < request->etags->count; i++) strListAddUnique(&etags, request->etags->items[i], ','); } +#endif if (strLen(etags)) httpHeaderPutStr(hdr_out, HDR_IF_NONE_MATCH, strBuf(etags)); stringClean(&etags); Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.133 retrieving revision 1.133.4.1 diff -u -r1.133 -r1.133.4.1 --- squid/src/protos.h 26 Jan 2007 02:52:43 -0000 1.133 +++ squid/src/protos.h 18 Feb 2007 16:27:36 -0000 1.133.4.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.133 2007/01/26 02:52:43 squidadm Exp $ + * $Id: protos.h,v 1.133.4.1 2007/02/18 16:27:36 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -313,7 +313,6 @@ extern int httpAnonHdrDenied(http_hdr_type hdr_id); extern void httpBuildRequestHeader(request_t *, request_t *, StoreEntry *, HttpHeader *, http_state_flags); extern void httpBuildVersion(http_version_t * version, unsigned int major, unsigned int minor); -extern const char *httpMakeVaryMark(request_t * request, HttpReply * reply); /* Http Status Line */ /* init/clean */ @@ -1418,11 +1417,6 @@ extern void errorMapInit(void); extern int errorMapStart(const errormap * map, request_t * req, HttpReply * reply, const char *aclname, ERRMAPCB * callback, void *data); -/* ETag support */ -void storeLocateVaryDone(VaryData * data); -void storeLocateVary(StoreEntry * e, int offset, const char *vary_data, String accept_encoding, STLVCB * callback, void *cbdata); -void storeAddVary(const char *url, const method_t method, const cache_key * key, const char *etag, const char *vary, const char *vary_headers, const char *accept_encoding); - /* New HTTP message parsing support */ extern void HttpMsgBufInit(HttpMsgBuf * hmsg, const char *buf, size_t size); extern void httpMsgBufDone(HttpMsgBuf * hmsg); Index: squid/src/store.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/store.c,v retrieving revision 1.45 retrieving revision 1.45.4.1 diff -u -r1.45 -r1.45.4.1 --- squid/src/store.c 7 Feb 2007 00:51:54 -0000 1.45 +++ squid/src/store.c 18 Feb 2007 16:27:38 -0000 1.45.4.1 @@ -1,6 +1,6 @@ /* - * $Id: store.c,v 1.45 2007/02/07 00:51:54 squidadm Exp $ + * $Id: store.c,v 1.45.4.1 2007/02/18 16:27:38 hno Exp $ * * DEBUG: section 20 Storage Manager * AUTHOR: Harvest Derived @@ -182,8 +182,6 @@ mem->request = NULL; ctx_exit(ctx); /* must exit before we free mem->url */ safe_free(mem->url); - safe_free(mem->vary_headers); - safe_free(mem->vary_encoding); memFree(mem, MEM_MEMOBJECT); } @@ -346,13 +344,6 @@ StoreEntry * storeGetPublicByRequestMethod(request_t * req, const method_t method) { - if (req->vary) { - /* Varying objects... */ - if (req->vary->key) - return storeGet(storeKeyScan(req->vary->key)); - else - return NULL; - } return storeGet(storeKeyPublicByRequestMethod(req, method)); } @@ -398,75 +389,6 @@ storeHashInsert(e, newkey); } -typedef struct { - StoreEntry *oe; - StoreEntry *e; - store_client *sc; - char *url; - char *key; - char *vary_headers; - char *accept_encoding; - char *etag; - squid_off_t seen_offset; - char *buf; - size_t buf_size; - size_t buf_offset; - int done:1; - struct { - char *key; - char *etag; - char *accept_encoding; - int this_key:1; - int key_used:1; - int ignore:1; - } current; -} AddVaryState; - -CBDATA_TYPE(AddVaryState); -static void -free_AddVaryState(void *data) -{ - AddVaryState *state = data; - debug(11, 2) ("free_AddVaryState: %p\n", data); - if (!EBIT_TEST(state->e->flags, ENTRY_ABORTED)) { - storeBuffer(state->e); - if (!state->done && state->key) { - storeAppendPrintf(state->e, "Key: %s\n", state->key); - if (state->accept_encoding) - storeAppendPrintf(state->e, "Accept-Encoding: %s\n", state->accept_encoding); - if (state->etag) - storeAppendPrintf(state->e, "ETag: %s\n", state->etag); - storeAppendPrintf(state->e, "VaryData: %s\n", state->vary_headers); - } - storeTimestampsSet(state->e); - storeComplete(state->e); - storeTimestampsSet(state->e); - storeBufferFlush(state->e); - } - storeUnlockObject(state->e); - state->e = NULL; - if (state->sc) { - storeClientUnregister(state->sc, state->oe, state); - state->sc = NULL; - } - if (state->oe) { - storeUnlockObject(state->oe); - state->oe = NULL; - } - safe_free(state->url); - safe_free(state->key); - safe_free(state->vary_headers); - safe_free(state->accept_encoding); - safe_free(state->etag); - safe_free(state->current.key); - safe_free(state->current.etag); - safe_free(state->current.accept_encoding); - if (state->buf) { - memFreeBuf(state->buf_size, state->buf); - state->buf = NULL; - } -} - static int inline strmatchbeg(const char *search, const char *match, int maxlen) { @@ -485,36 +407,7 @@ return strncmp(search, match, maxlen); } -static void -storeAddVaryFlush(AddVaryState * state) -{ - if (state->current.ignore || state->current.key_used) { - /* do nothing */ - } else if (state->current.this_key) { - if (state->current.key) - storeAppendPrintf(state->e, "Key: %s\n", state->current.key); - else - storeAppendPrintf(state->e, "Key: %s\n", state->key); - if (state->accept_encoding) - storeAppendPrintf(state->e, "Accept-Encoding: %s\n", state->accept_encoding); - if (state->etag) - storeAppendPrintf(state->e, "ETag: %s\n", state->etag); - storeAppendPrintf(state->e, "VaryData: %s\n", state->vary_headers); - state->done = 1; - state->current.key_used = 1; - } else if (state->current.key) { - storeAppendPrintf(state->e, "Key: %s\n", state->current.key); - safe_free(state->current.key); - if (state->current.accept_encoding) - storeAppendPrintf(state->e, "Accept-Encoding: %s\n", state->current.accept_encoding); - if (state->current.etag) { - storeAppendPrintf(state->e, "ETag: %s\n", state->current.etag); - safe_free(state->current.etag); - } - state->current.key_used = 1; - } -} - +#if UNUSED_CODE static int strcmpnull(const char *a, const char *b) { @@ -526,7 +419,9 @@ return -1; return 0; } +#endif +#if UNUSED_CODE static int strncmpnull(const char *a, const char *b, size_t n) { @@ -538,438 +433,7 @@ return -1; return 0; } - -static void -storeAddVaryReadOld(void *data, char *buf, ssize_t size) -{ - AddVaryState *state = data; - size_t l = size + state->buf_offset; - char *e; - char *p = state->buf; - debug(11, 3) ("storeAddVaryReadOld: %p seen_offset=%" PRINTF_OFF_T " buf_offset=%d size=%d\n", data, state->seen_offset, (int) state->buf_offset, (int) size); - if (size <= 0) { - debug(11, 2) ("storeAddVaryReadOld: DONE\n"); - cbdataFree(state); - return; - } - if (EBIT_TEST(state->e->flags, ENTRY_ABORTED)) { - debug(11, 1) ("storeAddVaryReadOld: New index aborted at %d (%d)\n", (int) state->seen_offset, (int) size); - cbdataFree(state); - return; - } - storeBuffer(state->e); - if (state->seen_offset != 0) { - state->seen_offset = state->seen_offset + size; - } else { - int hdr_sz; - if (!state->oe->mem_obj->reply) - goto invalid_marker_obj; - if (!strLen(state->oe->mem_obj->reply->content_type)) - goto invalid_marker_obj; - if (strCmp(state->oe->mem_obj->reply->content_type, "x-squid-internal/vary") != 0) { - invalid_marker_obj: - debug(11, 2) ("storeAddVaryReadOld: %p (%s) is not a Vary maker object, ignoring\n", data, storeUrl(state->oe)); - cbdataFree(state); - return; - } - hdr_sz = state->oe->mem_obj->reply->hdr_sz; - state->seen_offset = hdr_sz; - if (l >= hdr_sz) { - state->seen_offset = l; - l -= hdr_sz; - p += hdr_sz; - } else { - l = 0; - state->seen_offset = hdr_sz; - } - } - while (l && (e = memchr(p, '\n', l)) != NULL) { - int l2; - char *p2; - if (strmatchbeg(p, "Key: ", l) == 0) { - /* key field */ - p2 = p + 5; - l2 = e - p2; - if (state->current.this_key) { - storeAddVaryFlush(state); - } - safe_free(state->current.key); - safe_free(state->current.etag); - safe_free(state->current.accept_encoding); - memset(&state->current, 0, sizeof(state->current)); - state->current.key = xmalloc(l2 + 1); - memcpy(state->current.key, p2, l2); - state->current.key[l2] = '\0'; - if (state->key) { - if (strcmp(state->current.key, state->key) == 0) - state->current.this_key = 1; - } - debug(11, 3) ("storeAddVaryReadOld: Key: %s%s\n", state->current.key, state->current.this_key ? " (THIS)" : ""); -#if 0 /* This condition is not correct here.. current.key is always null */ - } else if (!state->current.key) { - debug(11, 1) ("storeAddVaryReadOld: Unexpected data '%s'\n", p); #endif - } else if (strmatchbeg(p, "ETag: ", l) == 0) { - /* etag field */ - p2 = p + 6; - l2 = e - p2; - safe_free(state->current.etag); - state->current.etag = xmalloc(l2 + 1); - memcpy(state->current.etag, p2, l2); - state->current.etag[l2] = '\0'; - if (state->etag && strcmp(state->current.etag, state->etag) == 0) { - if (state->accept_encoding && strcmpnull(state->accept_encoding, state->current.accept_encoding) != 0) { - /* Skip this match. It's not ours */ - } else if (!state->key) { - state->current.this_key = 1; - } else if (!state->current.this_key) { - /* XXX This could use a bit of protection from corrupted entries where Key had not been seen before ETag.. */ - const cache_key *oldkey = storeKeyScan(state->current.key); - StoreEntry *old_e = storeGet(oldkey); - if (old_e) - storeRelease(old_e); - if (!state->done) { - safe_free(state->current.key); - state->current.key = xstrdup(state->key); - state->current.this_key = 1; - } else { - state->current.ignore = 1; - } - } - } else if (state->current.this_key) { - state->current.ignore = 1; - } - debug(11, 2) ("storeAddVaryReadOld: ETag: %s%s%s\n", state->current.etag, state->current.this_key ? " (THIS)" : "", state->current.ignore ? " (IGNORE)" : ""); - } else if (!state->current.ignore && strmatchbeg(p, "VaryData: ", l) == 0) { - /* vary field */ - p2 = p + 10; - l2 = e - p2; - storeAddVaryFlush(state); - if (strmatch(p2, state->vary_headers, l2) != 0) { - storeAppend(state->e, p, e - p + 1); - debug(11, 3) ("storeAddVaryReadOld: %s\n", p); - } - } else if (strmatchbeg(p, "Accept-Encoding: ", l) == 0) { - p2 = p + 17; - l2 = e - p2; - safe_free(state->current.accept_encoding); - state->current.accept_encoding = xmalloc(l2 + 1); - memcpy(state->current.accept_encoding, p2, l2); - state->current.accept_encoding[l2] = '\0'; - } - e += 1; - l -= e - p; - p = e; - if (l == 0) - break; - assert(p <= (buf + size)); - } - state->buf_offset = l; - if (l && p != state->buf) - memmove(state->buf, p, l); - if (state->buf_offset == state->buf_size) { - /* Oops.. the buffer size is not sufficient. Grow */ - if (state->buf_size < 65536) { - debug(11, 2) ("storeAddVaryReadOld: Increasing entry buffer size to %d\n", (int) state->buf_size * 2); - state->buf = memReallocBuf(state->buf, state->buf_size * 2, &state->buf_size); - } else { - /* This does not look good. Bail out. This should match the size <= 0 case above */ - debug(11, 1) ("storeAddVaryReadOld: Buffer very large and still can't fit the data.. bailing out\n"); - cbdataFree(state); - return; - } - } - debug(11, 3) ("storeAddVaryReadOld: %p seen_offset=%" PRINTF_OFF_T " buf_offset=%d\n", data, state->seen_offset, (int) state->buf_offset); - storeBufferFlush(state->e); - storeClientCopy(state->sc, state->oe, - state->seen_offset, - state->seen_offset, - state->buf_size - state->buf_offset, - state->buf + state->buf_offset, - storeAddVaryReadOld, - state); -} - -/* - * Adds/updates a Vary record. - * For updates only one of key or etag needs to be specified - * At leas one of key or etag must be specified, preferably both. - */ -void -storeAddVary(const char *url, const method_t method, const cache_key * key, const char *etag, const char *vary, const char *vary_headers, const char *accept_encoding) -{ - AddVaryState *state; - http_version_t version; - request_flags flags = null_request_flags; - CBDATA_INIT_TYPE_FREECB(AddVaryState, free_AddVaryState); - state = cbdataAlloc(AddVaryState); - state->url = xstrdup(url); - if (key) - state->key = xstrdup(storeKeyText(key)); - state->vary_headers = xstrdup(vary_headers); - if (accept_encoding) - state->accept_encoding = xstrdup(accept_encoding); - if (etag) - state->etag = xstrdup(etag); - state->oe = storeGetPublic(url, method); - debug(11, 2) ("storeAddVary: %s (%s) %s %s\n", - state->url, state->key, state->vary_headers, state->etag); - if (state->oe) - storeLockObject(state->oe); - flags.cachable = 1; - state->e = storeCreateEntry(url, flags, method); - httpBuildVersion(&version, 1, 0); - httpReplySetHeaders(state->e->mem_obj->reply, version, HTTP_OK, "Internal marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000); - httpHeaderPutStr(&state->e->mem_obj->reply->header, HDR_VARY, vary); - storeSetPublicKey(state->e); - storeBuffer(state->e); - httpReplySwapOut(state->e->mem_obj->reply, state->e); - if (state->oe) { - /* Here we need to tack on the old etag/vary information, and we should - * merge, clean up etc - * - * Suggestion: - * swap in the old file, looking for ETag, Key and VaryData. If a match is - * found then - * - on ETag, update the key, and expire the old object if different - * - on Key, drop the old data if ETag is different, else nothing - * - on VaryData, remove the line if a different key. If this makes - * the searched key "empty" then expire it and remove it from the - * map - * - VaryData is added last in the Key record it corresponds to (after - * modifications above) - */ - /* Swap in the dummy Vary object */ - if (!state->oe->mem_obj) { - storeCreateMemObject(state->oe, state->url); - state->oe->mem_obj->method = method; - } - state->sc = storeClientRegister(state->oe, state); - state->buf = memAllocBuf(4096, &state->buf_size); - debug(11, 3) ("storeAddVary: %p\n", state); - storeClientCopy(state->sc, state->oe, 0, 0, - state->buf_size, - state->buf, - storeAddVaryReadOld, - state); - return; - } else { - cbdataFree(state); - } -} - -static MemPool *VaryData_pool = NULL; - -void -storeLocateVaryDone(VaryData * data) -{ - int i; - safe_free(data->key); - data->etag = NULL; /* points to an entry in etags */ - for (i = 0; i < data->etags.count; i++) { - safe_free(data->etags.items[i]); - } - arrayClean(&data->etags); - memPoolFree(VaryData_pool, data); -} - -typedef struct { - VaryData *data; - STLVCB *callback; - void *callback_data; - StoreEntry *e; - store_client *sc; - char *buf; - size_t buf_size; - size_t buf_offset; - char *vary_data; - char *accept_encoding; - squid_off_t seen_offset; - struct { - int ignore; - int encoding_ok; - char *key; - char *etag; - } current; -} LocateVaryState; - -CBDATA_TYPE(LocateVaryState); - -static void -storeLocateVaryCallback(LocateVaryState * state) -{ - if (cbdataValid(state->callback_data)) { - VaryData *data = state->data; - if (data->key || data->etags.count) { - state->callback(data, state->callback_data); - state->data = NULL; /* now owned by the caller */ - } else { - state->callback(NULL, state->callback_data); - } - } - cbdataUnlock(state->callback_data); - if (state->data) { - storeLocateVaryDone(state->data); - state->data = NULL; - } - state->current.etag = NULL; /* shared by data->entries[x] */ - safe_free(state->vary_data); - safe_free(state->accept_encoding); - safe_free(state->current.key); - if (state->sc) { - storeClientUnregister(state->sc, state->e, state); - state->sc = NULL; - } - if (state->e) { - storeUnlockObject(state->e); - state->e = NULL; - } - if (state->buf) { - memFreeBuf(state->buf_size, state->buf); - state->buf = NULL; - } - cbdataFree(state); - debug(11, 2) ("storeLocateVary: DONE\n"); -} - -static void -storeLocateVaryRead(void *data, char *buf, ssize_t size) -{ - LocateVaryState *state = data; - char *e; - char *p = state->buf; - size_t l = size + state->buf_offset; - debug(11, 3) ("storeLocateVaryRead: %s %p seen_offset=%" PRINTF_OFF_T " buf_offset=%d size=%d\n", state->vary_data, data, state->seen_offset, (int) state->buf_offset, (int) size); - if (size <= 0) { - storeLocateVaryCallback(state); - return; - } - state->seen_offset = state->seen_offset + size; - while ((e = memchr(p, '\n', l)) != NULL) { - int l2; - char *p2; - if (strmatchbeg(p, "Key: ", l) == 0) { - /* key field */ - p2 = p + 5; - l2 = e - p2; - safe_free(state->current.key); - state->current.etag = NULL; /* saved in data.etags[] */ - state->current.ignore = 0; - state->current.encoding_ok = !state->accept_encoding; - state->current.key = xmalloc(l2 + 1); - memcpy(state->current.key, p2, l2); - state->current.key[l2] = '\0'; - debug(11, 3) ("storeLocateVaryRead: Key: %s\n", state->current.key); - } else if (state->current.ignore) { - /* Skip this entry */ - } else if (!state->current.key) { - char *t1 = xstrndup(p, e - p); - char *t2 = xstrndup(state->buf, size + state->buf_offset); - debug(11, 1) ("storeLocateVaryRead: Unexpected data '%s' in '%s'", t1, t2); - safe_free(t2); - safe_free(t1); - } else if (strmatchbeg(p, "ETag: ", l) == 0) { - /* etag field */ - char *etag; - if (state->current.encoding_ok) { - p2 = p + 6; - l2 = e - p2; - etag = xmalloc(l2 + 1); - memcpy(etag, p2, l2); - etag[l2] = '\0'; - state->current.etag = etag; - arrayAppend(&state->data->etags, etag); - debug(11, 3) ("storeLocateVaryRead: ETag: %s\n", etag); - } else { - state->current.ignore = 1; - } - } else if (strmatchbeg(p, "VaryData: ", l) == 0) { - /* vary field */ - p2 = p + 10; - l2 = e - p2; - if (strmatch(p2, state->vary_data, l2) == 0) { - /* A matching vary header found */ - safe_free(state->data->key); - state->data->key = xstrdup(state->current.key); - state->data->etag = state->current.etag; - debug(11, 2) ("storeLocateVaryRead: MATCH! %s %s\n", state->current.key, state->current.etag); - } - } else if (strmatchbeg(p, "Accept-Encoding: ", l) == 0) { - p2 = p + 17; - l2 = e - p2; - if (strncmpnull(state->accept_encoding, p2, l2) == 0 && state->accept_encoding[l2] == '\0') { - state->current.encoding_ok = 1; - } - } - e += 1; - l -= e - p; - p = e; - if (l == 0) - break; - assert(l > 0); - assert(p < (buf + size)); - } - state->buf_offset = l; - if (l) - memmove(state->buf, p, l); - if (state->buf_offset == state->buf_size) { - /* Oops.. the buffer size is not sufficient. Grow */ - if (state->buf_size < 65536) { - debug(11, 2) ("storeLocateVaryRead: Increasing entry buffer size to %d\n", (int) state->buf_size * 2); - state->buf = memReallocBuf(state->buf, state->buf_size * 2, &state->buf_size); - } else { - /* This does not look good. Bail out. This should match the size <= 0 case above */ - debug(11, 1) ("storeLocateVaryRead: Buffer very large and still can't fit the data.. bailing out\n"); - storeLocateVaryCallback(state); - return; - } - } - debug(11, 3) ("storeLocateVaryRead: %p seen_offset=%" PRINTF_OFF_T " buf_offset=%d\n", data, state->seen_offset, (int) state->buf_offset); - storeClientCopy(state->sc, state->e, - state->seen_offset, - state->seen_offset, - state->buf_size - state->buf_offset, - state->buf + state->buf_offset, - storeLocateVaryRead, - state); -} - -void -storeLocateVary(StoreEntry * e, int offset, const char *vary_data, String accept_encoding, STLVCB * callback, void *cbdata) -{ - LocateVaryState *state; - debug(11, 2) ("storeLocateVary: %s\n", vary_data); - CBDATA_INIT_TYPE(LocateVaryState); - if (!VaryData_pool) - VaryData_pool = memPoolCreate("VaryData", sizeof(VaryData)); - state = cbdataAlloc(LocateVaryState); - state->vary_data = xstrdup(vary_data); - if (strBuf(accept_encoding)) - state->accept_encoding = xstrdup(strBuf(accept_encoding)); - state->data = memPoolAlloc(VaryData_pool); - state->e = e; - storeLockObject(state->e); - state->callback_data = cbdata; - cbdataLock(cbdata); - state->callback = callback; - state->buf = memAllocBuf(4096, &state->buf_size); - state->sc = storeClientRegister(state->e, state); - state->seen_offset = offset; - if (strCmp(e->mem_obj->reply->content_type, "x-squid-internal/vary") != 0) { - /* This is not our Vary marker object. Bail out. */ - debug(33, 1) ("storeLocateVary: Not our vary marker object, %s = '%s', '%s'/'%s'\n", - storeKeyText(e->hash.key), e->mem_obj->url, vary_data, strBuf(accept_encoding) ? strBuf(accept_encoding) : "-"); - storeLocateVaryCallback(state); - return; - } - storeClientCopy(state->sc, state->e, - state->seen_offset, - state->seen_offset, - state->buf_size, - state->buf, - storeLocateVaryRead, - state); -} void storeSetPublicKey(StoreEntry * e) @@ -1003,48 +467,7 @@ #endif assert(!EBIT_TEST(e->flags, RELEASE_REQUEST)); if (mem->request) { - StoreEntry *pe; - request_t *request = mem->request; - if (!mem->vary_headers) { - /* First handle the case where the object no longer varies */ - safe_free(request->vary_headers); - } else { - if (request->vary_headers && strcmp(request->vary_headers, mem->vary_headers) != 0) { - /* Oops.. the variance has changed. Kill the base object - * to record the new variance key - */ - safe_free(request->vary_headers); /* free old "bad" variance key */ - pe = storeGetPublic(mem->url, mem->method); - if (pe) - storeRelease(pe); - } - /* Make sure the request knows the variance status */ - else if (!request->vary_headers) { - if (!httpMakeVaryMark(request, mem->reply)) { - /* Release the object if we could not index the variance */ - storeReleaseRequest(e); - return; - } - } - } newkey = storeKeyPublicByRequest(mem->request); - if (mem->vary_headers && !EBIT_TEST(e->flags, KEY_EARLY_PUBLIC)) { - String vary = StringNull; - String varyhdr; - varyhdr = httpHeaderGetList(&mem->reply->header, HDR_VARY); - if (strBuf(varyhdr)) - strListAdd(&vary, strBuf(varyhdr), ','); - stringClean(&varyhdr); -#if X_ACCELERATOR_VARY - /* This needs to match the order in http.c:httpMakeVaryMark */ - varyhdr = httpHeaderGetList(&mem->reply->header, HDR_X_ACCELERATOR_VARY); - if (strBuf(varyhdr)) - strListAdd(&vary, strBuf(varyhdr), ','); - stringClean(&varyhdr); -#endif - storeAddVary(mem->url, mem->method, newkey, httpHeaderGetStr(&mem->reply->header, HDR_ETAG), strBuf(vary), mem->vary_headers, mem->vary_encoding); - stringClean(&vary); - } } else { newkey = storeKeyPublic(mem->url, mem->method); }