httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r1021946 - /httpd/httpd/trunk/modules/cache/mod_cache.c
Date Tue, 12 Oct 2010 22:54:06 GMT
Author: minfrin
Date: Tue Oct 12 22:54:06 2010
New Revision: 1021946

URL: http://svn.apache.org/viewvc?rev=1021946&view=rev
Log:
mod_cache: Support stale-on-error behaviour for the mod_proxy case in
addition to the existing case where the error was generated by ourselves.

Modified:
    httpd/httpd/trunk/modules/cache/mod_cache.c

Modified: httpd/httpd/trunk/modules/cache/mod_cache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_cache.c?rev=1021946&r1=1021945&r2=1021946&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache.c Tue Oct 12 22:54:06 2010
@@ -779,6 +779,61 @@ static int cache_save_filter(ap_filter_t
 
     dconf = ap_get_module_config(r->per_dir_config, &cache_module);
 
+    /* RFC2616 13.8 Errors or Incomplete Response Cache Behavior:
+     * If a cache receives a 5xx response while attempting to revalidate an
+     * entry, it MAY either forward this response to the requesting client,
+     * or act as if the server failed to respond. In the latter case, it MAY
+     * return a previously received response unless the cached entry
+     * includes the "must-revalidate" cache-control directive (see section
+     * 14.9).
+     *
+     * This covers the case where an error was generated behind us, for example
+     * by a backend server via mod_proxy.
+     */
+    if (dconf->stale_on_error && r->status >= HTTP_INTERNAL_SERVER_ERROR)
{
+
+        ap_remove_output_filter(cache->remove_url_filter);
+
+        if (cache->stale_handle && !ap_cache_liststr(
+                NULL,
+                apr_table_get(cache->stale_handle->resp_hdrs, "Cache-Control"),
+                "must-revalidate", NULL)) {
+            const char *warn_head;
+
+            /* morph the current save filter into the out filter, and serve from
+             * cache.
+             */
+            cache->handle = cache->stale_handle;
+            if (r->main) {
+                f->frec = cache_out_subreq_filter_handle;
+            }
+            else {
+                f->frec = cache_out_filter_handle;
+            }
+
+            r->headers_out = cache->stale_handle->resp_hdrs;
+
+            /* add a stale warning */
+            warn_head = apr_table_get(r->err_headers_out, "Warning");
+            if ((warn_head == NULL) || ((warn_head != NULL)
+                    && (ap_strstr_c(warn_head, "110") == NULL))) {
+                apr_table_mergen(r->err_headers_out, "Warning",
+                        "110 Response is stale");
+            }
+
+            cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_HIT,
+                    apr_psprintf(r->pool,
+                            "cache hit: %d status; stale content returned",
+                            r->status));
+
+            /* give someone else the chance to cache the file */
+            cache_remove_lock(conf, cache, f->r, NULL);
+
+            /* pass brigade to our morphed out filter */
+            return ap_pass_brigade(f, in);
+        }
+    }
+
     /* read expiry date; if a bad date, then leave it so the client can
      * read it
      */
@@ -1534,6 +1589,9 @@ static void cache_insert_error_filter(re
      * return a previously received response unless the cached entry
      * includes the "must-revalidate" cache-control directive (see section
      * 14.9).
+     *
+     * This covers the case where the error was generated by our server via
+     * ap_die().
      */
     apr_pool_userdata_get(&dummy, CACHE_CTX_KEY, r->pool);
     if (dummy) {



Mime
View raw message