comparison src/http/modules/ngx_http_headers_filter_module.c @ 376:d13234035cad NGINX_0_6_32

nginx 0.6.32 *) Change: the "none" parameter in the "ssl_session_cache" directive; now this is default parameter. Thanks to Rob Mueller. *) Change: now the 0x00-0x1F, '"' and '\' characters are escaped as \xXX in an access_log. Thanks to Maxim Dounin. *) Change: now nginx allows several "Host" request header line. *) Feature: the "modified" flag in the "expires" directive. *) Feature: the $uid_got and $uid_set variables may be used at any request processing stage. *) Feature: the $hostname variable. Thanks to Andrei Nigmatulin. *) Feature: DESTDIR support. Thanks to Todd A. Fisher and Andras Voroskoi. *) Bugfix: if sub_filter and SSI were used together, then responses might were transferred incorrectly. *) Bugfix: large SSI inclusions might be truncated. *) Bugfix: the "proxy_pass" directive did not work with the HTTPS protocol; the bug had appeared in 0.6.9. *) Bugfix: worker processes might not catch reconfiguration and log rotation signals. *) Bugfix: nginx could not be built on latest Fedora 9 Linux. Thanks to Roxis. *) Bugfix: a segmentation fault might occur in worker process on Linux, if keepalive was enabled.
author Igor Sysoev <http://sysoev.ru>
date Mon, 07 Jul 2008 00:00:00 +0400
parents e10168d6e371
children 3ce4580ae286
comparison
equal deleted inserted replaced
375:52f3c9c7eff0 376:d13234035cad
29 ngx_array_t *lengths; 29 ngx_array_t *lengths;
30 ngx_array_t *values; 30 ngx_array_t *values;
31 }; 31 };
32 32
33 33
34 #define NGX_HTTP_EXPIRES_OFF 0
35 #define NGX_HTTP_EXPIRES_EPOCH 1
36 #define NGX_HTTP_EXPIRES_MAX 2
37 #define NGX_HTTP_EXPIRES_ACCESS 3
38 #define NGX_HTTP_EXPIRES_MODIFIED 4
39
40
34 typedef struct { 41 typedef struct {
35 time_t expires; 42 ngx_uint_t expires;
43 time_t expires_time;
36 ngx_array_t *headers; 44 ngx_array_t *headers;
37 } ngx_http_headers_conf_t; 45 } ngx_http_headers_conf_t;
38
39
40 #define NGX_HTTP_EXPIRES_UNSET -2147483647
41 #define NGX_HTTP_EXPIRES_OFF -2147483646
42 #define NGX_HTTP_EXPIRES_EPOCH -2147483645
43 #define NGX_HTTP_EXPIRES_MAX -2147483644
44 46
45 47
46 static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r, 48 static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r,
47 ngx_http_headers_conf_t *conf); 49 ngx_http_headers_conf_t *conf);
48 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r, 50 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
74 76
75 static ngx_command_t ngx_http_headers_filter_commands[] = { 77 static ngx_command_t ngx_http_headers_filter_commands[] = {
76 78
77 { ngx_string("expires"), 79 { ngx_string("expires"),
78 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF 80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
79 |NGX_CONF_TAKE1, 81 |NGX_CONF_TAKE12,
80 ngx_http_headers_expires, 82 ngx_http_headers_expires,
81 NGX_HTTP_LOC_CONF_OFFSET, 83 NGX_HTTP_LOC_CONF_OFFSET,
82 0, 84 0,
83 NULL}, 85 NULL},
84 86
183 185
184 static ngx_int_t 186 static ngx_int_t
185 ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) 187 ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
186 { 188 {
187 size_t len; 189 size_t len;
190 time_t since;
188 ngx_uint_t i; 191 ngx_uint_t i;
189 ngx_table_elt_t *expires, *cc, **ccp; 192 ngx_table_elt_t *expires, *cc, **ccp;
190 193
191 expires = r->headers_out.expires; 194 expires = r->headers_out.expires;
192 195
264 expires->value.data = ngx_palloc(r->pool, len); 267 expires->value.data = ngx_palloc(r->pool, len);
265 if (expires->value.data == NULL) { 268 if (expires->value.data == NULL) {
266 return NGX_ERROR; 269 return NGX_ERROR;
267 } 270 }
268 271
269 if (conf->expires == 0) { 272 if (conf->expires_time == 0) {
270 ngx_memcpy(expires->value.data, ngx_cached_http_time.data, 273 ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
271 ngx_cached_http_time.len + 1); 274 ngx_cached_http_time.len + 1);
272 275
273 cc->value.len = sizeof("max-age=0") - 1; 276 cc->value.len = sizeof("max-age=0") - 1;
274 cc->value.data = (u_char *) "max-age=0"; 277 cc->value.data = (u_char *) "max-age=0";
275 278
276 return NGX_OK; 279 return NGX_OK;
277 } 280 }
278 281
279 ngx_http_time(expires->value.data, ngx_time() + conf->expires); 282 if (conf->expires == NGX_HTTP_EXPIRES_ACCESS
280 283 || r->headers_out.last_modified_time == -1)
281 if (conf->expires < 0) { 284 {
285 since = ngx_time();
286
287 } else {
288 since = r->headers_out.last_modified_time;
289 }
290
291 ngx_http_time(expires->value.data, since + conf->expires_time);
292
293 if (conf->expires_time < 0) {
282 cc->value.len = sizeof("no-cache") - 1; 294 cc->value.len = sizeof("no-cache") - 1;
283 cc->value.data = (u_char *) "no-cache"; 295 cc->value.data = (u_char *) "no-cache";
284 296
285 return NGX_OK; 297 return NGX_OK;
286 } 298 }
289 sizeof("max-age=") + NGX_TIME_T_LEN + 1); 301 sizeof("max-age=") + NGX_TIME_T_LEN + 1);
290 if (cc->value.data == NULL) { 302 if (cc->value.data == NULL) {
291 return NGX_ERROR; 303 return NGX_ERROR;
292 } 304 }
293 305
294 cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", conf->expires) 306 cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
307 since + conf->expires_time - ngx_time())
295 - cc->value.data; 308 - cc->value.data;
296 309
297 return NGX_OK; 310 return NGX_OK;
298 } 311 }
299 312
411 424
412 /* 425 /*
413 * set by ngx_pcalloc(): 426 * set by ngx_pcalloc():
414 * 427 *
415 * conf->headers = NULL; 428 * conf->headers = NULL;
429 * conf->expires_time = 0;
416 */ 430 */
417 431
418 conf->expires = NGX_HTTP_EXPIRES_UNSET; 432 conf->expires = NGX_CONF_UNSET_UINT;
419 433
420 return conf; 434 return conf;
421 } 435 }
422 436
423 437
425 ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child) 439 ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
426 { 440 {
427 ngx_http_headers_conf_t *prev = parent; 441 ngx_http_headers_conf_t *prev = parent;
428 ngx_http_headers_conf_t *conf = child; 442 ngx_http_headers_conf_t *conf = child;
429 443
430 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { 444 if (conf->expires == NGX_CONF_UNSET_UINT) {
431 conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ? 445 conf->expires = prev->expires;
432 NGX_HTTP_EXPIRES_OFF : prev->expires; 446 conf->expires_time = prev->expires_time;
447
448 if (conf->expires == NGX_CONF_UNSET_UINT) {
449 conf->expires = NGX_HTTP_EXPIRES_OFF;
450 }
433 } 451 }
434 452
435 if (conf->headers == NULL) { 453 if (conf->headers == NULL) {
436 conf->headers = prev->headers; 454 conf->headers = prev->headers;
437 } 455 }
453 static char * 471 static char *
454 ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 472 ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
455 { 473 {
456 ngx_http_headers_conf_t *hcf = conf; 474 ngx_http_headers_conf_t *hcf = conf;
457 475
458 ngx_uint_t minus; 476 ngx_uint_t minus, n;
459 ngx_str_t *value; 477 ngx_str_t *value;
460 478
461 if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) { 479 if (hcf->expires != NGX_CONF_UNSET_UINT) {
462 return "is duplicate"; 480 return "is duplicate";
463 } 481 }
464 482
465 value = cf->args->elts; 483 value = cf->args->elts;
466 484
467 if (ngx_strcmp(value[1].data, "epoch") == 0) { 485 if (cf->args->nelts == 2) {
468 hcf->expires = NGX_HTTP_EXPIRES_EPOCH; 486
469 return NGX_CONF_OK; 487 if (ngx_strcmp(value[1].data, "epoch") == 0) {
470 } 488 hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
471 489 return NGX_CONF_OK;
472 if (ngx_strcmp(value[1].data, "max") == 0) { 490 }
473 hcf->expires = NGX_HTTP_EXPIRES_MAX; 491
474 return NGX_CONF_OK; 492 if (ngx_strcmp(value[1].data, "max") == 0) {
475 } 493 hcf->expires = NGX_HTTP_EXPIRES_MAX;
476 494 return NGX_CONF_OK;
477 if (ngx_strcmp(value[1].data, "off") == 0) { 495 }
478 hcf->expires = NGX_HTTP_EXPIRES_OFF; 496
479 return NGX_CONF_OK; 497 if (ngx_strcmp(value[1].data, "off") == 0) {
480 } 498 hcf->expires = NGX_HTTP_EXPIRES_OFF;
481 499 return NGX_CONF_OK;
482 if (value[1].data[0] == '+') { 500 }
483 value[1].data++; 501
484 value[1].len--; 502 hcf->expires = NGX_HTTP_EXPIRES_ACCESS;
503
504 n = 1;
505
506 } else { /* cf->args->nelts == 3 */
507
508 if (ngx_strcmp(value[1].data, "modified") != 0) {
509 return "invalid value";
510 }
511
512 hcf->expires = NGX_HTTP_EXPIRES_MODIFIED;
513
514 n = 2;
515 }
516
517 if (value[n].data[0] == '+') {
518 value[n].data++;
519 value[n].len--;
485 minus = 0; 520 minus = 0;
486 521
487 } else if (value[1].data[0] == '-') { 522 } else if (value[n].data[0] == '-') {
488 value[1].data++; 523 value[n].data++;
489 value[1].len--; 524 value[n].len--;
490 minus = 1; 525 minus = 1;
491 526
492 } else { 527 } else {
493 minus = 0; 528 minus = 0;
494 } 529 }
495 530
496 hcf->expires = ngx_parse_time(&value[1], 1); 531 hcf->expires_time = ngx_parse_time(&value[n], 1);
497 532
498 if (hcf->expires == NGX_ERROR) { 533 if (hcf->expires_time == NGX_ERROR) {
499 return "invalid value"; 534 return "invalid value";
500 } 535 }
501 536
502 if (hcf->expires == NGX_PARSE_LARGE_TIME) { 537 if (hcf->expires_time == NGX_PARSE_LARGE_TIME) {
503 return "value must be less than 68 years"; 538 return "value must be less than 68 years";
504 } 539 }
505 540
506 if (minus) { 541 if (minus) {
507 hcf->expires = - hcf->expires; 542 hcf->expires_time = - hcf->expires_time;
508 } 543 }
509 544
510 return NGX_CONF_OK; 545 return NGX_CONF_OK;
511 } 546 }
512 547