]> granicus.if.org Git - apache/blob - modules/cache/cache_util.c
Fix a corner case where automatic APLOGNO number generation generates invalid code...
[apache] / modules / cache / cache_util.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "mod_cache.h"
18
19 #include "cache_util.h"
20 #include <ap_provider.h>
21
22 #include "test_char.h"
23
24 APLOG_USE_MODULE(cache);
25
26 /* -------------------------------------------------------------- */
27
28 extern APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key;
29
30 extern module AP_MODULE_DECLARE_DATA cache_module;
31
32 /* Determine if "url" matches the hostname, scheme and port and path
33  * in "filter". All but the path comparisons are case-insensitive.
34  */
35 static int uri_meets_conditions(const apr_uri_t *filter, const int pathlen,
36                                 const apr_uri_t *url, const char *path)
37 {
38     /* Scheme, hostname port and local part. The filter URI and the
39      * URI we test may have the following shapes:
40      *   /<path>
41      *   <scheme>[:://<hostname>[:<port>][/<path>]]
42      * That is, if there is no scheme then there must be only the path,
43      * and we check only the path; if there is a scheme, we check the
44      * scheme for equality, and then if present we match the hostname,
45      * and then if present match the port, and finally the path if any.
46      *
47      * Note that this means that "/<path>" only matches local paths,
48      * and to match proxied paths one *must* specify the scheme.
49      */
50
51     /* Is the filter is just for a local path or a proxy URI? */
52     if (!filter->scheme) {
53         if (url->scheme || url->hostname) {
54             return 0;
55         }
56     }
57     else {
58         /* The URI scheme must be present and identical except for case. */
59         if (!url->scheme || ap_cstr_casecmp(filter->scheme, url->scheme)) {
60             return 0;
61         }
62
63         /* If the filter hostname is null or empty it matches any hostname,
64          * if it begins with a "*" it matches the _end_ of the URI hostname
65          * excluding the "*", if it begins with a "." it matches the _end_
66          * of the URI * hostname including the ".", otherwise it must match
67          * the URI hostname exactly. */
68
69         if (filter->hostname && filter->hostname[0]) {
70             if (filter->hostname[0] == '.') {
71                 const size_t fhostlen = strlen(filter->hostname);
72                 const size_t uhostlen = url->hostname ? strlen(url->hostname) : 0;
73
74                 if (fhostlen > uhostlen
75                     || (url->hostname
76                         && strcasecmp(filter->hostname,
77                                       url->hostname + uhostlen - fhostlen))) {
78                     return 0;
79                 }
80             }
81             else if (filter->hostname[0] == '*') {
82                 const size_t fhostlen = strlen(filter->hostname + 1);
83                 const size_t uhostlen = url->hostname ? strlen(url->hostname) : 0;
84
85                 if (fhostlen > uhostlen
86                     || (url->hostname
87                         && strcasecmp(filter->hostname + 1,
88                                       url->hostname + uhostlen - fhostlen))) {
89                     return 0;
90                 }
91             }
92             else if (!url->hostname || strcasecmp(filter->hostname, url->hostname)) {
93                 return 0;
94             }
95         }
96
97         /* If the filter port is empty it matches any URL port.
98          * If the filter or URL port are missing, or the URL port is
99          * empty, they default to the port for their scheme. */
100
101         if (!(filter->port_str && !filter->port_str[0])) {
102             /* NOTE:  ap_port_of_scheme will return 0 if given NULL input */
103             const unsigned fport = filter->port_str ? filter->port
104                     : apr_uri_port_of_scheme(filter->scheme);
105             const unsigned uport = (url->port_str && url->port_str[0])
106                     ? url->port : apr_uri_port_of_scheme(url->scheme);
107
108             if (fport != uport) {
109                 return 0;
110             }
111         }
112     }
113
114     /* For HTTP caching purposes, an empty (NULL) path is equivalent to
115      * a single "/" path. RFCs 3986/2396
116      */
117     if (!path) {
118         if (*filter->path == '/' && pathlen == 1) {
119             return 1;
120         }
121         else {
122             return 0;
123         }
124     }
125
126     /* Url has met all of the filter conditions so far, determine
127      * if the paths match.
128      */
129     return !strncmp(filter->path, path, pathlen);
130 }
131
132 int cache_use_early_url(request_rec *r)
133 {
134     cache_server_conf *conf;
135
136     if (r->proxyreq == PROXYREQ_PROXY) {
137         return 1;
138     }
139
140     conf = ap_get_module_config(r->server->module_config, &cache_module);
141     if (conf->quick) {
142         return 1;
143     }
144
145     return 0;
146 }
147
148 static cache_provider_list *get_provider(request_rec *r, struct cache_enable *ent,
149         cache_provider_list *providers)
150 {
151     /* Fetch from global config and add to the list. */
152     cache_provider *provider;
153     provider = ap_lookup_provider(CACHE_PROVIDER_GROUP, ent->type,
154                                   "0");
155     if (!provider) {
156         /* Log an error! */
157     }
158     else {
159         cache_provider_list *newp;
160         newp = apr_pcalloc(r->pool, sizeof(cache_provider_list));
161         newp->provider_name = ent->type;
162         newp->provider = provider;
163
164         if (!providers) {
165             providers = newp;
166         }
167         else {
168             cache_provider_list *last = providers;
169
170             while (last->next) {
171                 if (last->provider == provider) {
172                     return providers;
173                 }
174                 last = last->next;
175             }
176             if (last->provider == provider) {
177                 return providers;
178             }
179             last->next = newp;
180         }
181     }
182
183     return providers;
184 }
185
186 cache_provider_list *cache_get_providers(request_rec *r,
187                                          cache_server_conf *conf)
188 {
189     cache_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &cache_module);
190     cache_provider_list *providers = NULL;
191     const char *path;
192     int i;
193
194     /* per directory cache disable */
195     if (dconf->disable) {
196         return NULL;
197     }
198
199     path = cache_use_early_url(r) ? r->parsed_uri.path : r->uri;
200
201     /* global cache disable */
202     for (i = 0; i < conf->cachedisable->nelts; i++) {
203         struct cache_disable *ent =
204                                (struct cache_disable *)conf->cachedisable->elts;
205         if (uri_meets_conditions(&ent[i].url, ent[i].pathlen,
206                                  &r->parsed_uri, path)) {
207             /* Stop searching now. */
208             return NULL;
209         }
210     }
211
212     /* loop through all the per directory cacheenable entries */
213     for (i = 0; i < dconf->cacheenable->nelts; i++) {
214         struct cache_enable *ent =
215                                 (struct cache_enable *)dconf->cacheenable->elts;
216         providers = get_provider(r, &ent[i], providers);
217     }
218
219     /* loop through all the global cacheenable entries */
220     for (i = 0; i < conf->cacheenable->nelts; i++) {
221         struct cache_enable *ent =
222                                 (struct cache_enable *)conf->cacheenable->elts;
223         if (uri_meets_conditions(&ent[i].url, ent[i].pathlen,
224                                  &r->parsed_uri, path)) {
225             providers = get_provider(r, &ent[i], providers);
226         }
227     }
228
229     return providers;
230 }
231
232
233 /* do a HTTP/1.1 age calculation */
234 CACHE_DECLARE(apr_int64_t) ap_cache_current_age(cache_info *info,
235                                                 const apr_time_t age_value,
236                                                 apr_time_t now)
237 {
238     apr_time_t apparent_age, corrected_received_age, response_delay,
239                corrected_initial_age, resident_time, current_age,
240                age_value_usec;
241
242     age_value_usec = apr_time_from_sec(age_value);
243
244     /* Perform an HTTP/1.1 age calculation. (RFC2616 13.2.3) */
245
246     apparent_age = MAX(0, info->response_time - info->date);
247     corrected_received_age = MAX(apparent_age, age_value_usec);
248     response_delay = info->response_time - info->request_time;
249     corrected_initial_age = corrected_received_age + response_delay;
250     resident_time = now - info->response_time;
251     current_age = corrected_initial_age + resident_time;
252
253     if (current_age < 0) {
254         current_age = 0;
255     }
256
257     return apr_time_sec(current_age);
258 }
259
260 /**
261  * Try obtain a cache wide lock on the given cache key.
262  *
263  * If we return APR_SUCCESS, we obtained the lock, and we are clear to
264  * proceed to the backend. If we return APR_EEXIST, then the lock is
265  * already locked, someone else has gone to refresh the backend data
266  * already, so we must return stale data with a warning in the mean
267  * time. If we return anything else, then something has gone pear
268  * shaped, and we allow the request through to the backend regardless.
269  *
270  * This lock is created from the request pool, meaning that should
271  * something go wrong and the lock isn't deleted on return of the
272  * request headers from the backend for whatever reason, at worst the
273  * lock will be cleaned up when the request dies or finishes.
274  *
275  * If something goes truly bananas and the lock isn't deleted when the
276  * request dies, the lock will be trashed when its max-age is reached,
277  * or when a request arrives containing a Cache-Control: no-cache. At
278  * no point is it possible for this lock to permanently deny access to
279  * the backend.
280  */
281 apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache,
282         request_rec *r)
283 {
284     apr_status_t status;
285     const char *lockname;
286     const char *path;
287     char dir[5];
288     apr_time_t now = apr_time_now();
289     apr_finfo_t finfo;
290     apr_file_t *lockfile;
291     void *dummy;
292
293     finfo.mtime = 0;
294
295     if (!conf || !conf->lock || !conf->lockpath) {
296         /* no locks configured, leave */
297         return APR_SUCCESS;
298     }
299
300     /* lock already obtained earlier? if so, success */
301     apr_pool_userdata_get(&dummy, CACHE_LOCKFILE_KEY, r->pool);
302     if (dummy) {
303         return APR_SUCCESS;
304     }
305
306     /* create the key if it doesn't exist */
307     if (!cache->key) {
308         cache_handle_t *h;
309         /*
310          * Try to use the key of a possible open but stale cache
311          * entry if we have one.
312          */
313         if (cache->handle != NULL) {
314             h = cache->handle;
315         }
316         else {
317             h = cache->stale_handle;
318         }
319         if ((h != NULL) &&
320             (h->cache_obj != NULL) &&
321             (h->cache_obj->key != NULL)) {
322             cache->key = apr_pstrdup(r->pool, h->cache_obj->key);
323         }
324         else {
325             cache_generate_key(r, r->pool, &cache->key);
326         }
327     }
328
329     /* create a hashed filename from the key, and save it for later */
330     lockname = ap_cache_generate_name(r->pool, 0, 0, cache->key);
331
332     /* lock files represent discrete just-went-stale URLs "in flight", so
333      * we support a simple two level directory structure, more is overkill.
334      */
335     dir[0] = '/';
336     dir[1] = lockname[0];
337     dir[2] = '/';
338     dir[3] = lockname[1];
339     dir[4] = 0;
340
341     /* make the directories */
342     path = apr_pstrcat(r->pool, conf->lockpath, dir, NULL);
343     if (APR_SUCCESS != (status = apr_dir_make_recursive(path,
344             APR_UREAD|APR_UWRITE|APR_UEXECUTE, r->pool))) {
345         ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00778)
346                 "Could not create a cache lock directory: %s",
347                 path);
348         return status;
349     }
350     lockname = apr_pstrcat(r->pool, path, "/", lockname, NULL);
351     apr_pool_userdata_set(lockname, CACHE_LOCKNAME_KEY, NULL, r->pool);
352
353     /* is an existing lock file too old? */
354     status = apr_stat(&finfo, lockname,
355                 APR_FINFO_MTIME | APR_FINFO_NLINK, r->pool);
356     if (!(APR_STATUS_IS_ENOENT(status)) && APR_SUCCESS != status) {
357         ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00779)
358                 "Could not stat a cache lock file: %s",
359                 lockname);
360         return status;
361     }
362     if ((status == APR_SUCCESS) && (((now - finfo.mtime) > conf->lockmaxage)
363                                   || (now < finfo.mtime))) {
364         ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(00780)
365                 "Cache lock file for '%s' too old, removing: %s",
366                 r->uri, lockname);
367         apr_file_remove(lockname, r->pool);
368     }
369
370     /* try obtain a lock on the file */
371     if (APR_SUCCESS == (status = apr_file_open(&lockfile, lockname,
372             APR_WRITE | APR_CREATE | APR_EXCL | APR_DELONCLOSE,
373             APR_UREAD | APR_UWRITE, r->pool))) {
374         apr_pool_userdata_set(lockfile, CACHE_LOCKFILE_KEY, NULL, r->pool);
375     }
376     return status;
377
378 }
379
380 /**
381  * Remove the cache lock, if present.
382  *
383  * First, try to close the file handle, whose delete-on-close should
384  * kill the file. Otherwise, just delete the file by name.
385  *
386  * If no lock name has yet been calculated, do the calculation of the
387  * lock name first before trying to delete the file.
388  *
389  * If an optional bucket brigade is passed, the lock will only be
390  * removed if the bucket brigade contains an EOS bucket.
391  */
392 apr_status_t cache_remove_lock(cache_server_conf *conf,
393         cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb)
394 {
395     void *dummy;
396     const char *lockname;
397
398     if (!conf || !conf->lock || !conf->lockpath) {
399         /* no locks configured, leave */
400         return APR_SUCCESS;
401     }
402     if (bb) {
403         apr_bucket *e;
404         int eos_found = 0;
405         for (e = APR_BRIGADE_FIRST(bb);
406              e != APR_BRIGADE_SENTINEL(bb);
407              e = APR_BUCKET_NEXT(e))
408         {
409             if (APR_BUCKET_IS_EOS(e)) {
410                 eos_found = 1;
411                 break;
412             }
413         }
414         if (!eos_found) {
415             /* no eos found in brigade, don't delete anything just yet,
416              * we are not done.
417              */
418             return APR_SUCCESS;
419         }
420     }
421     apr_pool_userdata_get(&dummy, CACHE_LOCKFILE_KEY, r->pool);
422     if (dummy) {
423         return apr_file_close((apr_file_t *)dummy);
424     }
425     apr_pool_userdata_get(&dummy, CACHE_LOCKNAME_KEY, r->pool);
426     lockname = (const char *)dummy;
427     if (!lockname) {
428         char dir[5];
429
430         /* create the key if it doesn't exist */
431         if (!cache->key) {
432             cache_generate_key(r, r->pool, &cache->key);
433         }
434
435         /* create a hashed filename from the key, and save it for later */
436         lockname = ap_cache_generate_name(r->pool, 0, 0, cache->key);
437
438         /* lock files represent discrete just-went-stale URLs "in flight", so
439          * we support a simple two level directory structure, more is overkill.
440          */
441         dir[0] = '/';
442         dir[1] = lockname[0];
443         dir[2] = '/';
444         dir[3] = lockname[1];
445         dir[4] = 0;
446
447         lockname = apr_pstrcat(r->pool, conf->lockpath, dir, "/", lockname, NULL);
448     }
449     return apr_file_remove(lockname, r->pool);
450 }
451
452 int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r)
453 {
454
455     cache_server_conf *conf =
456       (cache_server_conf *)ap_get_module_config(r->server->module_config,
457                                                 &cache_module);
458
459     /*
460      * At this point, we may have data cached, but the request may have
461      * specified that cached data may not be used in a response.
462      *
463      * This is covered under RFC2616 section 14.9.4 (Cache Revalidation and
464      * Reload Controls).
465      *
466      * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache, or Pragma:
467      * no-cache. The server MUST NOT use a cached copy when responding to such
468      * a request.
469      */
470
471     /* This value comes from the client's initial request. */
472     if (!cache->control_in.parsed) {
473         const char *cc_req = cache_table_getm(r->pool, r->headers_in,
474                 "Cache-Control");
475         const char *pragma = cache_table_getm(r->pool, r->headers_in, "Pragma");
476         ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
477     }
478
479     if (cache->control_in.no_cache) {
480
481         if (!conf->ignorecachecontrol) {
482             return 0;
483         }
484         else {
485             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02657)
486                     "Incoming request is asking for an uncached version of "
487                     "%s, but we have been configured to ignore it and serve "
488                     "cached content anyway", r->unparsed_uri);
489         }
490     }
491
492     return 1;
493 }
494
495 int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r)
496 {
497
498     cache_server_conf *conf =
499       (cache_server_conf *)ap_get_module_config(r->server->module_config,
500                                                 &cache_module);
501
502     /*
503      * At this point, we may have data cached, but the request may have
504      * specified that cached data may not be used in a response.
505      *
506      * - RFC2616 14.9.2 What May be Stored by Caches. If Cache-Control:
507      * no-store arrives, do not serve from or store to the cache.
508      */
509
510     /* This value comes from the client's initial request. */
511     if (!cache->control_in.parsed) {
512         const char *cc_req = cache_table_getm(r->pool, r->headers_in,
513                 "Cache-Control");
514         const char *pragma = cache_table_getm(r->pool, r->headers_in, "Pragma");
515         ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
516     }
517
518     if (cache->control_in.no_store) {
519
520         if (!conf->ignorecachecontrol) {
521             /* We're not allowed to serve a cached copy */
522             return 0;
523         }
524         else {
525             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02658)
526                     "Incoming request is asking for a no-store version of "
527                     "%s, but we have been configured to ignore it and serve "
528                     "cached content anyway", r->unparsed_uri);
529         }
530     }
531
532     return 1;
533 }
534
535 int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache,
536         request_rec *r)
537 {
538     apr_status_t status;
539     apr_int64_t age, maxage_req, maxage_cresp, maxage, smaxage, maxstale;
540     apr_int64_t minfresh;
541     const char *cc_req;
542     const char *pragma;
543     const char *agestr = NULL;
544     apr_time_t age_c = 0;
545     cache_info *info = &(h->cache_obj->info);
546     const char *warn_head;
547     cache_server_conf *conf =
548       (cache_server_conf *)ap_get_module_config(r->server->module_config,
549                                                 &cache_module);
550
551     /*
552      * We now want to check if our cached data is still fresh. This depends
553      * on a few things, in this order:
554      *
555      * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache. no-cache
556      * in either the request or the cached response means that we must
557      * perform the request unconditionally, and ignore cached content. We
558      * should never reach here, but if we do, mark the content as stale,
559      * as this is the best we can do.
560      *
561      * - RFC2616 14.32 Pragma: no-cache This is treated the same as
562      * Cache-Control: no-cache.
563      *
564      * - RFC2616 14.9.3 Cache-Control: max-stale, must-revalidate,
565      * proxy-revalidate if the max-stale request header exists, modify the
566      * stale calculations below so that an object can be at most <max-stale>
567      * seconds stale before we request a revalidation, _UNLESS_ a
568      * must-revalidate or proxy-revalidate cached response header exists to
569      * stop us doing this.
570      *
571      * - RFC2616 14.9.3 Cache-Control: s-maxage the origin server specifies the
572      * maximum age an object can be before it is considered stale. This
573      * directive has the effect of proxy|must revalidate, which in turn means
574      * simple ignore any max-stale setting.
575      *
576      * - RFC2616 14.9.4 Cache-Control: max-age this header can appear in both
577      * requests and responses. If both are specified, the smaller of the two
578      * takes priority.
579      *
580      * - RFC2616 14.21 Expires: if this request header exists in the cached
581      * entity, and it's value is in the past, it has expired.
582      *
583      */
584
585     /* This value comes from the client's initial request. */
586     cc_req = apr_table_get(r->headers_in, "Cache-Control");
587     pragma = apr_table_get(r->headers_in, "Pragma");
588
589     ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
590
591     if (cache->control_in.no_cache) {
592
593         if (!conf->ignorecachecontrol) {
594             /* Treat as stale, causing revalidation */
595             return 0;
596         }
597
598         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00781)
599                 "Incoming request is asking for a uncached version of "
600                 "%s, but we have been configured to ignore it and "
601                 "serve a cached response anyway",
602                 r->unparsed_uri);
603     }
604
605     /* These come from the cached entity. */
606     if (h->cache_obj->info.control.no_cache
607             || h->cache_obj->info.control.invalidated) {
608         /*
609          * The cached entity contained Cache-Control: no-cache, or a
610          * no-cache with a header present, or a private with a header
611          * present, or the cached entity has been invalidated in the
612          * past, so treat as stale causing revalidation.
613          */
614         return 0;
615     }
616
617     if ((agestr = apr_table_get(h->resp_hdrs, "Age"))) {
618         char *endp;
619         apr_off_t offt;
620         if (!apr_strtoff(&offt, agestr, &endp, 10)
621                 && endp > agestr && !*endp) {
622             age_c = offt;
623         }
624     }
625
626     /* calculate age of object */
627     age = ap_cache_current_age(info, age_c, r->request_time);
628
629     /* extract s-maxage */
630     smaxage = h->cache_obj->info.control.s_maxage_value;
631
632     /* extract max-age from request */
633     maxage_req = -1;
634     if (!conf->ignorecachecontrol) {
635         maxage_req = cache->control_in.max_age_value;
636     }
637
638     /*
639      * extract max-age from response, if both s-maxage and max-age, s-maxage
640      * takes priority
641      */
642     if (smaxage != -1) {
643         maxage_cresp = smaxage;
644     }
645     else {
646         maxage_cresp = h->cache_obj->info.control.max_age_value;
647     }
648
649     /*
650      * if both maxage request and response, the smaller one takes priority
651      */
652     if (maxage_req == -1) {
653         maxage = maxage_cresp;
654     }
655     else if (maxage_cresp == -1) {
656         maxage = maxage_req;
657     }
658     else {
659         maxage = MIN(maxage_req, maxage_cresp);
660     }
661
662     /* extract max-stale */
663     if (cache->control_in.max_stale) {
664         if (cache->control_in.max_stale_value != -1) {
665             maxstale = cache->control_in.max_stale_value;
666         }
667         else {
668             /*
669              * If no value is assigned to max-stale, then the client is willing
670              * to accept a stale response of any age (RFC2616 14.9.3). We will
671              * set it to one year in this case as this situation is somewhat
672              * similar to a "never expires" Expires header (RFC2616 14.21)
673              * which is set to a date one year from the time the response is
674              * sent in this case.
675              */
676             maxstale = APR_INT64_C(86400*365);
677         }
678     }
679     else {
680         maxstale = 0;
681     }
682
683     /* extract min-fresh */
684     if (!conf->ignorecachecontrol && cache->control_in.min_fresh) {
685         minfresh = cache->control_in.min_fresh_value;
686     }
687     else {
688         minfresh = 0;
689     }
690
691     /* override maxstale if must-revalidate, proxy-revalidate or s-maxage */
692     if (maxstale && (h->cache_obj->info.control.must_revalidate
693             || h->cache_obj->info.control.proxy_revalidate || smaxage != -1)) {
694         maxstale = 0;
695     }
696
697     /* handle expiration */
698     if (((maxage != -1) && (age < (maxage + maxstale - minfresh))) ||
699         ((smaxage == -1) && (maxage == -1) &&
700          (info->expire != APR_DATE_BAD) &&
701          (age < (apr_time_sec(info->expire - info->date) + maxstale - minfresh)))) {
702
703         warn_head = apr_table_get(h->resp_hdrs, "Warning");
704
705         /* it's fresh darlings... */
706         /* set age header on response */
707         apr_table_set(h->resp_hdrs, "Age",
708                       apr_psprintf(r->pool, "%lu", (unsigned long)age));
709
710         /* add warning if maxstale overrode freshness calculation */
711         if (!(((maxage != -1) && age < maxage) ||
712               (info->expire != APR_DATE_BAD &&
713                (apr_time_sec(info->expire - info->date)) > age))) {
714             /* make sure we don't stomp on a previous warning */
715             if ((warn_head == NULL) ||
716                     (ap_strstr_c(warn_head, "110") == NULL)) {
717                 apr_table_mergen(h->resp_hdrs, "Warning",
718                                  "110 Response is stale");
719             }
720         }
721
722         /*
723          * If none of Expires, Cache-Control: max-age, or Cache-Control:
724          * s-maxage appears in the response, and the response header age
725          * calculated is more than 24 hours add the warning 113
726          */
727         if ((maxage_cresp == -1) && (smaxage == -1) && (apr_table_get(
728                 h->resp_hdrs, "Expires") == NULL) && (age > 86400)) {
729
730             /* Make sure we don't stomp on a previous warning, and don't dup
731              * a 113 marning that is already present. Also, make sure to add
732              * the new warning to the correct *headers_out location.
733              */
734             if ((warn_head == NULL) ||
735                     (ap_strstr_c(warn_head, "113") == NULL)) {
736                 apr_table_mergen(h->resp_hdrs, "Warning",
737                                  "113 Heuristic expiration");
738             }
739         }
740         return 1;    /* Cache object is fresh (enough) */
741     }
742
743     /*
744      * At this point we are stale, but: if we are under load, we may let
745      * a significant number of stale requests through before the first
746      * stale request successfully revalidates itself, causing a sudden
747      * unexpected thundering herd which in turn brings angst and drama.
748      *
749      * So.
750      *
751      * We want the first stale request to go through as normal. But the
752      * second and subsequent request, we must pretend to be fresh until
753      * the first request comes back with either new content or confirmation
754      * that the stale content is still fresh.
755      *
756      * To achieve this, we create a very simple file based lock based on
757      * the key of the cached object. We attempt to open the lock file with
758      * exclusive write access. If we succeed, woohoo! we're first, and we
759      * follow the stale path to the backend server. If we fail, oh well,
760      * we follow the fresh path, and avoid being a thundering herd.
761      *
762      * The lock lives only as long as the stale request that went on ahead.
763      * If the request succeeds, the lock is deleted. If the request fails,
764      * the lock is deleted, and another request gets to make a new lock
765      * and try again.
766      *
767      * At any time, a request marked "no-cache" will force a refresh,
768      * ignoring the lock, ensuring an extended lockout is impossible.
769      *
770      * A lock that exceeds a maximum age will be deleted, and another
771      * request gets to make a new lock and try again.
772      */
773     status = cache_try_lock(conf, cache, r);
774     if (APR_SUCCESS == status) {
775         /* we obtained a lock, follow the stale path */
776         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00782)
777                 "Cache lock obtained for stale cached URL, "
778                 "revalidating entry: %s",
779                 r->unparsed_uri);
780         return 0;
781     }
782     else if (APR_STATUS_IS_EEXIST(status)) {
783         /* lock already exists, return stale data anyway, with a warning */
784         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00783)
785                 "Cache already locked for stale cached URL, "
786                 "pretend it is fresh: %s",
787                 r->unparsed_uri);
788
789         /* make sure we don't stomp on a previous warning */
790         warn_head = apr_table_get(h->resp_hdrs, "Warning");
791         if ((warn_head == NULL) ||
792                 (ap_strstr_c(warn_head, "110") == NULL)) {
793             apr_table_mergen(h->resp_hdrs, "Warning",
794                              "110 Response is stale");
795         }
796
797         return 1;
798     }
799     else {
800         /* some other error occurred, just treat the object as stale */
801         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00784)
802                 "Attempt to obtain a cache lock for stale "
803                 "cached URL failed, revalidating entry anyway: %s",
804                 r->unparsed_uri);
805         return 0;
806     }
807
808 }
809
810 /* return each comma separated token, one at a time */
811 CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list,
812                                            const char **str)
813 {
814     apr_size_t i;
815     const char *s;
816
817     s = ap_strchr_c(list, ',');
818     if (s != NULL) {
819         i = s - list;
820         do
821             s++;
822         while (apr_isspace(*s))
823             ; /* noop */
824     }
825     else
826         i = strlen(list);
827
828     while (i > 0 && apr_isspace(list[i - 1]))
829         i--;
830
831     *str = s;
832     if (i)
833         return apr_pstrmemdup(p, list, i);
834     else
835         return NULL;
836 }
837
838 /*
839  * Converts apr_time_t expressed as hex digits to
840  * a true apr_time_t.
841  */
842 CACHE_DECLARE(apr_time_t) ap_cache_hex2usec(const char *x)
843 {
844     int i, ch;
845     apr_time_t j;
846     for (i = 0, j = 0; i < sizeof(j) * 2; i++) {
847         ch = x[i];
848         j <<= 4;
849         if (apr_isdigit(ch))
850             j |= ch - '0';
851         else if (apr_isupper(ch))
852             j |= ch - ('A' - 10);
853         else
854             j |= ch - ('a' - 10);
855     }
856     return j;
857 }
858
859 /*
860  * Converts apr_time_t to apr_time_t expressed as hex digits.
861  */
862 CACHE_DECLARE(void) ap_cache_usec2hex(apr_time_t j, char *y)
863 {
864     int i, ch;
865
866     for (i = (sizeof(j) * 2)-1; i >= 0; i--) {
867         ch = (int)(j & 0xF);
868         j >>= 4;
869         if (ch >= 10)
870             y[i] = ch + ('A' - 10);
871         else
872             y[i] = ch + '0';
873     }
874     y[sizeof(j) * 2] = '\0';
875 }
876
877 static void cache_hash(const char *it, char *val, int ndepth, int nlength)
878 {
879     apr_md5_ctx_t context;
880     unsigned char digest[16];
881     char tmp[22];
882     int i, k, d;
883     unsigned int x;
884     static const char enc_table[64] =
885     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@";
886
887     apr_md5_init(&context);
888     apr_md5_update(&context, (const unsigned char *) it, strlen(it));
889     apr_md5_final(digest, &context);
890
891     /* encode 128 bits as 22 characters, using a modified uuencoding
892      * the encoding is 3 bytes -> 4 characters* i.e. 128 bits is
893      * 5 x 3 bytes + 1 byte -> 5 * 4 characters + 2 characters
894      */
895     for (i = 0, k = 0; i < 15; i += 3) {
896         x = (digest[i] << 16) | (digest[i + 1] << 8) | digest[i + 2];
897         tmp[k++] = enc_table[x >> 18];
898         tmp[k++] = enc_table[(x >> 12) & 0x3f];
899         tmp[k++] = enc_table[(x >> 6) & 0x3f];
900         tmp[k++] = enc_table[x & 0x3f];
901     }
902
903     /* one byte left */
904     x = digest[15];
905     tmp[k++] = enc_table[x >> 2];    /* use up 6 bits */
906     tmp[k++] = enc_table[(x << 4) & 0x3f];
907
908     /* now split into directory levels */
909     for (i = k = d = 0; d < ndepth; ++d) {
910         memcpy(&val[i], &tmp[k], nlength);
911         k += nlength;
912         val[i + nlength] = '/';
913         i += nlength + 1;
914     }
915     memcpy(&val[i], &tmp[k], 22 - k);
916     val[i + 22 - k] = '\0';
917 }
918
919 CACHE_DECLARE(char *)ap_cache_generate_name(apr_pool_t *p, int dirlevels,
920                                             int dirlength, const char *name)
921 {
922     char hashfile[66];
923     cache_hash(name, hashfile, dirlevels, dirlength);
924     return apr_pstrdup(p, hashfile);
925 }
926
927 /**
928  * String tokenizer per RFC 7234 section 5.2 (1#token[=["]arg["]]).
929  * If any (and arg not NULL), the argument is also returned (unquoted).
930  */
931 apr_status_t cache_strqtok(char *str, char **token, char **arg, char **last)
932 {
933 #define CACHE_TOKEN_SEPS "\t ,"
934     apr_status_t rv = APR_SUCCESS;
935     enum {
936         IN_TOKEN,
937         IN_BETWEEN,
938         IN_ARGUMENT,
939         IN_QUOTES
940     } state = IN_TOKEN;
941     char *wpos;
942
943     if (!str) {         /* subsequent call */
944         str = *last;    /* start where we left off */
945     }
946     if (!str) {         /* no more tokens */
947         return APR_EOF;
948     }
949
950     /* skip separators (will terminate at '\0') */
951     while (*str && TEST_CHAR(*str, T_HTTP_TOKEN_STOP)) {
952         if (!ap_strchr_c(CACHE_TOKEN_SEPS, *str)) {
953             return APR_EINVAL;
954         }
955         ++str;
956     }
957     if (!*str) {        /* no more tokens */
958         return APR_EOF;
959     }
960
961     *token = str;
962     if (arg) {
963         *arg = NULL;
964     }
965
966     /* skip valid token characters to terminate token and
967      * prepare for the next call (will terminate at '\0)
968      * on the way, handle quoted strings, and within
969      * quoted strings, escaped characters.
970      */
971     for (wpos = str; *str; ++str) {
972         switch (state) {
973         case IN_TOKEN:
974             if (*str == '=') {
975                 state = IN_BETWEEN;
976                 *wpos++ = '\0';
977                 if (arg) *arg = wpos;
978                 continue;
979             }
980             break;
981
982         case IN_BETWEEN:
983             if (*str == '"') {
984                 state = IN_QUOTES;
985                 continue;
986             }
987             /* fall through */
988             state = IN_ARGUMENT;
989         case IN_ARGUMENT:
990             if (TEST_CHAR(*str, T_HTTP_TOKEN_STOP)) {
991                 goto end;
992             }
993             break;
994
995         default:
996             AP_DEBUG_ASSERT(state == IN_QUOTES);
997             if (*str == '"') {
998                 ++str;
999                 goto end;
1000             }
1001             if (*str == '\\' && *(str + 1)) {
1002                 ++str;
1003             }
1004             break;
1005         }
1006         *wpos++ = *str;
1007     }
1008 end:
1009     /* anything after should be trailing OWS or comma */
1010     for (; *str; ++str) {
1011         if (*str == ',') {
1012             ++str;
1013             break;
1014         }
1015         if (*str != '\t' && *str != ' ') {
1016             rv = APR_EINVAL;
1017             break;
1018         }
1019     }
1020
1021     *wpos = '\0';
1022     *last = str;
1023     return rv;
1024 }
1025
1026 /**
1027  * Parse the Cache-Control and Pragma headers in one go, marking
1028  * which tokens appear within the header. Populate the structure
1029  * passed in.
1030  */
1031 int ap_cache_control(request_rec *r, cache_control_t *cc,
1032         const char *cc_header, const char *pragma_header, apr_table_t *headers)
1033 {
1034     char *last;
1035     apr_status_t rv;
1036
1037     if (cc->parsed) {
1038         return cc->cache_control || cc->pragma;
1039     }
1040
1041     cc->parsed = 1;
1042     cc->max_age_value = -1;
1043     cc->max_stale_value = -1;
1044     cc->min_fresh_value = -1;
1045     cc->s_maxage_value = -1;
1046
1047     if (pragma_header) {
1048         char *header = apr_pstrdup(r->pool, pragma_header), *token;
1049         for (rv = cache_strqtok(header, &token, NULL, &last);
1050              rv == APR_SUCCESS;
1051              rv = cache_strqtok(NULL, &token, NULL, &last)) {
1052             if (!ap_cstr_casecmp(token, "no-cache")) {
1053                 cc->no_cache = 1;
1054             }
1055         }
1056         cc->pragma = 1;
1057     }
1058
1059     if (cc_header) {
1060         char *header = apr_pstrdup(r->pool, cc_header), *token, *arg;
1061         for (rv = cache_strqtok(header, &token, &arg, &last);
1062              rv == APR_SUCCESS;
1063              rv = cache_strqtok(NULL, &token, &arg, &last)) {
1064             char *endp;
1065             apr_off_t offt;
1066
1067             switch (token[0]) {
1068             case 'n':
1069             case 'N':
1070                 if (!ap_cstr_casecmp(token, "no-cache")) {
1071                     if (!arg) {
1072                         cc->no_cache = 1;
1073                     }
1074                     else {
1075                         cc->no_cache_header = 1;
1076                     }
1077                 }
1078                 else if (!ap_cstr_casecmp(token, "no-store")) {
1079                     cc->no_store = 1;
1080                 }
1081                 else if (!ap_cstr_casecmp(token, "no-transform")) {
1082                     cc->no_transform = 1;
1083                 }
1084                 break;
1085
1086             case 'm':
1087             case 'M':
1088                 if (arg && !ap_cstr_casecmp(token, "max-age")) {
1089                     if (!apr_strtoff(&offt, arg, &endp, 10)
1090                             && endp > arg && !*endp) {
1091                         cc->max_age = 1;
1092                         cc->max_age_value = offt;
1093                     }
1094                 }
1095                 else if (!ap_cstr_casecmp(token, "must-revalidate")) {
1096                     cc->must_revalidate = 1;
1097                 }
1098                 else if (!ap_cstr_casecmp(token, "max-stale")) {
1099                     if (!arg) {
1100                         cc->max_stale = 1;
1101                         cc->max_stale_value = -1;
1102                     }
1103                     else if (!apr_strtoff(&offt, arg, &endp, 10)
1104                              && endp > arg && !*endp) {
1105                         cc->max_stale = 1;
1106                         cc->max_stale_value = offt;
1107                     }
1108                 }
1109                 else if (arg && !ap_cstr_casecmp(token, "min-fresh")) {
1110                     if (!apr_strtoff(&offt, arg, &endp, 10)
1111                             && endp > arg && !*endp) {
1112                         cc->min_fresh = 1;
1113                         cc->min_fresh_value = offt;
1114                     }
1115                 }
1116                 break;
1117
1118             case 'o':
1119             case 'O':
1120                 if (!ap_cstr_casecmp(token, "only-if-cached")) {
1121                     cc->only_if_cached = 1;
1122                 }
1123                 break;
1124
1125             case 'p':
1126             case 'P':
1127                 if (!ap_cstr_casecmp(token, "public")) {
1128                     cc->public = 1;
1129                 }
1130                 else if (!ap_cstr_casecmp(token, "private")) {
1131                     if (!arg) {
1132                         cc->private = 1;
1133                     }
1134                     else {
1135                         cc->private_header = 1;
1136                     }
1137                 }
1138                 else if (!ap_cstr_casecmp(token, "proxy-revalidate")) {
1139                     cc->proxy_revalidate = 1;
1140                 }
1141                 break;
1142
1143             case 's':
1144             case 'S':
1145                 if (arg && !ap_cstr_casecmp(token, "s-maxage")) {
1146                     if (!apr_strtoff(&offt, arg, &endp, 10)
1147                             && endp > arg && !*endp) {
1148                         cc->s_maxage = 1;
1149                         cc->s_maxage_value = offt;
1150                     }
1151                 }
1152                 break;
1153             }
1154         }
1155         cc->cache_control = 1;
1156     }
1157
1158     return (cc_header != NULL || pragma_header != NULL);
1159 }
1160
1161 /**
1162  * Parse the Cache-Control, identifying and removing headers that
1163  * exist as tokens after the no-cache and private tokens.
1164  */
1165 static int cache_control_remove(request_rec *r, const char *cc_header,
1166         apr_table_t *headers)
1167 {
1168     char *last, *slast, *sheader;
1169     int found = 0;
1170
1171     if (cc_header) {
1172         apr_status_t rv;
1173         char *header = apr_pstrdup(r->pool, cc_header), *token, *arg;
1174         for (rv = cache_strqtok(header, &token, &arg, &last);
1175              rv == APR_SUCCESS;
1176              rv = cache_strqtok(NULL, &token, &arg, &last)) {
1177             if (!arg) {
1178                 continue;
1179             }
1180
1181             switch (token[0]) {
1182             case 'n':
1183             case 'N':
1184                 if (!ap_cstr_casecmp(token, "no-cache")) {
1185                     for (rv = cache_strqtok(arg, &sheader, NULL, &slast);
1186                          rv == APR_SUCCESS;
1187                          rv = cache_strqtok(NULL, &sheader, NULL, &slast)) {
1188                         apr_table_unset(headers, sheader);
1189                     }
1190                     found = 1;
1191                 }
1192                 break;
1193
1194             case 'p':
1195             case 'P':
1196                 if (!ap_cstr_casecmp(token, "private")) {
1197                     for (rv = cache_strqtok(arg, &sheader, NULL, &slast);
1198                          rv == APR_SUCCESS;
1199                          rv = cache_strqtok(NULL, &sheader, NULL, &slast)) {
1200                         apr_table_unset(headers, sheader);
1201                     }
1202                     found = 1;
1203                 }
1204                 break;
1205             }
1206         }
1207     }
1208
1209     return found;
1210 }
1211
1212 /*
1213  * Create a new table consisting of those elements from an
1214  * headers table that are allowed to be stored in a cache.
1215  */
1216 CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers(apr_pool_t *pool,
1217                                                         apr_table_t *t,
1218                                                         server_rec *s)
1219 {
1220     cache_server_conf *conf;
1221     char **header;
1222     int i;
1223     apr_table_t *headers_out;
1224
1225     /* Short circuit the common case that there are not
1226      * (yet) any headers populated.
1227      */
1228     if (t == NULL) {
1229         return apr_table_make(pool, 10);
1230     };
1231
1232     /* Make a copy of the headers, and remove from
1233      * the copy any hop-by-hop headers, as defined in Section
1234      * 13.5.1 of RFC 2616
1235      */
1236     headers_out = apr_table_copy(pool, t);
1237
1238     apr_table_unset(headers_out, "Connection");
1239     apr_table_unset(headers_out, "Keep-Alive");
1240     apr_table_unset(headers_out, "Proxy-Authenticate");
1241     apr_table_unset(headers_out, "Proxy-Authorization");
1242     apr_table_unset(headers_out, "TE");
1243     apr_table_unset(headers_out, "Trailers");
1244     apr_table_unset(headers_out, "Transfer-Encoding");
1245     apr_table_unset(headers_out, "Upgrade");
1246
1247     conf = (cache_server_conf *)ap_get_module_config(s->module_config,
1248                                                      &cache_module);
1249
1250     /* Remove the user defined headers set with CacheIgnoreHeaders.
1251      * This may break RFC 2616 compliance on behalf of the administrator.
1252      */
1253     header = (char **)conf->ignore_headers->elts;
1254     for (i = 0; i < conf->ignore_headers->nelts; i++) {
1255         apr_table_unset(headers_out, header[i]);
1256     }
1257     return headers_out;
1258 }
1259
1260 /*
1261  * Create a new table consisting of those elements from an input
1262  * headers table that are allowed to be stored in a cache.
1263  */
1264 CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_in(request_rec *r)
1265 {
1266     return ap_cache_cacheable_headers(r->pool, r->headers_in, r->server);
1267 }
1268
1269 /*
1270  * Create a new table consisting of those elements from an output
1271  * headers table that are allowed to be stored in a cache;
1272  * ensure there is a content type and capture any errors.
1273  */
1274 CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_out(request_rec *r)
1275 {
1276     apr_table_t *headers_out;
1277
1278     headers_out = ap_cache_cacheable_headers(r->pool,
1279                                              cache_merge_headers_out(r),
1280                                              r->server);
1281
1282     cache_control_remove(r,
1283             cache_table_getm(r->pool, headers_out, "Cache-Control"),
1284             headers_out);
1285
1286     return headers_out;
1287 }
1288
1289 apr_table_t *cache_merge_headers_out(request_rec *r)
1290 {
1291     apr_table_t *headers_out;
1292
1293     headers_out = apr_table_overlay(r->pool, r->headers_out,
1294                                     r->err_headers_out);
1295
1296     if (r->content_type
1297             && !apr_table_get(headers_out, "Content-Type")) {
1298         const char *ctype = ap_make_content_type(r, r->content_type);
1299         if (ctype) {
1300             apr_table_setn(headers_out, "Content-Type", ctype);
1301         }
1302     }
1303
1304     if (r->content_encoding
1305             && !apr_table_get(headers_out, "Content-Encoding")) {
1306         apr_table_setn(headers_out, "Content-Encoding",
1307                        r->content_encoding);
1308     }
1309
1310     return headers_out;
1311 }
1312
1313 typedef struct
1314 {
1315     apr_pool_t *p;
1316     const char *first;
1317     apr_array_header_t *merged;
1318 } cache_table_getm_t;
1319
1320 static int cache_table_getm_do(void *v, const char *key, const char *val)
1321 {
1322     cache_table_getm_t *state = (cache_table_getm_t *) v;
1323
1324     if (!state->first) {
1325         /**
1326          * The most common case is a single header, and this is covered by
1327          * a fast path that doesn't allocate any memory. On the second and
1328          * subsequent header, an array is created and the array concatenated
1329          * together to form the final value.
1330          */
1331         state->first = val;
1332     }
1333     else {
1334         const char **elt;
1335         if (!state->merged) {
1336             state->merged = apr_array_make(state->p, 10, sizeof(const char *));
1337             elt = apr_array_push(state->merged);
1338             *elt = state->first;
1339         }
1340         elt = apr_array_push(state->merged);
1341         *elt = val;
1342     }
1343     return 1;
1344 }
1345
1346 const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t,
1347         const char *key)
1348 {
1349     cache_table_getm_t state;
1350
1351     state.p = p;
1352     state.first = NULL;
1353     state.merged = NULL;
1354
1355     apr_table_do(cache_table_getm_do, &state, t, key, NULL);
1356
1357     if (!state.first) {
1358         return NULL;
1359     }
1360     else if (!state.merged) {
1361         return state.first;
1362     }
1363     else {
1364         return apr_array_pstrcat(p, state.merged, ',');
1365     }
1366 }