]> granicus.if.org Git - apache/commitdiff
rewrite of ap_cache_liststr
authorBrian Pane <brianp@apache.org>
Sat, 12 Oct 2002 07:51:09 +0000 (07:51 +0000)
committerBrian Pane <brianp@apache.org>
Sat, 12 Oct 2002 07:51:09 +0000 (07:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97187 13f79535-47bb-0310-9956-ffa450edef68

modules/experimental/cache_util.c
modules/experimental/mod_cache.c
modules/experimental/mod_cache.h

index bb454b2cbcba6c4f076f58ea88c0bfab15fd7347..dcdb9e6ba0752f01f0412758bc37c9531ec6297c 100644 (file)
@@ -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 */
index 4402fda646d351af32f649df58d82425da9aaec3..8b732ccfcbdfd6e964b167bcf9cfae610a7bc841 100644 (file)
@@ -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) {
 
index c9bcc5d7120d08f53161f02657844f52989251e5..d98ba3edf5c14dc1ea598cd05e25fd6546b83905 100644 (file)
@@ -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);
 
 /**