You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2013/05/06 00:27:32 UTC

svn commit: r1479411 - in /httpd/httpd/trunk: CHANGES modules/cache/mod_cache.c modules/cache/mod_cache_disk.c modules/cache/mod_cache_socache.c

Author: minfrin
Date: Sun May  5 22:27:31 2013
New Revision: 1479411

URL: http://svn.apache.org/r1479411
Log:
mod_cache: Ensure that updated responses to HEAD requests don't get
mistakenly paired with a previously cached body. Ensure that any existing
body is removed when a HEAD request is cached.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/modules/cache/mod_cache.c
    httpd/httpd/trunk/modules/cache/mod_cache_disk.c
    httpd/httpd/trunk/modules/cache/mod_cache_socache.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1479411&r1=1479410&r2=1479411&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sun May  5 22:27:31 2013
@@ -1,6 +1,11 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_cache: Ensure that updated responses to HEAD requests don't get
+     mistakenly paired with a previously cached body. Ensure that any existing
+     body is removed when a HEAD request is cached. [Graham Leggett,
+     Co-Advisor <coad measurement-factory.com>]
+
   *) mod_cache: Honour Cache-Control: no-store in a request. [Graham Leggett]
 
   *) mod_cache: RFC2616 14.9.3 The s-maxage directive also implies the

Modified: httpd/httpd/trunk/modules/cache/mod_cache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_cache.c?rev=1479411&r1=1479410&r2=1479411&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache.c Sun May  5 22:27:31 2013
@@ -1435,9 +1435,6 @@ static apr_status_t cache_save_filter(ap
 
     /* We found a stale entry which wasn't really stale. */
     if (cache->stale_handle) {
-        /* Load in the saved status and clear the status line. */
-        r->status = info->status;
-        r->status_line = NULL;
 
         /* RFC 2616 10.3.5 states that entity headers are not supposed
          * to be in the 304 response.  Therefore, we need to combine the
@@ -1476,6 +1473,10 @@ static apr_status_t cache_save_filter(ap
         apr_bucket *bkt;
         int status;
 
+        /* Load in the saved status and clear the status line. */
+        r->status = info->status;
+        r->status_line = NULL;
+
         /* We're just saving response headers, so we are done. Commit
          * the response at this point, unless there was a previous error.
          */

Modified: httpd/httpd/trunk/modules/cache/mod_cache_disk.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_cache_disk.c?rev=1479411&r1=1479410&r2=1479411&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache_disk.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache_disk.c Sun May  5 22:27:31 2013
@@ -942,6 +942,10 @@ static apr_status_t store_headers(cache_
         dobj->headers_in = ap_cache_cacheable_headers_in(r);
     }
 
+    if (r->header_only && r->status != HTTP_NOT_MODIFIED) {
+        dobj->disk_info.header_only = 1;
+    }
+
     return APR_SUCCESS;
 }
 
@@ -1190,49 +1194,51 @@ static apr_status_t store_body(cache_han
             continue;
         }
 
-        /* Attempt to create the data file at the last possible moment, if
-         * the body is empty, we don't write a file at all, and save an inode.
-         */
-        if (!dobj->data.tempfd) {
-            apr_finfo_t finfo;
-            rv = apr_file_mktemp(&dobj->data.tempfd, dobj->data.tempfile,
-                                 APR_CREATE | APR_WRITE | APR_BINARY |
-                                 APR_BUFFERED | APR_EXCL, dobj->data.pool);
+        if (!dobj->disk_info.header_only) {
+
+            /* Attempt to create the data file at the last possible moment, if
+             * the body is empty, we don't write a file at all, and save an inode.
+             */
+            if (!dobj->data.tempfd) {
+                apr_finfo_t finfo;
+                rv = apr_file_mktemp(&dobj->data.tempfd, dobj->data.tempfile,
+                        APR_CREATE | APR_WRITE | APR_BINARY | APR_BUFFERED
+                                | APR_EXCL, dobj->data.pool);
+                if (rv != APR_SUCCESS) {
+                    apr_pool_destroy(dobj->data.pool);
+                    return rv;
+                }
+                dobj->file_size = 0;
+                rv = apr_file_info_get(&finfo, APR_FINFO_IDENT,
+                        dobj->data.tempfd);
+                if (rv != APR_SUCCESS) {
+                    apr_pool_destroy(dobj->data.pool);
+                    return rv;
+                }
+                dobj->disk_info.device = finfo.device;
+                dobj->disk_info.inode = finfo.inode;
+                dobj->disk_info.has_body = 1;
+            }
+
+            /* write to the cache, leave if we fail */
+            rv = apr_file_write_full(dobj->data.tempfd, str, length, &written);
             if (rv != APR_SUCCESS) {
+                ap_log_rerror(
+                        APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00731) "Error when writing cache file for URL %s", h->cache_obj->key);
+                /* Remove the intermediate cache file and return non-APR_SUCCESS */
                 apr_pool_destroy(dobj->data.pool);
                 return rv;
             }
-            dobj->file_size = 0;
-            rv = apr_file_info_get(&finfo, APR_FINFO_IDENT,
-                    dobj->data.tempfd);
-            if (rv != APR_SUCCESS) {
+            dobj->file_size += written;
+            if (dobj->file_size > dconf->maxfs) {
+                ap_log_rerror(
+                        APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00732) "URL %s failed the size check "
+                        "(%" APR_OFF_T_FMT ">%" APR_OFF_T_FMT ")", h->cache_obj->key, dobj->file_size, dconf->maxfs);
+                /* Remove the intermediate cache file and return non-APR_SUCCESS */
                 apr_pool_destroy(dobj->data.pool);
-                return rv;
+                return APR_EGENERAL;
             }
-            dobj->disk_info.device = finfo.device;
-            dobj->disk_info.inode = finfo.inode;
-            dobj->disk_info.has_body = 1;
-        }
 
-        /* write to the cache, leave if we fail */
-        rv = apr_file_write_full(dobj->data.tempfd, str, length, &written);
-        if (rv != APR_SUCCESS) {
-            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00731)
-                    "Error when writing cache file for URL %s",
-                    h->cache_obj->key);
-            /* Remove the intermediate cache file and return non-APR_SUCCESS */
-            apr_pool_destroy(dobj->data.pool);
-            return rv;
-        }
-        dobj->file_size += written;
-        if (dobj->file_size > dconf->maxfs) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00732)
-                    "URL %s failed the size check "
-                    "(%" APR_OFF_T_FMT ">%" APR_OFF_T_FMT ")",
-                    h->cache_obj->key, dobj->file_size, dconf->maxfs);
-            /* Remove the intermediate cache file and return non-APR_SUCCESS */
-            apr_pool_destroy(dobj->data.pool);
-            return APR_EGENERAL;
         }
 
         /* have we reached the limit of how much we're prepared to write in one
@@ -1258,43 +1264,44 @@ static apr_status_t store_body(cache_han
     if (seen_eos) {
         const char *cl_header = apr_table_get(r->headers_out, "Content-Length");
 
-        if (dobj->data.tempfd) {
-            rv = apr_file_close(dobj->data.tempfd);
-            if (rv != APR_SUCCESS) {
-                /* Buffered write failed, abandon attempt to write */
-                apr_pool_destroy(dobj->data.pool);
-                return rv;
+        if (!dobj->disk_info.header_only) {
+
+            if (dobj->data.tempfd) {
+                rv = apr_file_close(dobj->data.tempfd);
+                if (rv != APR_SUCCESS) {
+                    /* Buffered write failed, abandon attempt to write */
+                    apr_pool_destroy(dobj->data.pool);
+                    return rv;
+                }
             }
-        }
 
