comparison src/http/modules/ngx_http_not_modified_filter_module.c @ 5734:af229f8cf987

Entity tags: weak comparison for If-None-Match.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 26 Jun 2014 02:21:20 +0400
parents bb3d74fc4aea
children 5fb1e57c758a
comparison
equal deleted inserted replaced
5733:e491b26fa5a1 5734:af229f8cf987
11 11
12 12
13 static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r); 13 static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r);
14 static ngx_uint_t ngx_http_test_if_modified(ngx_http_request_t *r); 14 static ngx_uint_t ngx_http_test_if_modified(ngx_http_request_t *r);
15 static ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r, 15 static ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r,
16 ngx_table_elt_t *header); 16 ngx_table_elt_t *header, ngx_uint_t weak);
17 static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf); 17 static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
18 18
19 19
20 static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = { 20 static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = {
21 NULL, /* preconfiguration */ 21 NULL, /* preconfiguration */
67 return ngx_http_filter_finalize_request(r, NULL, 67 return ngx_http_filter_finalize_request(r, NULL,
68 NGX_HTTP_PRECONDITION_FAILED); 68 NGX_HTTP_PRECONDITION_FAILED);
69 } 69 }
70 70
71 if (r->headers_in.if_match 71 if (r->headers_in.if_match
72 && !ngx_http_test_if_match(r, r->headers_in.if_match)) 72 && !ngx_http_test_if_match(r, r->headers_in.if_match, 0))
73 { 73 {
74 return ngx_http_filter_finalize_request(r, NULL, 74 return ngx_http_filter_finalize_request(r, NULL,
75 NGX_HTTP_PRECONDITION_FAILED); 75 NGX_HTTP_PRECONDITION_FAILED);
76 } 76 }
77 77
82 { 82 {
83 return ngx_http_next_header_filter(r); 83 return ngx_http_next_header_filter(r);
84 } 84 }
85 85
86 if (r->headers_in.if_none_match 86 if (r->headers_in.if_none_match
87 && !ngx_http_test_if_match(r, r->headers_in.if_none_match)) 87 && !ngx_http_test_if_match(r, r->headers_in.if_none_match, 1))
88 { 88 {
89 return ngx_http_next_header_filter(r); 89 return ngx_http_next_header_filter(r);
90 } 90 }
91 91
92 /* not modified */ 92 /* not modified */
159 return 0; 159 return 0;
160 } 160 }
161 161
162 162
163 static ngx_uint_t 163 static ngx_uint_t
164 ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header) 164 ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header,
165 ngx_uint_t weak)
165 { 166 {
166 u_char *start, *end, ch; 167 u_char *start, *end, ch;
167 ngx_str_t *etag, *list; 168 ngx_str_t etag, *list;
168 169
169 list = &header->value; 170 list = &header->value;
170 171
171 if (list->len == 1 && list->data[0] == '*') { 172 if (list->len == 1 && list->data[0] == '*') {
172 return 1; 173 return 1;
174 175
175 if (r->headers_out.etag == NULL) { 176 if (r->headers_out.etag == NULL) {
176 return 0; 177 return 0;
177 } 178 }
178 179
179 etag = &r->headers_out.etag->value; 180 etag = r->headers_out.etag->value;
180 181
181 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 182 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
182 "http im:\"%V\" etag:%V", list, etag); 183 "http im:\"%V\" etag:%V", list, &etag);
184
185 if (weak
186 && etag.len > 2
187 && etag.data[0] == 'W'
188 && etag.data[1] == '/')
189 {
190 etag.len -= 2;
191 etag.data += 2;
192 }
183 193
184 start = list->data; 194 start = list->data;
185 end = list->data + list->len; 195 end = list->data + list->len;
186 196
187 while (start < end) { 197 while (start < end) {
188 198
189 if (etag->len > (size_t) (end - start)) { 199 if (weak
200 && end - start > 2
201 && start[0] == 'W'
202 && start[1] == '/')
203 {
204 start += 2;
205 }
206
207 if (etag.len > (size_t) (end - start)) {
190 return 0; 208 return 0;
191 } 209 }
192 210
193 if (ngx_strncmp(start, etag->data, etag->len) != 0) { 211 if (ngx_strncmp(start, etag.data, etag.len) != 0) {
194 goto skip; 212 goto skip;
195 } 213 }
196 214
197 start += etag->len; 215 start += etag.len;
198 216
199 while (start < end) { 217 while (start < end) {
200 ch = *start; 218 ch = *start;
201 219
202 if (ch == ' ' || ch == '\t') { 220 if (ch == ' ' || ch == '\t') {