/*
- * $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
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);
/*
- * $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
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)
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) {
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);
}
}
/*
- * $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
time_t,
time_t,
time_t,
+ u_num32,
+ u_num32,
int));
static StoreEntry *storeGetInMemFirst _PARAMS((void));
static StoreEntry *storeGetInMemNext _PARAMS((void));
/* 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;
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);
int scan2;
int scan3;
int scan4;
+ int scan5;
+ int scan6;
off_t size;
int sfileno = 0;
int count;
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;
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 */
expires,
timestamp,
lastmod,
+ (u_num32) scan5, /* refcount */
+ (u_num32) scan6, /* flags */
d->clean);
storeDirSwapLog(e);
HTTPCacheInfo->proto_newobject(HTTPCacheInfo,
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;