summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2013-05-06 13:41:10 +0200
committerGraham Leggett <minfrin@apache.org>2013-05-06 13:41:10 +0200
commit997e0f6d33051abddc95b39fcd71a8191d83a22a (patch)
tree993bfb996f992bb8d0bb9206de1ba46357c8e6da /server
parentmod_cache: Ensure that updated responses to HEAD requests don't get (diff)
downloadapache2-997e0f6d33051abddc95b39fcd71a8191d83a22a.tar.xz
apache2-997e0f6d33051abddc95b39fcd71a8191d83a22a.zip
core: Add the ability to do explicit matching on weak and strong ETags
as per RFC2616 Section 13.3.3. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1479528 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r--server/util.c72
1 files changed, 66 insertions, 6 deletions
diff --git a/server/util.c b/server/util.c
index 676759fe48..6be14736b7 100644
--- a/server/util.c
+++ b/server/util.c
@@ -1287,27 +1287,58 @@ AP_DECLARE(char *) ap_get_list_item(apr_pool_t *p, const char **field)
return token;
}
+typedef enum ap_etag_e {
+ AP_ETAG_NONE,
+ AP_ETAG_WEAK,
+ AP_ETAG_STRONG
+} ap_etag_e;
+
/* Find an item in canonical form (lowercase, no extra spaces) within
* an HTTP field value list. Returns 1 if found, 0 if not found.
* This would be much more efficient if we stored header fields as
* an array of list items as they are received instead of a plain string.
*/
-AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line,
- const char *tok)
+static int find_list_item(apr_pool_t *p, const char *line,
+ const char *tok, ap_etag_e type)
{
const unsigned char *pos;
const unsigned char *ptr = (const unsigned char *)line;
int good = 0, addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0;
- if (!line || !tok)
+ if (!line || !tok) {
+ return 0;
+ }
+ if (type == AP_ETAG_STRONG && *tok != '\"') {
return 0;
+ }
+ if (type == AP_ETAG_WEAK) {
+ if (*tok == 'W' && (*(tok+1)) == '/' && (*(tok+2)) == '\"') {
+ tok += 2;
+ }
+ else if (*tok != '\"') {
+ return 0;
+ }
+ }
do { /* loop for each item in line's list */
/* Find first non-comma, non-whitespace byte */
-
- while (*ptr == ',' || apr_isspace(*ptr))
+ while (*ptr == ',' || apr_isspace(*ptr)) {
++ptr;
+ }
+
+ /* Account for strong or weak Etags, depending on our search */
+ if (type == AP_ETAG_STRONG && *ptr != '\"') {
+ break;
+ }
+ if (type == AP_ETAG_WEAK) {
+ if (*ptr == 'W' && (*(ptr+1)) == '/' && (*(ptr+2)) == '\"') {
+ ptr += 2;
+ }
+ else if (*ptr != '\"') {
+ break;
+ }
+ }
if (*ptr)
good = 1; /* until proven otherwise for this item */
@@ -1375,7 +1406,8 @@ AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line,
if (in_com || in_qstr)
good = good && (*pos++ == *ptr);
else
- good = good && (*pos++ == apr_tolower(*ptr));
+ good = good
+ && (apr_tolower(*pos++) == apr_tolower(*ptr));
addspace = 0;
break;
}
@@ -1389,6 +1421,34 @@ AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line,
return good;
}
+/* Find an item in canonical form (lowercase, no extra spaces) within
+ * an HTTP field value list. Returns 1 if found, 0 if not found.
+ * This would be much more efficient if we stored header fields as
+ * an array of list items as they are received instead of a plain string.
+ */
+AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line,
+ const char *tok)
+{
+ return find_list_item(p, line, tok, AP_ETAG_NONE);
+}
+
+/* Find a strong Etag in canonical form (lowercase, no extra spaces) within
+ * an HTTP field value list. Returns 1 if found, 0 if not found.
+ */
+AP_DECLARE(int) ap_find_etag_strong(apr_pool_t *p, const char *line,
+ const char *tok)
+{
+ return find_list_item(p, line, tok, AP_ETAG_STRONG);
+}
+
+/* Find a weak ETag in canonical form (lowercase, no extra spaces) within
+ * an HTTP field value list. Returns 1 if found, 0 if not found.
+ */
+AP_DECLARE(int) ap_find_etag_weak(apr_pool_t *p, const char *line,
+ const char *tok)
+{
+ return find_list_item(p, line, tok, AP_ETAG_WEAK);
+}
/* Retrieve a token, spacing over it and returning a pointer to
* the first non-white byte afterwards. Note that these tokens