Mercurial > hg > nginx
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') { |