From 5f625b7df05ab02232c6e5dff94bc2961be3a554 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 27 Oct 2014 21:14:12 +0300 Subject: [PATCH] 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. --- src/http/ngx_http_file_cache.c | 68 +++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c index ff1363d6a..bc4c80602 100644 --- 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_request_t *r, ngx_md5_t *md5, 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; + } } }