changeset 5881:ee9230cd4bda

Cache: normalization of some Vary headers. Spaces in Accept-Charset, Accept-Encoding, and Accept-Language headers are now ignored. As per syntax of these headers spaces can only appear in places where they are optional.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 27 Oct 2014 21:14:12 +0300
parents 78c49e243848
children ec81934727a1
files src/http/ngx_http_file_cache.c
diffstat 1 files changed, 66 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -951,10 +951,34 @@ static void
 ngx_http_file_cache_vary_header(ngx_http_request_t *r, ngx_md5_t *md5,
     ngx_str_t *name)
 {
-    ngx_uint_t        i;
+    size_t            len;
+    u_char           *p, *start, *last;
+    ngx_uint_t        i, multiple, normalize;
     ngx_list_part_t  *part;
     ngx_table_elt_t  *header;
 
+    multiple = 0;
+    normalize = 0;
+
+    if (name->len == sizeof("Accept-Charset") - 1
+        && ngx_strncasecmp(name->data, (u_char *) "Accept-Charset",
+                           sizeof("Accept-Charset") - 1) == 0)
+    {
+        normalize = 1;
+
+    } else if (name->len == sizeof("Accept-Encoding") - 1
+        && ngx_strncasecmp(name->data, (u_char *) "Accept-Encoding",
+                           sizeof("Accept-Encoding") - 1) == 0)
+    {
+        normalize = 1;
+
+    } else if (name->len == sizeof("Accept-Language") - 1
+        && ngx_strncasecmp(name->data, (u_char *) "Accept-Language",
+                           sizeof("Accept-Language") - 1) == 0)
+    {
+        normalize = 1;
+    }
+
     part = &r->headers_in.headers.part;
     header = part->elts;
 
@@ -982,7 +1006,47 @@ ngx_http_file_cache_vary_header(ngx_http
             continue;
         }
 
-        ngx_md5_update(md5, header[i].value.data, header[i].value.len);
+        if (!normalize) {
+
+            if (multiple) {
+                ngx_md5_update(md5, (u_char *) ",", sizeof(",") - 1);
+            }
+
+            ngx_md5_update(md5, header[i].value.data, header[i].value.len);
+
+            multiple = 1;
+
+            continue;
+        }
+
+        /* normalize spaces */
+
+        p = header[i].value.data;
+        start = p;
+        last = p + header[i].value.len;
+
+        while (p < last) {
+
+            while (p < last && (*p == ' ' || *p == ',')) { p++; }
+
+            start = p;
+
+            while (p < last && *p != ',' && *p != ' ') { p++; }
+
+            len = p - start;
+
+            if (len == 0) {
+                break;
+            }
+
+            if (multiple) {
+                ngx_md5_update(md5, (u_char *) ",", sizeof(",") - 1);
+            }
+
+            ngx_md5_update(md5, start, len);
+
+            multiple = 1;
+        }
     }
 }