comparison src/http/modules/ngx_http_headers_filter_module.c @ 1363:b0e114fb3bdc

use header specific handler in add_handler, "Last-Modified" header handler
author Igor Sysoev <igor@sysoev.ru>
date Wed, 01 Aug 2007 14:01:30 +0000
parents db7c468c447d
children b7a8c9fe2337
comparison
equal deleted inserted replaced
1362:8dcb9eb5e25a 1363:b0e114fb3bdc
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 10
11 11
12 typedef struct ngx_http_header_val_s ngx_http_header_val_t;
13
14 typedef ngx_int_t (*ngx_http_set_header_pt)(ngx_http_request_t *r,
15 ngx_http_header_val_t *hv, ngx_str_t *value);
16
17
12 typedef struct { 18 typedef struct {
13 ngx_table_elt_t value; 19 ngx_str_t name;
14 ngx_array_t *lengths; 20 ngx_uint_t offset;
15 ngx_array_t *values; 21 ngx_http_set_header_pt handler;
16 } ngx_http_header_val_t; 22 } ngx_http_set_header_t;
23
24
25 struct ngx_http_header_val_s {
26 ngx_table_elt_t value;
27 ngx_uint_t offset;
28 ngx_http_set_header_pt handler;
29 ngx_array_t *lengths;
30 ngx_array_t *values;
31 };
17 32
18 33
19 typedef struct { 34 typedef struct {
20 time_t expires; 35 time_t expires;
21 ngx_str_t cache_control; 36 ngx_str_t cache_control;
22 ngx_array_t *headers; 37 ngx_array_t *headers;
23 } ngx_http_headers_conf_t; 38 } ngx_http_headers_conf_t;
24 39
25 40
26 #define NGX_HTTP_EXPIRES_UNSET -2147483647 41 #define NGX_HTTP_EXPIRES_UNSET -2147483647
27 #define NGX_HTTP_EXPIRES_OFF -2147483646 42 #define NGX_HTTP_EXPIRES_OFF -2147483646
28 #define NGX_HTTP_EXPIRES_EPOCH -2147483645 43 #define NGX_HTTP_EXPIRES_EPOCH -2147483645
29 #define NGX_HTTP_EXPIRES_MAX -2147483644 44 #define NGX_HTTP_EXPIRES_MAX -2147483644
30 45
46
47 static ngx_int_t ngx_http_add_header(ngx_http_request_t *r,
48 ngx_http_header_val_t *hv, ngx_str_t *value);
49 static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r,
50 ngx_http_header_val_t *hv, ngx_str_t *value);
31 51
32 static void *ngx_http_headers_create_conf(ngx_conf_t *cf); 52 static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
33 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, 53 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
34 void *parent, void *child); 54 void *parent, void *child);
35 static ngx_int_t ngx_http_headers_filter_init(ngx_conf_t *cf); 55 static ngx_int_t ngx_http_headers_filter_init(ngx_conf_t *cf);
36 static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, 56 static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd,
37 void *conf); 57 void *conf);
38 static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, 58 static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
39 void *conf); 59 void *conf);
60
61
62 static ngx_http_set_header_t ngx_http_set_headers[] = {
63
64 { ngx_string("Last-Modified"),
65 offsetof(ngx_http_headers_out_t, last_modified),
66 ngx_http_set_last_modified },
67
68 { ngx_null_string, 0, NULL }
69 };
40 70
41 71
42 static ngx_command_t ngx_http_headers_filter_commands[] = { 72 static ngx_command_t ngx_http_headers_filter_commands[] = {
43 73
44 { ngx_string("expires"), 74 { ngx_string("expires"),
97 127
98 static ngx_int_t 128 static ngx_int_t
99 ngx_http_headers_filter(ngx_http_request_t *r) 129 ngx_http_headers_filter(ngx_http_request_t *r)
100 { 130 {
101 size_t len; 131 size_t len;
132 ngx_str_t value;
102 ngx_uint_t i; 133 ngx_uint_t i;
103 ngx_table_elt_t *expires, *cc, **ccp, *out; 134 ngx_table_elt_t *expires, *cc, **ccp;
104 ngx_http_header_val_t *h; 135 ngx_http_header_val_t *h;
105 ngx_http_headers_conf_t *conf; 136 ngx_http_headers_conf_t *conf;
106 137
107 if (r != r->main 138 if (r != r->main
108 || (r->headers_out.status != NGX_HTTP_OK 139 || (r->headers_out.status != NGX_HTTP_OK
253 } 284 }
254 285
255 if (conf->headers) { 286 if (conf->headers) {
256 h = conf->headers->elts; 287 h = conf->headers->elts;
257 for (i = 0; i < conf->headers->nelts; i++) { 288 for (i = 0; i < conf->headers->nelts; i++) {
258 out = ngx_list_push(&r->headers_out.headers);
259 if (out == NULL) {
260 return NGX_ERROR;
261 }
262
263 out->hash = h[i].value.hash;
264 out->key = h[i].value.key;
265 289
266 if (h[i].lengths == NULL) { 290 if (h[i].lengths == NULL) {
267 out->value = h[i].value.value; 291 value = h[i].value.value;
268 continue; 292
269 } 293 } else {
270 294 if (ngx_http_script_run(r, &value, h[i].lengths->elts, 0,
271 if (ngx_http_script_run(r, &out->value, h[i].lengths->elts, 0, 295 h[i].values->elts)
272 h[i].values->elts) 296 == NULL)
273 == NULL) 297 {
274 { 298 return NGX_ERROR;
299 }
300 }
301
302 if (h[i].handler(r, &h[i], &value) != NGX_OK) {
275 return NGX_ERROR; 303 return NGX_ERROR;
276 } 304 }
277 } 305 }
278 } 306 }
279 307
280 return ngx_http_next_header_filter(r); 308 return ngx_http_next_header_filter(r);
309 }
310
311
312 static ngx_int_t
313 ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
314 ngx_str_t *value)
315 {
316 ngx_table_elt_t *h;
317
318 h = ngx_list_push(&r->headers_out.headers);
319 if (h == NULL) {
320 return NGX_ERROR;
321 }
322
323 h->hash = hv->value.hash;
324 h->key = hv->value.key;
325 h->value = *value;
326
327 return NGX_OK;
328 }
329
330
331 static ngx_int_t
332 ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
333 ngx_str_t *value)
334 {
335 ngx_table_elt_t *h, **old;
336
337 if (hv->offset) {
338 old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
339
340 } else {
341 old = NULL;
342 }
343
344 if (old == NULL || *old == NULL) {
345 h = ngx_list_push(&r->headers_out.headers);
346 if (h == NULL) {
347 return NGX_ERROR;
348 }
349
350 } else {
351 h = *old;
352 }
353
354 h->hash = hv->value.hash;
355 h->key = hv->value.key;
356 h->value = *value;
357
358 r->headers_out.last_modified_time = -1;
359
360 return NGX_OK;
281 } 361 }
282 362
283 363
284 static void * 364 static void *
285 ngx_http_headers_create_conf(ngx_conf_t *cf) 365 ngx_http_headers_create_conf(ngx_conf_t *cf)
404 { 484 {
405 ngx_http_headers_conf_t *hcf = conf; 485 ngx_http_headers_conf_t *hcf = conf;
406 486
407 ngx_int_t n; 487 ngx_int_t n;
408 ngx_str_t *value; 488 ngx_str_t *value;
489 ngx_uint_t i;
409 ngx_http_header_val_t *h; 490 ngx_http_header_val_t *h;
491 ngx_http_set_header_t *sh;
410 ngx_http_script_compile_t sc; 492 ngx_http_script_compile_t sc;
411 493
412 value = cf->args->elts; 494 value = cf->args->elts;
413 495
414 if (ngx_strcasecmp(value[1].data, (u_char *) "cache-control") == 0) { 496 if (ngx_strcasecmp(value[1].data, (u_char *) "cache-control") == 0) {
430 } 512 }
431 513
432 h->value.hash = 1; 514 h->value.hash = 1;
433 h->value.key = value[1]; 515 h->value.key = value[1];
434 h->value.value = value[2]; 516 h->value.value = value[2];
517 h->offset = 0;
518 h->handler = ngx_http_add_header;
435 h->lengths = NULL; 519 h->lengths = NULL;
436 h->values = NULL; 520 h->values = NULL;
521
522 sh = ngx_http_set_headers;
523 for (i = 0; sh[i].name.len; i++) {
524 if (ngx_strcasecmp(value[1].data, sh[i].name.data) != 0) {
525 continue;
526 }
527
528 h->offset = sh[i].offset;
529 h->handler = sh[i].handler;
530 break;
531 }
437 532
438 n = ngx_http_script_variables_count(&value[2]); 533 n = ngx_http_script_variables_count(&value[2]);
439 534
440 if (n == 0) { 535 if (n == 0) {
441 return NGX_CONF_OK; 536 return NGX_CONF_OK;