Mercurial > hg > nginx-vendor-current
comparison src/http/modules/ngx_http_not_modified_filter_module.c @ 680:597573166f34 NGINX_1_3_3
nginx 1.3.3
*) Feature: entity tags support and the "etag" directive.
*) Bugfix: trailing dot in a source value was not ignored if the "map"
directive was used with the "hostnames" parameter.
*) Bugfix: incorrect location might be used to process a request if a
URI was changed via a "rewrite" directive before an internal redirect
to a named location.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 10 Jul 2012 00:00:00 +0400 |
parents | d0f7a625f27c |
children |
comparison
equal
deleted
inserted
replaced
679:cad34cec7d3b | 680:597573166f34 |
---|---|
8 #include <ngx_config.h> | 8 #include <ngx_config.h> |
9 #include <ngx_core.h> | 9 #include <ngx_core.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | 11 |
12 | 12 |
13 static ngx_int_t ngx_http_test_precondition(ngx_http_request_t *r); | 13 static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r); |
14 static ngx_int_t ngx_http_test_not_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, | |
16 ngx_table_elt_t *header); | |
15 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); |
16 | 18 |
17 | 19 |
18 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 = { |
19 NULL, /* preconfiguration */ | 21 NULL, /* preconfiguration */ |
57 || r->headers_out.last_modified_time == -1) | 59 || r->headers_out.last_modified_time == -1) |
58 { | 60 { |
59 return ngx_http_next_header_filter(r); | 61 return ngx_http_next_header_filter(r); |
60 } | 62 } |
61 | 63 |
62 if (r->headers_in.if_unmodified_since) { | 64 if (r->headers_in.if_unmodified_since |
63 return ngx_http_test_precondition(r); | 65 && !ngx_http_test_if_unmodified(r)) |
64 } | 66 { |
65 | 67 return ngx_http_filter_finalize_request(r, NULL, |
66 if (r->headers_in.if_modified_since) { | 68 NGX_HTTP_PRECONDITION_FAILED); |
67 return ngx_http_test_not_modified(r); | 69 } |
70 | |
71 if (r->headers_in.if_match | |
72 && !ngx_http_test_if_match(r, r->headers_in.if_match)) | |
73 { | |
74 return ngx_http_filter_finalize_request(r, NULL, | |
75 NGX_HTTP_PRECONDITION_FAILED); | |
76 } | |
77 | |
78 if (r->headers_in.if_modified_since || r->headers_in.if_none_match) { | |
79 | |
80 if (r->headers_in.if_modified_since | |
81 && ngx_http_test_if_modified(r)) | |
82 { | |
83 return ngx_http_next_header_filter(r); | |
84 } | |
85 | |
86 if (r->headers_in.if_none_match | |
87 && !ngx_http_test_if_match(r, r->headers_in.if_none_match)) | |
88 { | |
89 return ngx_http_next_header_filter(r); | |
90 } | |
91 | |
92 /* not modified */ | |
93 | |
94 r->headers_out.status = NGX_HTTP_NOT_MODIFIED; | |
95 r->headers_out.status_line.len = 0; | |
96 r->headers_out.content_type.len = 0; | |
97 ngx_http_clear_content_length(r); | |
98 ngx_http_clear_accept_ranges(r); | |
99 | |
100 if (r->headers_out.content_encoding) { | |
101 r->headers_out.content_encoding->hash = 0; | |
102 r->headers_out.content_encoding = NULL; | |
103 } | |
104 | |
105 return ngx_http_next_header_filter(r); | |
68 } | 106 } |
69 | 107 |
70 return ngx_http_next_header_filter(r); | 108 return ngx_http_next_header_filter(r); |
71 } | 109 } |
72 | 110 |
73 | 111 |
74 static ngx_int_t | 112 static ngx_uint_t |
75 ngx_http_test_precondition(ngx_http_request_t *r) | 113 ngx_http_test_if_unmodified(ngx_http_request_t *r) |
76 { | 114 { |
77 time_t iums; | 115 time_t iums; |
78 | 116 |
79 iums = ngx_http_parse_time(r->headers_in.if_unmodified_since->value.data, | 117 iums = ngx_http_parse_time(r->headers_in.if_unmodified_since->value.data, |
80 r->headers_in.if_unmodified_since->value.len); | 118 r->headers_in.if_unmodified_since->value.len); |
81 | 119 |
82 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 120 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
83 "http iums:%d lm:%d", iums, r->headers_out.last_modified_time); | 121 "http iums:%d lm:%d", iums, r->headers_out.last_modified_time); |
84 | 122 |
85 if (iums >= r->headers_out.last_modified_time) { | 123 if (iums >= r->headers_out.last_modified_time) { |
86 return ngx_http_next_header_filter(r); | 124 return 1; |
87 } | 125 } |
88 | 126 |
89 return ngx_http_filter_finalize_request(r, NULL, | 127 return 0; |
90 NGX_HTTP_PRECONDITION_FAILED); | 128 } |
91 } | 129 |
92 | 130 |
93 | 131 static ngx_uint_t |
94 static ngx_int_t | 132 ngx_http_test_if_modified(ngx_http_request_t *r) |
95 ngx_http_test_not_modified(ngx_http_request_t *r) | |
96 { | 133 { |
97 time_t ims; | 134 time_t ims; |
98 ngx_http_core_loc_conf_t *clcf; | 135 ngx_http_core_loc_conf_t *clcf; |
99 | 136 |
100 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 137 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
101 | 138 |
102 if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) { | 139 if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) { |
103 return ngx_http_next_header_filter(r); | 140 return 1; |
104 } | 141 } |
105 | 142 |
106 ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data, | 143 ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data, |
107 r->headers_in.if_modified_since->value.len); | 144 r->headers_in.if_modified_since->value.len); |
108 | 145 |
109 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 146 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
110 "http ims:%d lm:%d", ims, r->headers_out.last_modified_time); | 147 "http ims:%d lm:%d", ims, r->headers_out.last_modified_time); |
111 | 148 |
112 if (ims != r->headers_out.last_modified_time) { | 149 if (ims == r->headers_out.last_modified_time) { |
113 | 150 return 0; |
114 if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT | 151 } |
115 || ims < r->headers_out.last_modified_time) | 152 |
116 { | 153 if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT |
117 return ngx_http_next_header_filter(r); | 154 || ims < r->headers_out.last_modified_time) |
118 } | 155 { |
119 } | 156 return 1; |
120 | 157 } |
121 r->headers_out.status = NGX_HTTP_NOT_MODIFIED; | 158 |
122 r->headers_out.status_line.len = 0; | 159 return 0; |
123 r->headers_out.content_type.len = 0; | 160 } |
124 ngx_http_clear_content_length(r); | 161 |
125 ngx_http_clear_accept_ranges(r); | 162 |
126 | 163 static ngx_uint_t |
127 if (r->headers_out.content_encoding) { | 164 ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header) |
128 r->headers_out.content_encoding->hash = 0; | 165 { |
129 r->headers_out.content_encoding = NULL; | 166 u_char *start, *end, ch; |
130 } | 167 ngx_str_t *etag, *list; |
131 | 168 |
132 return ngx_http_next_header_filter(r); | 169 list = &header->value; |
170 | |
171 if (list->len == 1 && list->data[0] == '*') { | |
172 return 1; | |
173 } | |
174 | |
175 if (r->headers_out.etag == NULL) { | |
176 return 0; | |
177 } | |
178 | |
179 etag = &r->headers_out.etag->value; | |
180 | |
181 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
182 "http im:\"%V\" etag:%V", list, etag); | |
183 | |
184 start = list->data; | |
185 end = list->data + list->len; | |
186 | |
187 while (start < end) { | |
188 | |
189 if (etag->len > (size_t) (end - start)) { | |
190 return 0; | |
191 } | |
192 | |
193 if (ngx_strncmp(start, etag->data, etag->len) != 0) { | |
194 goto skip; | |
195 } | |
196 | |
197 start += etag->len; | |
198 | |
199 while (start < end) { | |
200 ch = *start; | |
201 | |
202 if (ch == ' ' || ch == '\t') { | |
203 start++; | |
204 continue; | |
205 } | |
206 | |
207 break; | |
208 } | |
209 | |
210 if (start == end || *start == ',') { | |
211 return 1; | |
212 } | |
213 | |
214 skip: | |
215 | |
216 while (start < end && *start != ',') { start++; } | |
217 while (start < end) { | |
218 ch = *start; | |
219 | |
220 if (ch == ' ' || ch == '\t' || ch == ',') { | |
221 start++; | |
222 continue; | |
223 } | |
224 | |
225 break; | |
226 } | |
227 } | |
228 | |
229 return 0; | |
133 } | 230 } |
134 | 231 |
135 | 232 |
136 static ngx_int_t | 233 static ngx_int_t |
137 ngx_http_not_modified_filter_init(ngx_conf_t *cf) | 234 ngx_http_not_modified_filter_init(ngx_conf_t *cf) |