From: wessels <> Date: Thu, 3 Jul 1997 04:42:54 +0000 (+0000) Subject: Support for Cache-Control: proxy-revalidate. From squid-1.1.x patch by X-Git-Tag: SQUID_3_0_PRE1~4907 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c54e905272ddb8b18d3206b47f126406b6ad6f0d;p=thirdparty%2Fsquid.git Support for Cache-Control: proxy-revalidate. From squid-1.1.x patch by Mike Mitchell --- diff --git a/src/client_side.cc b/src/client_side.cc index 53521583c7..2eca05712a 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.114 1997/06/26 22:41:40 wessels Exp $ + * $Id: client_side.cc,v 1.115 1997/07/02 22:42:54 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -402,13 +402,20 @@ icpHandleIMSReply(void *data, char *buf, ssize_t size) if (entry->store_status == STORE_ABORTED) { debug(33, 3) ("icpHandleIMSReply: ABORTED/%s '%s'\n", log_tags[entry->mem_obj->abort_code], entry->url); - /* We have an existing entry, but failed to validate it, - * so send the old one anyway */ - http->log_type = LOG_TCP_REFRESH_FAIL_HIT; - storeUnregister(entry, http); - storeUnlockObject(entry); - entry = http->entry = http->old_entry; - entry->refcount++; + /* We have an existing entry, but failed to validate it */ + if (BIT_SET(entry->flag, ENTRY_REVALIDATE)) { + /* We can't send the old one, so send the abort message */ + http->log_type = LOG_TCP_REFRESH_MISS; + storeUnregister(http->old_entry, http); + storeUnlockObject(http->old_entry); + } else { + /* Its okay to send the old one anyway */ + http->log_type = entry->mem_obj->abort_code; + storeUnregister(entry, http); + storeUnlockObject(entry); + entry = http->entry = http->old_entry; + entry->refcount++; + } } else if (mem->reply->code == 0) { debug(33, 3) ("icpHandleIMSReply: Incomplete headers for '%s'\n", entry->url); diff --git a/src/http.cc b/src/http.cc index f21b77f545..dbc869bcd3 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,5 +1,5 @@ /* - * $Id: http.cc,v 1.175 1997/06/26 22:35:49 wessels Exp $ + * $Id: http.cc,v 1.176 1997/07/02 22:42:55 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -402,6 +402,92 @@ httpParseReplyHeaders(const char *buf, struct _http_reply *reply) put_free_4k_page(line); } +/* httpCheckPublic + * + * Return 1 if the entry can be made public + * 0 if the entry must be made private + * -1 if the entry should be negatively cached + */ +int +httpCheckPublic(struct _http_reply *reply, HttpStateData * httpState) +{ + request_t *request = httpState->request; + switch (reply->code) { + /* Responses that are cacheable */ + case 200: /* OK */ + case 203: /* Non-Authoritative Information */ + case 300: /* Multiple Choices */ + case 301: /* Moved Permanently */ + case 410: /* Gone */ + /* don't cache objects from neighbors w/o LMT, Date, or Expires */ + if (EBIT_TEST(reply->cache_control, SCC_PRIVATE)) + return 0; + if (EBIT_TEST(reply->cache_control, SCC_NOCACHE)) + return 0; + if (BIT_TEST(request->flags, REQ_AUTH)) + if (!EBIT_TEST(reply->cache_control, SCC_PROXYREVALIDATE)) + return 0; + /* + * Dealing with cookies is quite a bit more complicated + * than this. Ideally we should strip the cookie + * header from the reply but still cache the reply body. + * More confusion at draft-ietf-http-state-mgmt-05.txt. + */ + if (EBIT_TEST(reply->misc_headers, HDR_SET_COOKIE)) + return 0; + if (reply->date > -1) + return 1; + if (reply->last_modified > -1) + return 1; + if (!httpState->neighbor) + return 1; + if (reply->expires > -1) + return 1; +#ifdef OLD_CODE + if (entry->mem_obj->request->protocol != PROTO_HTTP) + /* XXX Remove this check after a while. DW 8/21/96 + * We won't keep some FTP objects from neighbors running + * 1.0.8 or earlier because their ftpget's don't + * add a Date: field */ + return 1; +#endif + else + return 0; + break; + /* Responses that only are cacheable if the server says so */ + case 302: /* Moved temporarily */ + if (reply->expires > -1) + return 1; + else + return 0; + break; + /* Errors can be negatively cached */ + case 204: /* No Content */ + case 305: /* Use Proxy (proxy redirect) */ + case 400: /* Bad Request */ + case 403: /* Forbidden */ + case 404: /* Not Found */ + case 405: /* Method Now Allowed */ + case 414: /* Request-URI Too Long */ + case 500: /* Internal Server Error */ + case 501: /* Not Implemented */ + case 502: /* Bad Gateway */ + case 503: /* Service Unavailable */ + case 504: /* Gateway Timeout */ + return -1; + break; + /* Some responses can never be cached */ + case 303: /* See Other */ + case 304: /* Not Modified */ + case 401: /* Unauthorized */ + case 407: /* Proxy Authentication Required */ + case 600: /* Squid header parsing error */ + default: /* Unknown status code */ + return 0; + break; + } + assert(0); +} void httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size) @@ -411,9 +497,7 @@ httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size) int room; int hdr_len; struct _http_reply *reply = entry->mem_obj->reply; - debug(11, 3) ("httpProcessReplyHeader: key '%s'\n", entry->key); - if (httpState->reply_hdr == NULL) httpState->reply_hdr = get_free_8k_page(); if (httpState->reply_hdr_state == 0) { @@ -444,75 +528,22 @@ httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size) storeTimestampsSet(entry); /* Check if object is cacheable or not based on reply code */ debug(11, 3) ("httpProcessReplyHeader: HTTP CODE: %d\n", reply->code); - switch (reply->code) { - /* Responses that are cacheable */ - case 200: /* OK */ - case 203: /* Non-Authoritative Information */ - case 300: /* Multiple Choices */ - case 301: /* Moved Permanently */ - case 410: /* Gone */ - /* don't cache objects from neighbors w/o LMT, Date, or Expires */ - if (EBIT_TEST(reply->cache_control, SCC_PRIVATE)) - httpMakePrivate(entry); - else if (EBIT_TEST(reply->cache_control, SCC_NOCACHE)) - httpMakePrivate(entry); - /* - * Dealing with cookies is quite a bit more complicated - * than this. Ideally we should strip the cookie - * header from the reply but still cache the reply body. - * More confusion at draft-ietf-http-state-mgmt-05.txt. - */ - else if (EBIT_TEST(reply->misc_headers, HDR_SET_COOKIE)) - httpMakePrivate(entry); - else if (reply->date > -1) - httpMakePublic(entry); - else if (reply->last_modified > -1) - httpMakePublic(entry); - else if (!httpState->neighbor) - httpMakePublic(entry); - else if (reply->expires > -1) - httpMakePublic(entry); - else if (entry->mem_obj->request->protocol != PROTO_HTTP) - /* XXX Remove this check after a while. DW 8/21/96 - * We won't keep some FTP objects from neighbors running - * 1.0.8 or earlier because their ftpget's don't - * add a Date: field */ - httpMakePublic(entry); - else - httpMakePrivate(entry); + switch (httpCheckPublic(reply, httpState)) { + case 1: + httpMakePublic(entry); break; - /* Responses that only are cacheable if the server says so */ - case 302: /* Moved temporarily */ - if (reply->expires > -1) - httpMakePublic(entry); - else - httpMakePrivate(entry); + case 0: + httpMakePrivate(entry); break; - /* Errors can be negatively cached */ - case 204: /* No Content */ - case 305: /* Use Proxy (proxy redirect) */ - case 400: /* Bad Request */ - case 403: /* Forbidden */ - case 404: /* Not Found */ - case 405: /* Method Now Allowed */ - case 414: /* Request-URI Too Long */ - case 500: /* Internal Server Error */ - case 501: /* Not Implemented */ - case 502: /* Bad Gateway */ - case 503: /* Service Unavailable */ - case 504: /* Gateway Timeout */ + case -1: httpCacheNegatively(entry); break; - /* Some responses can never be cached */ - case 303: /* See Other */ - case 304: /* Not Modified */ - case 401: /* Unauthorized */ - case 407: /* Proxy Authentication Required */ - case 600: /* Squid header parsing error */ - default: /* Unknown status code */ - httpMakePrivate(entry); + default: + assert(0); break; } + if (EBIT_TEST(reply->cache_control, SCC_PROXYREVALIDATE)) + BIT_SET(entry->flag, ENTRY_REVALIDATE); } } diff --git a/src/refresh.cc b/src/refresh.cc index 42194cb1c3..4e0b94e216 100644 --- a/src/refresh.cc +++ b/src/refresh.cc @@ -1,6 +1,6 @@ /* - * $Id: refresh.cc,v 1.12 1997/06/04 06:16:08 wessels Exp $ + * $Id: refresh.cc,v 1.13 1997/07/02 22:42:57 wessels Exp $ * * DEBUG: section 22 Refresh Calculation * AUTHOR: Harvest Derived @@ -127,6 +127,10 @@ refreshCheck(const StoreEntry * entry, const request_t * request, time_t delta) int factor; time_t check_time = squid_curtime + delta; debug(22, 3) ("refreshCheck: '%s'\n", entry->url); + if (BIT_TEST(entry->flag, ENTRY_REVALIDATE)) { + debug(22, 3)("refreshCheck: YES: Required Authorization\n"); + return 1; + } for (R = Refresh_tbl; R; R = R->next) { if (regexec(&(R->compiled_pattern), entry->url, 0, 0, 0) != 0) continue; diff --git a/src/store.cc b/src/store.cc index 7aa262fcca..9d8af833a4 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.263 1997/06/26 22:36:00 wessels Exp $ + * $Id: store.cc,v 1.264 1997/07/02 22:42:58 wessels Exp $ * * DEBUG: section 20 Storeage Manager * AUTHOR: Harvest Derived @@ -273,6 +273,8 @@ static StoreEntry *storeAddDiskRestore _PARAMS((const char *, time_t, time_t, time_t, + u_num32, + u_num32, int)); static StoreEntry *storeGetInMemFirst _PARAMS((void)); static StoreEntry *storeGetInMemNext _PARAMS((void)); @@ -778,7 +780,7 @@ storeCreateEntry(const char *url, int flags, method_t method) /* Add a new object to the cache with empty memory copy and pointer to disk * use to rebuild store from disk. */ static StoreEntry * -storeAddDiskRestore(const char *url, int file_number, int size, time_t expires, time_t timestamp, time_t lastmod, int clean) +storeAddDiskRestore(const char *url, int file_number, int size, time_t expires, time_t timestamp, time_t lastmod, u_num32 refcount, u_num32 flags, int clean) { StoreEntry *e = NULL; @@ -808,6 +810,8 @@ storeAddDiskRestore(const char *url, int file_number, int size, time_t expires, e->timestamp = timestamp; e->expires = expires; e->lastmod = lastmod; + e->refcount = refcount; + e->flag = flags; e->ping_status = PING_NONE; if (clean) { BIT_SET(e->flag, ENTRY_VALIDATED); @@ -1300,6 +1304,8 @@ storeDoRebuildFromDisk(void *data) int scan2; int scan3; int scan4; + int scan5; + int scan6; off_t size; int sfileno = 0; int count; @@ -1340,17 +1346,19 @@ storeDoRebuildFromDisk(void *data) scan2 = 0; scan3 = 0; scan4 = 0; - x = sscanf(RB->line_in, "%x %x %x %x %d %s", + x = sscanf(RB->line_in, "%x %x %x %x %d %d %x %s", &sfileno, /* swap_file_number */ &scan1, /* timestamp */ &scan2, /* expires */ &scan3, /* last modified */ &scan4, /* size */ + &scan5, /* refcount */ + &scan6, /* flags */ url); /* url */ if (x < 1) continue; storeSwapFullPath(sfileno, swapfile); - if (x != 6) + if (x != 8) continue; if (sfileno < 0) continue; @@ -1379,6 +1387,8 @@ storeDoRebuildFromDisk(void *data) e->timestamp = timestamp; e->expires = expires; e->lastmod = lastmod; + e->flag |= (u_num32) scan5; + e->refcount += (u_num32) scan6; continue; } else if (used) { /* swapfile in use, not by this URL, log entry is newer */ @@ -1419,6 +1429,8 @@ storeDoRebuildFromDisk(void *data) expires, timestamp, lastmod, + (u_num32) scan5, /* refcount */ + (u_num32) scan6, /* flags */ d->clean); storeDirSwapLog(e); HTTPCacheInfo->proto_newobject(HTTPCacheInfo, @@ -1672,6 +1684,7 @@ storeAbort(StoreEntry * e, log_type abort_code, const char *msg, int cbflag) if (msg) mem->e_abort_msg = xstrdup(msg); debug(20, 6) ("storeAbort: %s %s\n", log_tags[abort_code], e->key); + mem->abort_code = abort_code; storeNegativeCache(e); storeReleaseRequest(e); e->store_status = STORE_ABORTED; diff --git a/src/store_dir.cc b/src/store_dir.cc index 0c538ea006..c0ca4402a2 100644 --- a/src/store_dir.cc +++ b/src/store_dir.cc @@ -242,12 +242,14 @@ storeDirSwapLog(const StoreEntry * e) dirn = e->swap_file_number >> SWAP_DIR_SHIFT; assert(dirn < ncache_dirs); /* Note this printf format appears in storeWriteCleanLog() too */ - sprintf(logmsg, "%08x %08x %08x %08x %9d %s\n", + sprintf(logmsg, "%08x %08x %08x %08x %9d %6d %08x %s\n", (int) e->swap_file_number, (int) e->timestamp, (int) e->expires, (int) e->lastmod, e->object_len, + e->refcount, + e->flag, e->url); file_write(SwapDirs[dirn].swaplog_fd, xstrdup(logmsg),