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;