From dd5aede8c4c1a109208cd7d57a859cccc01e93ea Mon Sep 17 00:00:00 2001 From: Brian Pane Date: Sat, 12 Oct 2002 07:51:09 +0000 Subject: [PATCH] rewrite of ap_cache_liststr git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97187 13f79535-47bb-0310-9956-ffa450edef68 --- modules/experimental/cache_util.c | 115 +++++++++++++++++++----------- modules/experimental/mod_cache.c | 14 ++-- modules/experimental/mod_cache.h | 3 +- 3 files changed, 81 insertions(+), 51 deletions(-) diff --git a/modules/experimental/cache_util.c b/modules/experimental/cache_util.c index bb454b2cbc..dcdb9e6ba0 100644 --- a/modules/experimental/cache_util.c +++ b/modules/experimental/cache_util.c @@ -209,19 +209,19 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_request_rec *cache, age = ap_cache_current_age(info, age_c); /* extract s-maxage */ - if (cc_cresp && ap_cache_liststr(cc_cresp, "s-maxage", &val)) + if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "s-maxage", &val)) smaxage = apr_atoi64(val); else smaxage = -1; /* extract max-age from request */ - if (cc_req && ap_cache_liststr(cc_req, "max-age", &val)) + if (cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val)) maxage_req = apr_atoi64(val); else maxage_req = -1; /* extract max-age from response */ - if (cc_cresp && ap_cache_liststr(cc_cresp, "max-age", &val)) + if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "max-age", &val)) maxage_cresp = apr_atoi64(val); else maxage_cresp = -1; @@ -237,27 +237,29 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_request_rec *cache, maxage = MIN(maxage_req, maxage_cresp); /* extract max-stale */ - if (cc_req && ap_cache_liststr(cc_req, "max-stale", &val)) + if (cc_req && ap_cache_liststr(r->pool, cc_req, "max-stale", &val)) maxstale = apr_atoi64(val); else maxstale = 0; /* extract min-fresh */ - if (cc_req && ap_cache_liststr(cc_req, "min-fresh", &val)) + if (cc_req && ap_cache_liststr(r->pool, cc_req, "min-fresh", &val)) minfresh = apr_atoi64(val); else minfresh = 0; /* override maxstale if must-revalidate or proxy-revalidate */ if (maxstale && ((cc_cresp && - ap_cache_liststr(cc_cresp, "must-revalidate", NULL)) - || (cc_cresp && ap_cache_liststr(cc_cresp, + ap_cache_liststr(NULL, + cc_cresp, "must-revalidate", NULL)) + || (cc_cresp && ap_cache_liststr(NULL, + cc_cresp, "proxy-revalidate", NULL)))) maxstale = 0; /* handle expiration */ if ((-1 < smaxage && age < (smaxage - minfresh)) || (-1 < maxage && age < (maxage + maxstale - minfresh)) || - (info->expire != APR_DATE_BAD && age < (info->expire - info->date + maxstale - minfresh))) { + (info->expire != APR_DATE_BAD && age < (apr_time_sec(info->expire - info->date) + maxstale - minfresh))) { /* it's fresh darlings... */ /* set age header on response */ apr_table_set(r->headers_out, "Age", @@ -280,47 +282,74 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_request_rec *cache, * The return returns 1 if the token val is found in the list, or 0 * otherwise. */ -CACHE_DECLARE(int) ap_cache_liststr(const char *list, const char *key, char **val) +CACHE_DECLARE(int) ap_cache_liststr(apr_pool_t *p, const char *list, + const char *key, char **val) { - int len, i; - char *p; - char valbuf[HUGE_STRING_LEN]; - valbuf[sizeof(valbuf)-1] = 0; /* safety terminating zero */ - - len = strlen(key); - - while (list != NULL) { - p = strchr((char *) list, ','); - if (p != NULL) { - i = p - list; - do - p++; - while (apr_isspace(*p)); + apr_size_t key_len; + const char *next; + + if (!list) { + return 0; + } + + key_len = strlen(key); + next = list; + + for (;;) { + + /* skip whitespace and commas to find the start of the next key */ + while (*next && (apr_isspace(*next) || (*next == ','))) { + next++; } - else - i = strlen(list); - - while (i > 0 && apr_isspace(list[i - 1])) - i--; - if (i == len && strncasecmp(list, key, len) == 0) { - if (val) { - p = strchr((char *) list, ','); - while (apr_isspace(*list)) { - list++; - } - if ('=' == list[0]) - list++; - while (apr_isspace(*list)) { - list++; + + if (!*next) { + return 0; + } + + if (!strncasecmp(next, key, key_len)) { + /* this field matches the key (though it might just be + * a prefix match, so make sure the match is followed + * by either a space or an equals sign) + */ + next += key_len; + if (!*next || (*next == '=') || apr_isspace(*next) || + (*next == ',')) { + /* valid match */ + if (val) { + while (*next && (*next != '=') && (*next != ',')) { + next++; + } + if (*next == '=') { + next++; + while (*next && apr_isspace(*next )) { + next++; + } + if (!*next) { + *val = NULL; + } + else { + const char *val_start = next; + while (*next && !apr_isspace(*next) && + (*next != ',')) { + next++; + } + *val = apr_pstrmemdup(p, val_start, + next - val_start); + } + } } - strncpy(valbuf, list, MIN(p-list, sizeof(valbuf)-1)); - *val = valbuf; + return 1; } - return 1; } - list = p; + + /* skip to the next field */ + do { + next++; + if (!*next) { + return 0; + } + } while (*next != ','); } - return 0; } /* return each comma separated token, one at a time */ diff --git a/modules/experimental/mod_cache.c b/modules/experimental/mod_cache.c index 4402fda646..8b732ccfcb 100644 --- a/modules/experimental/mod_cache.c +++ b/modules/experimental/mod_cache.c @@ -168,8 +168,8 @@ static int cache_url_handler(request_rec *r, int lookup) "%s, but we know better and are ignoring it", url); } else { - if (ap_cache_liststr(cc_in, "no-store", NULL) || - ap_cache_liststr(pragma, "no-cache", NULL) || (auth != NULL)) { + if (ap_cache_liststr(NULL, cc_in, "no-store", NULL) || + ap_cache_liststr(NULL, pragma, "no-cache", NULL) || (auth != NULL)) { /* delete the previously cached file */ cache_remove_url(r, cache->types, url); @@ -559,12 +559,12 @@ static int cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in) /* RFC2616 14.9.2 Cache-Control: no-store response * indicating do not cache, or stop now if you are * trying to cache it */ - || ap_cache_liststr(cc_out, "no-store", NULL) + || ap_cache_liststr(NULL, cc_out, "no-store", NULL) /* RFC2616 14.9.1 Cache-Control: private * this object is marked for this user's eyes only. Behave * as a tunnel. */ - || ap_cache_liststr(cc_out, "private", NULL) + || ap_cache_liststr(NULL, cc_out, "private", NULL) /* RFC2616 14.8 Authorisation: * if authorisation is included in the request, we don't cache, * but we can cache if the following exceptions are true: @@ -573,9 +573,9 @@ static int cache_in_filter(ap_filter_t *f, apr_bucket_brigade *in) * 3) If Cache-Control: public is included */ || (apr_table_get(r->headers_in, "Authorization") != NULL - && !(ap_cache_liststr(cc_out, "s-maxage", NULL) - || ap_cache_liststr(cc_out, "must-revalidate", NULL) - || ap_cache_liststr(cc_out, "public", NULL))) + && !(ap_cache_liststr(NULL, cc_out, "s-maxage", NULL) + || ap_cache_liststr(NULL, cc_out, "must-revalidate", NULL) + || ap_cache_liststr(NULL, cc_out, "public", NULL))) /* or we've been asked not to cache it above */ || r->no_cache) { diff --git a/modules/experimental/mod_cache.h b/modules/experimental/mod_cache.h index c9bcc5d712..d98ba3edf5 100644 --- a/modules/experimental/mod_cache.h +++ b/modules/experimental/mod_cache.h @@ -267,7 +267,8 @@ CACHE_DECLARE(char *) generate_name(apr_pool_t *p, int dirlevels, CACHE_DECLARE(int) ap_cache_request_is_conditional(request_rec *r); CACHE_DECLARE(void) ap_cache_reset_output_filters(request_rec *r); CACHE_DECLARE(const char *)ap_cache_get_cachetype(request_rec *r, cache_server_conf *conf, const char *url); -CACHE_DECLARE(int) ap_cache_liststr(const char *list, const char *key, char **val); +CACHE_DECLARE(int) ap_cache_liststr(apr_pool_t *p, const char *list, + const char *key, char **val); CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str); /** -- 2.40.0