-        if (r->connection->aborted || r->no_cache) {
-            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00733)
-                    "Discarding body for URL %s "
-                    "because connection has been aborted.",
-                    h->cache_obj->key);
-            /* Remove the intermediate cache file and return non-APR_SUCCESS */
-            apr_pool_destroy(dobj->data.pool);
-            return APR_EGENERAL;
-        }
-        if (dobj->file_size < dconf->minfs) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00734)
-                    "URL %s failed the size check "
-                    "(%" APR_OFF_T_FMT "<%" APR_OFF_T_FMT ")",
-                    h->cache_obj->key, dobj->file_size, dconf->minfs);
-            /* Remove the intermediate cache file and return non-APR_SUCCESS */
-            apr_pool_destroy(dobj->data.pool);
-            return APR_EGENERAL;
-        }
-        if (cl_header) {
-            apr_int64_t cl = apr_atoi64(cl_header);
-            if ((errno == 0) && (dobj->file_size != cl)) {
-                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00735)
-                        "URL %s didn't receive complete response, not caching",
-                        h->cache_obj->key);
+            if (r->connection->aborted || r->no_cache) {
+                ap_log_rerror(
+                        APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00733) "Discarding body for URL %s "
+                        "because connection has been aborted.", h->cache_obj->key);
+                /* Remove the intermediate cache file and return non-APR_SUCCESS */
+                apr_pool_destroy(dobj->data.pool);
+                return APR_EGENERAL;
+            }
+            if (dobj->file_size < dconf->minfs) {
+                ap_log_rerror(
+                        APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00734) "URL %s failed the size check "
+                        "(%" APR_OFF_T_FMT "<%" APR_OFF_T_FMT ")", h->cache_obj->key, dobj->file_size, dconf->minfs);
                 /* Remove the intermediate cache file and return non-APR_SUCCESS */
                 apr_pool_destroy(dobj->data.pool);
                 return APR_EGENERAL;
             }
+            if (cl_header) {
+                apr_int64_t cl = apr_atoi64(cl_header);
+                if ((errno == 0) && (dobj->file_size != cl)) {
+                    ap_log_rerror(
+                            APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00735) "URL %s didn't receive complete response, not caching", h->cache_obj->key);
+                    /* Remove the intermediate cache file and return non-APR_SUCCESS */
+                    apr_pool_destroy(dobj->data.pool);
+                    return APR_EGENERAL;
+                }
+            }
+
         }
 
         /* All checks were fine, we're good to go when the commit comes */
@@ -1321,7 +1328,12 @@ static apr_status_t commit_entity(cache_
         rv = file_cache_el_final(conf, &dobj->vary, r);
     }
     if (APR_SUCCESS == rv) {
-        rv = file_cache_el_final(conf, &dobj->data, r);
+        if (!dobj->disk_info.header_only) {
+            rv = file_cache_el_final(conf, &dobj->data, r);
+        }
+        else if (dobj->data.file){
+            rv = apr_file_remove(dobj->data.file, dobj->data.pool);
+        }
     }
 
     /* remove the cached items completely on any failure */

Modified: httpd/httpd/trunk/modules/cache/mod_cache_socache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_cache_socache.c?rev=1479411&r1=1479410&r2=1479411&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache_socache.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache_socache.c Sun May  5 22:27:31 2013
@@ -879,7 +879,13 @@ static apr_status_t store_headers(cache_
     socache_info->request_time = obj->info.request_time;
     socache_info->response_time = obj->info.response_time;
     socache_info->status = obj->info.status;
-    socache_info->header_only = r->header_only;
+
+    if (r->header_only && r->status != HTTP_NOT_MODIFIED) {
+        socache_info->header_only = 1;
+    }
+    else {
+        socache_info->header_only = sobj->socache_info.header_only;
+    }
 
     socache_info->name_len = strlen(sobj->name);