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);