You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by re...@apache.org on 2003/12/10 17:48:46 UTC
cvs commit: httpd-2.0/modules/experimental cache_storage.c cache_util.c mod_cache.c mod_cache.h mod_disk_cache.c mod_mem_cache.c
rederpj 2003/12/10 08:48:46
Modified: . Tag: APACHE_2_0_BRANCH CHANGES STATUS
modules/experimental Tag: APACHE_2_0_BRANCH cache_storage.c
cache_util.c mod_cache.c mod_cache.h
mod_disk_cache.c mod_mem_cache.c
Log:
Backporting the following fix from 2.1-dev:
*) Modified the cache code to be header-location agnostic. Also
fixed a number of other cache code bugs related to PR 15852.
Includes a patch submitted by Sushma Rai <rsushma novell.com>.
This fixes mod_mem_cache but not mod_disk_cache yet so I'm not
closing the PR since that is what they are using.
Reviewed by: Fielding, Trawick
Revision Changes Path
No revision
No revision
1.988.2.193 +6 -0 httpd-2.0/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-2.0/CHANGES,v
retrieving revision 1.988.2.192
retrieving revision 1.988.2.193
diff -u -r1.988.2.192 -r1.988.2.193
--- CHANGES 10 Dec 2003 08:50:09 -0000 1.988.2.192
+++ CHANGES 10 Dec 2003 16:48:45 -0000 1.988.2.193
@@ -1,5 +1,11 @@
Changes with Apache 2.0.49
+ *) Modified the cache code to be header-location agnostic. Also
+ fixed a number of other cache code bugs related to PR 15852.
+ Includes a patch submitted by Sushma Rai <rsushma novell.com>.
+ This fixes mod_mem_cache but not mod_disk_cache yet so I'm not
+ closing the PR since that is what they are using. [Paul J. Reder]
+
*) complain via error_log when mod_include's INCLUDES filter is
enabled, but the relevant Options flag allowing the filter to run
for the specific resource wasn't set, so that the filter won't
1.751.2.587 +1 -14 httpd-2.0/STATUS
Index: STATUS
===================================================================
RCS file: /home/cvs/httpd-2.0/STATUS,v
retrieving revision 1.751.2.586
retrieving revision 1.751.2.587
diff -u -r1.751.2.586 -r1.751.2.587
--- STATUS 10 Dec 2003 08:50:10 -0000 1.751.2.586
+++ STATUS 10 Dec 2003 16:48:45 -0000 1.751.2.587
@@ -107,19 +107,6 @@
http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/mappers/config9.m4.diff?r1=1.17&r2=1.18
+1: kess, trawick, nd, erikabele
- * Modifies the cache code to be header-location agnostic. Also
- fixes a number of other cache code bugs related to PR 15852
- (an RFC 2616 violation).
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/cache_storage.c.diff?r1=1.28&r2=1.29
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/cache_storage.c.diff?r1=1.29&r2=1.30
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/cache_util.c.diff?r1=1.27&r2=1.28
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/mod_cache.c.diff?r1=1.74&r2=1.75
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/mod_cache.c.diff?r1=1.75&r2=1.76
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/mod_cache.h.diff?r1=1.39&r2=1.40
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/mod_disk_cache.c.diff?r1=1.46&r2=1.47
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/experimental/mod_mem_cache.c.diff?r1=1.93&r2=1.94
- +1: rederpj, fielding, trawick
-
* Replace some of the mutex locking in the worker MPM with
atomic operations for higher concurrency.
server/mpm/worker/fdqueue.c 1.24, 1.25
No revision
No revision
1.27.2.2 +5 -1 httpd-2.0/modules/experimental/cache_storage.c
Index: cache_storage.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/cache_storage.c,v
retrieving revision 1.27.2.1
retrieving revision 1.27.2.2
diff -u -r1.27.2.1 -r1.27.2.2
--- cache_storage.c 3 Feb 2003 17:31:36 -0000 1.27.2.1
+++ cache_storage.c 10 Dec 2003 16:48:46 -0000 1.27.2.2
@@ -187,6 +187,7 @@
switch ((rv = cache_run_open_entity(h, r, type, key))) {
case OK: {
char *vary = NULL;
+ const char *varyhdr = NULL;
if (cache_read_entity_headers(h, r) != APR_SUCCESS) {
/* TODO: Handle this error */
return DECLINED;
@@ -209,7 +210,10 @@
*
* RFC2616 13.6 and 14.44 describe the Vary mechanism.
*/
- vary = apr_pstrdup(r->pool, apr_table_get(r->headers_out, "Vary"));
+ if ((varyhdr = apr_table_get(r->err_headers_out, "Vary")) == NULL) {
+ varyhdr = apr_table_get(r->headers_out, "Vary");
+ }
+ vary = apr_pstrdup(r->pool, varyhdr);
while (vary && *vary) {
char *name = vary;
const char *h1, *h2;
1.23.2.3 +51 -9 httpd-2.0/modules/experimental/cache_util.c
Index: cache_util.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/cache_util.c,v
retrieving revision 1.23.2.2
retrieving revision 1.23.2.3
diff -u -r1.23.2.2 -r1.23.2.3
--- cache_util.c 29 Sep 2003 21:09:47 -0000 1.23.2.2
+++ cache_util.c 10 Dec 2003 16:48:46 -0000 1.23.2.3
@@ -143,13 +143,16 @@
CACHE_DECLARE(apr_int64_t) ap_cache_current_age(cache_info *info, const apr_time_t age_value,
apr_time_t now)
{
- apr_time_t apparent_age, corrected_received_age, response_delay, corrected_initial_age,
- resident_time, current_age;
+ apr_time_t apparent_age, corrected_received_age, response_delay,
+ corrected_initial_age, resident_time, current_age,
+ age_value_usec;
+
+ age_value_usec = apr_time_from_sec(age_value);
/* Perform an HTTP/1.1 age calculation. (RFC2616 13.2.3) */
apparent_age = MAX(0, info->response_time - info->date);
- corrected_received_age = MAX(apparent_age, age_value);
+ corrected_received_age = MAX(apparent_age, age_value_usec);
response_delay = info->response_time - info->request_time;
corrected_initial_age = corrected_received_age + response_delay;
resident_time = now - info->response_time;
@@ -165,6 +168,7 @@
int age_in_errhdr = 0;
const char *cc_cresp, *cc_ceresp, *cc_req;
const char *agestr = NULL;
+ const char *expstr = NULL;
char *val;
apr_time_t age_c = 0;
cache_info *info = &(cache->handle->cache_obj->info);
@@ -213,6 +217,10 @@
age_in_errhdr = 1;
}
+ if (!(expstr = apr_table_get(r->err_headers_out, "Expires"))) {
+ expstr = apr_table_get(r->headers_out, "Expires");
+ }
+
/* calculate age of object */
age = ap_cache_current_age(info, age_c, r->request_time);
@@ -277,12 +285,25 @@
"proxy-revalidate", NULL)))) {
maxstale = 0;
}
+
/* handle expiration */
if (((smaxage != -1) && (age < (smaxage - minfresh))) ||
((maxage != -1) && (age < (maxage + maxstale - minfresh))) ||
((smaxage == -1) && (maxage == -1) &&
(info->expire != APR_DATE_BAD) &&
(age < (apr_time_sec(info->expire - info->date) + maxstale - minfresh)))) {
+ const char *warn_head;
+ apr_table_t *head_ptr;
+
+ warn_head = apr_table_get(r->headers_out, "Warning");
+ if (warn_head != NULL) {
+ head_ptr = r->headers_out;
+ }
+ else {
+ warn_head = apr_table_get(r->err_headers_out, "Warning");
+ head_ptr = r->err_headers_out;
+ }
+
/* it's fresh darlings... */
/* set age header on response */
if (age_in_errhdr) {
@@ -299,7 +320,27 @@
((maxage != -1) && age < maxage) ||
(info->expire != APR_DATE_BAD && (info->expire - info->date) > age))) {
/* make sure we don't stomp on a previous warning */
- apr_table_merge(r->headers_out, "Warning", "110 Response is stale");
+ if ((warn_head == NULL) ||
+ ((warn_head != NULL) && (ap_strstr_c(warn_head, "110") == NULL))) {
+ apr_table_merge(head_ptr, "Warning", "110 Response is stale");
+ }
+ }
+ /*
+ * If none of Expires, Cache-Control: max-age, or Cache-Control:
+ * s-maxage appears in the response, and the respose header age
+ * calculated is more than 24 hours add the warning 113
+ */
+ if ((maxage_cresp == -1) && (smaxage == -1) &&
+ (expstr == NULL) && (age > 86400)) {
+
+ /* Make sure we don't stomp on a previous warning, and don't dup
+ * a 113 marning that is already present. Also, make sure to add
+ * the new warning to the correct *headers_out location.
+ */
+ if ((warn_head == NULL) ||
+ ((warn_head != NULL) && (ap_strstr_c(warn_head, "113") == NULL))) {
+ apr_table_merge(head_ptr, "Warning", "113 Heuristic expiration");
+ }
}
return 1; /* Cache object is fresh (enough) */
}
@@ -496,17 +537,18 @@
return apr_pstrdup(p, hashfile);
}
-/* Create a new table consisting of those elements from a request_rec's
- * headers_out that are allowed to be stored in a cache.
+/* Create a new table consisting of those elements from an input
+ * headers table that are allowed to be stored in a cache.
*/
-CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_hdrs_out(request_rec *r)
+CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_hdrs_out(apr_pool_t *pool,
+ apr_table_t *t)
{
- /* Make a copy of the response headers, and remove from
+ /* Make a copy of the headers, and remove from
* the copy any hop-by-hop headers, as defined in Section
* 13.5.1 of RFC 2616
*/
apr_table_t *headers_out;
- headers_out = apr_table_copy(r->pool, r->headers_out);
+ headers_out = apr_table_copy(pool, t);
apr_table_unset(headers_out, "Connection");
apr_table_unset(headers_out, "Keep-Alive");
apr_table_unset(headers_out, "Proxy-Authenticate");
1.64.2.8 +53 -13 httpd-2.0/modules/experimental/mod_cache.c
Index: mod_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_cache.c,v
retrieving revision 1.64.2.7
retrieving revision 1.64.2.8
diff -u -r1.64.2.7 -r1.64.2.8
--- mod_cache.c 27 Sep 2003 18:17:10 -0000 1.64.2.7
+++ mod_cache.c 10 Dec 2003 16:48:46 -0000 1.64.2.8
@@ -250,7 +250,9 @@
return OK;
}
else {
- r->err_headers_out = apr_table_make(r->pool, 3);
+ if (!r->err_headers_out) {
+ r->err_headers_out = apr_table_make(r->pool, 3);
+ }
/* stale data available */
if (lookup) {
return DECLINED;
@@ -272,6 +274,16 @@
}
/* else if non-conditional request */
else {
+ /* Temporarily hack this to work the way it had been. Its broken,
+ * but its broken the way it was before. I'm working on figuring
+ * out why the filter add in the conditional filter doesn't work. pjr
+ *
+ * info = &(cache->handle->cache_obj->info);
+ *
+ * Uncomment the above when the code in cache_conditional_filter_handle
+ * is properly fixed... pjr
+ */
+
/* fudge response into a conditional */
if (info && info->etag) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
@@ -415,6 +427,7 @@
static int cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in)
{
int rv;
+ int date_in_errhdr = 0;
request_rec *r = f->r;
cache_request_rec *cache;
cache_server_conf *conf;
@@ -478,7 +491,10 @@
/* read expiry date; if a bad date, then leave it so the client can
* read it
*/
- exps = apr_table_get(r->headers_out, "Expires");
+ exps = apr_table_get(r->err_headers_out, "Expires");
+ if (exps == NULL) {
+ exps = apr_table_get(r->headers_out, "Expires");
+ }
if (exps != NULL) {
if (APR_DATE_BAD == (exp = apr_date_parse_http(exps))) {
exps = NULL;
@@ -489,7 +505,10 @@
}
/* read the last-modified date; if the date is bad, then delete it */
- lastmods = apr_table_get(r->headers_out, "Last-Modified");
+ lastmods = apr_table_get(r->err_headers_out, "Last-Modified");
+ if (lastmods ==NULL) {
+ lastmods = apr_table_get(r->headers_out, "Last-Modified");
+ }
if (lastmods != NULL) {
if (APR_DATE_BAD == (lastmod = apr_date_parse_http(lastmods))) {
lastmods = NULL;
@@ -501,8 +520,14 @@
conf = (cache_server_conf *) ap_get_module_config(r->server->module_config, &cache_module);
/* read the etag and cache-control from the entity */
- etag = apr_table_get(r->headers_out, "Etag");
- cc_out = apr_table_get(r->headers_out, "Cache-Control");
+ etag = apr_table_get(r->err_headers_out, "Etag");
+ if (etag == NULL) {
+ etag = apr_table_get(r->headers_out, "Etag");
+ }
+ cc_out = apr_table_get(r->err_headers_out, "Cache-Control");
+ if (cc_out == NULL) {
+ cc_out = apr_table_get(r->headers_out, "Cache-Control");
+ }
/*
* what responses should we not cache?
@@ -603,7 +628,10 @@
/* Set the content length if known.
*/
- cl = apr_table_get(r->headers_out, "Content-Length");
+ cl = apr_table_get(r->err_headers_out, "Content-Length");
+ if (cl == NULL) {
+ cl = apr_table_get(r->headers_out, "Content-Length");
+ }
if (cl) {
size = apr_atoi64(cl);
}
@@ -652,7 +680,7 @@
}
/* pre-existing cache handle and 304, make entity fresh */
else if (r->status == HTTP_NOT_MODIFIED) {
- /* update headers */
+ /* update headers: TODO */
/* remove this filter ??? */
@@ -689,7 +717,13 @@
*/
/* Read the date. Generate one if one is not supplied */
- dates = apr_table_get(r->headers_out, "Date");
+ dates = apr_table_get(r->err_headers_out, "Date");
+ if (dates != NULL) {
+ date_in_errhdr = 1;
+ }
+ else {
+ dates = apr_table_get(r->headers_out, "Date");
+ }
if (dates != NULL) {
info->date = apr_date_parse_http(dates);
}
@@ -700,10 +734,13 @@
now = apr_time_now();
if (info->date == APR_DATE_BAD) { /* No, or bad date */
char *dates;
- /* no date header! */
+ /* no date header (or bad header)! */
/* add one; N.B. use the time _now_ rather than when we were checking
* the cache
*/
+ if (date_in_errhdr == 1) {
+ apr_table_unset(r->err_headers_out, "Date");
+ }
date = now;
dates = apr_pcalloc(r->pool, MAX_STRING_LEN);
apr_rfc822_date(dates, now);
@@ -736,9 +773,9 @@
/* if no expiry date then
* if lastmod
- * expiry date = now + min((date - lastmod) * factor, maxexpire)
+ * expiry date = date + min((date - lastmod) * factor, maxexpire)
* else
- * expire date = now + defaultexpire
+ * expire date = date + defaultexpire
*/
if (exp == APR_DATE_BAD) {
/* if lastmod == date then you get 0*conf->factor which results in
@@ -747,18 +784,21 @@
*/
if ((lastmod != APR_DATE_BAD) && (lastmod < date)) {
apr_time_t x = (apr_time_t) ((date - lastmod) * conf->factor);
+
if (x > conf->maxex) {
x = conf->maxex;
}
- exp = now + x;
+ exp = date + x;
}
else {
- exp = now + conf->defex;
+ exp = date + conf->defex;
}
}
info->expire = exp;
info->content_type = apr_pstrdup(r->pool, r->content_type);
+ info->etag = apr_pstrdup(r->pool, etag);
+ info->lastmods = apr_pstrdup(r->pool, lastmods);
info->filename = apr_pstrdup(r->pool, r->filename );
/*
1.36.2.3 +1 -1 httpd-2.0/modules/experimental/mod_cache.h
Index: mod_cache.h
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_cache.h,v
retrieving revision 1.36.2.2
retrieving revision 1.36.2.3
diff -u -r1.36.2.2 -r1.36.2.3
--- mod_cache.h 3 Feb 2003 17:31:36 -0000 1.36.2.2
+++ mod_cache.h 10 Dec 2003 16:48:46 -0000 1.36.2.3
@@ -279,7 +279,7 @@
/* Create a new table consisting of those elements from a request_rec's
* headers_out that are allowed to be stored in a cache
*/
-CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_hdrs_out(request_rec *r);
+CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_hdrs_out(apr_pool_t *pool, apr_table_t *t);
/**
* cache_storage.c
1.45.2.2 +1 -1 httpd-2.0/modules/experimental/mod_disk_cache.c
Index: mod_disk_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_disk_cache.c,v
retrieving revision 1.45.2.1
retrieving revision 1.45.2.2
diff -u -r1.45.2.1 -r1.45.2.2
--- mod_disk_cache.c 3 Feb 2003 17:31:36 -0000 1.45.2.1
+++ mod_disk_cache.c 10 Dec 2003 16:48:46 -0000 1.45.2.2
@@ -603,7 +603,7 @@
if (r->headers_out) {
int i;
- apr_table_t* headers_out = ap_cache_cacheable_hdrs_out(r);
+ apr_table_t* headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out);
apr_table_entry_t *elts = (apr_table_entry_t *) apr_table_elts(headers_out)->elts;
for (i = 0; i < apr_table_elts(headers_out)->nelts; ++i) {
if (elts[i].key != NULL) {
1.88.2.3 +34 -1 httpd-2.0/modules/experimental/mod_mem_cache.c
Index: mod_mem_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_mem_cache.c,v
retrieving revision 1.88.2.2
retrieving revision 1.88.2.3
diff -u -r1.88.2.2 -r1.88.2.3
--- mod_mem_cache.c 3 Feb 2003 17:31:37 -0000 1.88.2.2
+++ mod_mem_cache.c 10 Dec 2003 16:48:46 -0000 1.88.2.3
@@ -86,10 +86,12 @@
typedef struct mem_cache_object {
cache_type_e type;
apr_ssize_t num_header_out;
+ apr_ssize_t num_err_header_out;
apr_ssize_t num_subprocess_env;
apr_ssize_t num_notes;
apr_ssize_t num_req_hdrs;
cache_header_tbl_t *header_out;
+ cache_header_tbl_t *err_header_out;
cache_header_tbl_t *subprocess_env;
cache_header_tbl_t *notes;
cache_header_tbl_t *req_hdrs; /* for Vary negotiation */
@@ -303,6 +305,11 @@
free(mobj->header_out[0].hdr);
free(mobj->header_out);
}
+ if (mobj->err_header_out) {
+ if (mobj->err_header_out[0].hdr)
+ free(mobj->err_header_out[0].hdr);
+ free(mobj->err_header_out);
+ }
if (mobj->subprocess_env) {
if (mobj->subprocess_env[0].hdr)
free(mobj->subprocess_env[0].hdr);
@@ -782,6 +789,7 @@
h->req_hdrs = apr_table_make(r->pool, mobj->num_req_hdrs);
r->headers_out = apr_table_make(r->pool, mobj->num_header_out);
+ r->err_headers_out = apr_table_make(r->pool, mobj->num_err_header_out);
r->subprocess_env = apr_table_make(r->pool, mobj->num_subprocess_env);
r->notes = apr_table_make(r->pool, mobj->num_notes);
@@ -791,6 +799,9 @@
rc = unserialize_table( mobj->header_out,
mobj->num_header_out,
r->headers_out);
+ rc = unserialize_table( mobj->err_header_out,
+ mobj->num_err_header_out,
+ r->err_headers_out);
rc = unserialize_table( mobj->subprocess_env,
mobj->num_subprocess_env,
r->subprocess_env);
@@ -852,7 +863,13 @@
/* Precompute how much storage we need to hold the headers */
rc = serialize_table(&mobj->header_out,
&mobj->num_header_out,
- ap_cache_cacheable_hdrs_out(r));
+ ap_cache_cacheable_hdrs_out(r->pool, r->headers_out));
+ if (rc != APR_SUCCESS) {
+ return rc;
+ }
+ rc = serialize_table(&mobj->err_header_out,
+ &mobj->num_err_header_out,
+ ap_cache_cacheable_hdrs_out(r->pool, r->err_headers_out));
if (rc != APR_SUCCESS) {
return rc;
}
@@ -891,6 +908,22 @@
return APR_ENOMEM;
}
memcpy(obj->info.content_type, info->content_type, len);
+ }
+ if (info->etag) {
+ apr_size_t len = strlen(info->etag) + 1;
+ obj->info.etag = (char*) malloc(len);
+ if (!obj->info.etag) {
+ return APR_ENOMEM;
+ }
+ memcpy(obj->info.etag, info->etag, len);
+ }
+ if (info->lastmods) {
+ apr_size_t len = strlen(info->lastmods) + 1;
+ obj->info.lastmods = (char*) malloc(len);
+ if (!obj->info.lastmods) {
+ return APR_ENOMEM;
+ }
+ memcpy(obj->info.lastmods, info->lastmods, len);
}
if ( info->filename) {
apr_size_t len = strlen(info->filename) + 1;