Mercurial > hg > nginx
comparison src/http/modules/ngx_http_headers_filter_module.c @ 1366:279210f24408
move "Expires" header code to a separate function
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 01 Aug 2007 19:32:58 +0000 |
parents | d1dc7ef7c3ce |
children | b318cdca3aac |
comparison
equal
deleted
inserted
replaced
1365:d1dc7ef7c3ce | 1366:279210f24408 |
---|---|
41 #define NGX_HTTP_EXPIRES_OFF -2147483646 | 41 #define NGX_HTTP_EXPIRES_OFF -2147483646 |
42 #define NGX_HTTP_EXPIRES_EPOCH -2147483645 | 42 #define NGX_HTTP_EXPIRES_EPOCH -2147483645 |
43 #define NGX_HTTP_EXPIRES_MAX -2147483644 | 43 #define NGX_HTTP_EXPIRES_MAX -2147483644 |
44 | 44 |
45 | 45 |
46 static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r, | |
47 ngx_http_headers_conf_t *conf); | |
46 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r, | 48 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r, |
47 ngx_http_header_val_t *hv, ngx_str_t *value); | 49 ngx_http_header_val_t *hv, ngx_str_t *value); |
48 static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r, | 50 static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r, |
49 ngx_http_header_val_t *hv, ngx_str_t *value); | 51 ngx_http_header_val_t *hv, ngx_str_t *value); |
50 | 52 |
127 | 129 |
128 | 130 |
129 static ngx_int_t | 131 static ngx_int_t |
130 ngx_http_headers_filter(ngx_http_request_t *r) | 132 ngx_http_headers_filter(ngx_http_request_t *r) |
131 { | 133 { |
132 size_t len; | |
133 ngx_str_t value; | 134 ngx_str_t value; |
134 ngx_uint_t i; | 135 ngx_uint_t i; |
135 ngx_table_elt_t *expires, *cc, **ccp; | |
136 ngx_http_header_val_t *h; | 136 ngx_http_header_val_t *h; |
137 ngx_http_headers_conf_t *conf; | 137 ngx_http_headers_conf_t *conf; |
138 | 138 |
139 if (r != r->main | 139 conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); |
140 | |
141 if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL) | |
142 || r != r->main | |
140 || (r->headers_out.status != NGX_HTTP_OK | 143 || (r->headers_out.status != NGX_HTTP_OK |
141 && r->headers_out.status != NGX_HTTP_NO_CONTENT | 144 && r->headers_out.status != NGX_HTTP_NO_CONTENT |
142 && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY | 145 && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY |
143 && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY | 146 && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY |
144 && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)) | 147 && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)) |
145 { | 148 { |
146 return ngx_http_next_header_filter(r); | 149 return ngx_http_next_header_filter(r); |
147 } | 150 } |
148 | 151 |
149 conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); | |
150 | |
151 if (conf->expires != NGX_HTTP_EXPIRES_OFF) { | 152 if (conf->expires != NGX_HTTP_EXPIRES_OFF) { |
152 | 153 if (ngx_http_set_expires(r, conf) != NGX_OK) { |
153 expires = r->headers_out.expires; | 154 return NGX_ERROR; |
154 | |
155 if (expires == NULL) { | |
156 | |
157 expires = ngx_list_push(&r->headers_out.headers); | |
158 if (expires == NULL) { | |
159 return NGX_ERROR; | |
160 } | |
161 | |
162 r->headers_out.expires = expires; | |
163 | |
164 expires->hash = 1; | |
165 expires->key.len = sizeof("Expires") - 1; | |
166 expires->key.data = (u_char *) "Expires"; | |
167 } | |
168 | |
169 len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT"); | |
170 expires->value.len = len - 1; | |
171 | |
172 ccp = r->headers_out.cache_control.elts; | |
173 | |
174 if (ccp == NULL) { | |
175 | |
176 if (ngx_array_init(&r->headers_out.cache_control, r->pool, | |
177 1, sizeof(ngx_table_elt_t *)) | |
178 != NGX_OK) | |
179 { | |
180 return NGX_ERROR; | |
181 } | |
182 | |
183 ccp = ngx_array_push(&r->headers_out.cache_control); | |
184 if (ccp == NULL) { | |
185 return NGX_ERROR; | |
186 } | |
187 | |
188 cc = ngx_list_push(&r->headers_out.headers); | |
189 if (cc == NULL) { | |
190 return NGX_ERROR; | |
191 } | |
192 | |
193 cc->hash = 1; | |
194 cc->key.len = sizeof("Cache-Control") - 1; | |
195 cc->key.data = (u_char *) "Cache-Control"; | |
196 | |
197 *ccp = cc; | |
198 | |
199 } else { | |
200 for (i = 1; i < r->headers_out.cache_control.nelts; i++) { | |
201 ccp[i]->hash = 0; | |
202 } | |
203 | |
204 cc = ccp[0]; | |
205 } | |
206 | |
207 if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) { | |
208 expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT"; | |
209 | |
210 cc->value.len = sizeof("no-cache") - 1; | |
211 cc->value.data = (u_char *) "no-cache"; | |
212 | |
213 } else if (conf->expires == NGX_HTTP_EXPIRES_MAX) { | |
214 expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT"; | |
215 | |
216 /* 10 years */ | |
217 cc->value.len = sizeof("max-age=315360000") - 1; | |
218 cc->value.data = (u_char *) "max-age=315360000"; | |
219 | |
220 } else { | |
221 expires->value.data = ngx_palloc(r->pool, len); | |
222 if (expires->value.data == NULL) { | |
223 return NGX_ERROR; | |
224 } | |
225 | |
226 if (conf->expires == 0) { | |
227 ngx_memcpy(expires->value.data, ngx_cached_http_time.data, | |
228 ngx_cached_http_time.len + 1); | |
229 | |
230 cc->value.len = sizeof("max-age=0") - 1; | |
231 cc->value.data = (u_char *) "max-age=0"; | |
232 | |
233 } else { | |
234 ngx_http_time(expires->value.data, ngx_time() + conf->expires); | |
235 | |
236 if (conf->expires < 0) { | |
237 cc->value.len = sizeof("no-cache") - 1; | |
238 cc->value.data = (u_char *) "no-cache"; | |
239 | |
240 } else { | |
241 cc->value.data = ngx_palloc(r->pool, sizeof("max-age=") | |
242 + NGX_TIME_T_LEN + 1); | |
243 if (cc->value.data == NULL) { | |
244 return NGX_ERROR; | |
245 } | |
246 | |
247 cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", | |
248 conf->expires) | |
249 - cc->value.data; | |
250 } | |
251 } | |
252 } | 155 } |
253 } | 156 } |
254 | 157 |
255 if (conf->headers) { | 158 if (conf->headers) { |
256 h = conf->headers->elts; | 159 h = conf->headers->elts; |
277 return ngx_http_next_header_filter(r); | 180 return ngx_http_next_header_filter(r); |
278 } | 181 } |
279 | 182 |
280 | 183 |
281 static ngx_int_t | 184 static ngx_int_t |
282 ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv, | 185 ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) |
283 ngx_str_t *value) | 186 { |
284 { | 187 size_t len; |
285 ngx_table_elt_t *h; | 188 ngx_uint_t i; |
286 | 189 ngx_table_elt_t *expires, *cc, **ccp; |
287 h = ngx_list_push(&r->headers_out.headers); | 190 |
288 if (h == NULL) { | 191 expires = r->headers_out.expires; |
289 return NGX_ERROR; | 192 |
290 } | 193 if (expires == NULL) { |
291 | 194 |
292 h->hash = hv->value.hash; | 195 expires = ngx_list_push(&r->headers_out.headers); |
293 h->key = hv->value.key; | 196 if (expires == NULL) { |
294 h->value = *value; | 197 return NGX_ERROR; |
295 | 198 } |
296 return NGX_OK; | 199 |
297 } | 200 r->headers_out.expires = expires; |
298 | 201 |
299 | 202 expires->hash = 1; |
300 static ngx_int_t | 203 expires->key.len = sizeof("Expires") - 1; |
301 ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv, | 204 expires->key.data = (u_char *) "Expires"; |
302 ngx_str_t *value) | 205 } |
303 { | 206 |
304 ngx_table_elt_t *cc, **ccp; | 207 len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT"); |
208 expires->value.len = len - 1; | |
305 | 209 |
306 ccp = r->headers_out.cache_control.elts; | 210 ccp = r->headers_out.cache_control.elts; |
307 | 211 |
308 if (ccp == NULL) { | 212 if (ccp == NULL) { |
309 | 213 |
311 1, sizeof(ngx_table_elt_t *)) | 215 1, sizeof(ngx_table_elt_t *)) |
312 != NGX_OK) | 216 != NGX_OK) |
313 { | 217 { |
314 return NGX_ERROR; | 218 return NGX_ERROR; |
315 } | 219 } |
220 | |
221 ccp = ngx_array_push(&r->headers_out.cache_control); | |
222 if (ccp == NULL) { | |
223 return NGX_ERROR; | |
224 } | |
225 | |
226 cc = ngx_list_push(&r->headers_out.headers); | |
227 if (cc == NULL) { | |
228 return NGX_ERROR; | |
229 } | |
230 | |
231 cc->hash = 1; | |
232 cc->key.len = sizeof("Cache-Control") - 1; | |
233 cc->key.data = (u_char *) "Cache-Control"; | |
234 | |
235 *ccp = cc; | |
236 | |
237 } else { | |
238 for (i = 1; i < r->headers_out.cache_control.nelts; i++) { | |
239 ccp[i]->hash = 0; | |
240 } | |
241 | |
242 cc = ccp[0]; | |
243 } | |
244 | |
245 if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) { | |
246 expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT"; | |
247 | |
248 cc->value.len = sizeof("no-cache") - 1; | |
249 cc->value.data = (u_char *) "no-cache"; | |
250 | |
251 return NGX_OK; | |
252 } | |
253 | |
254 if (conf->expires == NGX_HTTP_EXPIRES_MAX) { | |
255 expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT"; | |
256 | |
257 /* 10 years */ | |
258 cc->value.len = sizeof("max-age=315360000") - 1; | |
259 cc->value.data = (u_char *) "max-age=315360000"; | |
260 | |
261 return NGX_OK; | |
262 } | |
263 | |
264 expires->value.data = ngx_palloc(r->pool, len); | |
265 if (expires->value.data == NULL) { | |
266 return NGX_ERROR; | |
267 } | |
268 | |
269 if (conf->expires == 0) { | |
270 ngx_memcpy(expires->value.data, ngx_cached_http_time.data, | |
271 ngx_cached_http_time.len + 1); | |
272 | |
273 cc->value.len = sizeof("max-age=0") - 1; | |
274 cc->value.data = (u_char *) "max-age=0"; | |
275 | |
276 return NGX_OK; | |
277 } | |
278 | |
279 ngx_http_time(expires->value.data, ngx_time() + conf->expires); | |
280 | |
281 if (conf->expires < 0) { | |
282 cc->value.len = sizeof("no-cache") - 1; | |
283 cc->value.data = (u_char *) "no-cache"; | |
284 | |
285 return NGX_OK; | |
286 } | |
287 | |
288 cc->value.data = ngx_palloc(r->pool, | |
289 sizeof("max-age=") + NGX_TIME_T_LEN + 1); | |
290 if (cc->value.data == NULL) { | |
291 return NGX_ERROR; | |
292 } | |
293 | |
294 cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", conf->expires) | |
295 - cc->value.data; | |
296 | |
297 return NGX_OK; | |
298 } | |
299 | |
300 | |
301 static ngx_int_t | |
302 ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv, | |
303 ngx_str_t *value) | |
304 { | |
305 ngx_table_elt_t *h; | |
306 | |
307 h = ngx_list_push(&r->headers_out.headers); | |
308 if (h == NULL) { | |
309 return NGX_ERROR; | |
310 } | |
311 | |
312 h->hash = hv->value.hash; | |
313 h->key = hv->value.key; | |
314 h->value = *value; | |
315 | |
316 return NGX_OK; | |
317 } | |
318 | |
319 | |
320 static ngx_int_t | |
321 ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv, | |
322 ngx_str_t *value) | |
323 { | |
324 ngx_table_elt_t *cc, **ccp; | |
325 | |
326 ccp = r->headers_out.cache_control.elts; | |
327 | |
328 if (ccp == NULL) { | |
329 | |
330 if (ngx_array_init(&r->headers_out.cache_control, r->pool, | |
331 1, sizeof(ngx_table_elt_t *)) | |
332 != NGX_OK) | |
333 { | |
334 return NGX_ERROR; | |
335 } | |
316 } | 336 } |
317 | 337 |
318 ccp = ngx_array_push(&r->headers_out.cache_control); | 338 ccp = ngx_array_push(&r->headers_out.cache_control); |
319 if (ccp == NULL) { | 339 if (ccp == NULL) { |
320 return NGX_ERROR; | 340 return NGX_ERROR; |
380 } | 400 } |
381 | 401 |
382 /* | 402 /* |
383 * set by ngx_pcalloc(): | 403 * set by ngx_pcalloc(): |
384 * | 404 * |
385 * conf->cache_control.len = 0; | |
386 * conf->cache_control.data = NULL; | |
387 * conf->headers = NULL; | 405 * conf->headers = NULL; |
388 */ | 406 */ |
389 | 407 |
390 conf->expires = NGX_HTTP_EXPIRES_UNSET; | 408 conf->expires = NGX_HTTP_EXPIRES_UNSET; |
391 | 409 |