]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Support for Cache-Control: proxy-revalidate. From squid-1.1.x patch by
authorwessels <>
Thu, 3 Jul 1997 04:42:54 +0000 (04:42 +0000)
committerwessels <>
Thu, 3 Jul 1997 04:42:54 +0000 (04:42 +0000)
Mike Mitchell <mcm@unx.sas.com>

src/client_side.cc
src/http.cc
src/refresh.cc
src/store.cc
src/store_dir.cc

index 53521583c77afafedf8c60df20aa815baf70f2bc..2eca05712a7ec266b63e42d155a1344f88b8d6bc 100644 (file)
@@ -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);
index f21b77f545482b53eb27e7b48603ba5efd7947ff..dbc869bcd372e9e6c8db6c8843e46689abeaaf18 100644 (file)
@@ -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);
     }
 }
 
index 42194cb1c3bd5b03b6d8c934e573f799cdbd39b5..4e0b94e216d799c69431b9afdf5bfdf787a6d25a 100644 (file)
@@ -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;
index 7aa262fcca69a0bc0a61f1f1571b057af523eec0..9d8af833a48455e0afd0788f286d0cf4f6a9a83d 100644 (file)
@@ -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;
index 0c538ea006424db054f02c1a6e20d8e229e5316e..c0ca4402a27a2b8bcfb05956d30ede7c298ce9bb 100644 (file)
@@ -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),