Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_headers_filter_module.c @ 5942:4983f7d18fe3
Headers filter: variables support in expires (ticket #113).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 11 Dec 2014 23:42:11 +0300 |
parents | 36e61455a8f4 |
children | 173561dfd567 |
comparison
equal
deleted
inserted
replaced
5941:36e61455a8f4 | 5942:4983f7d18fe3 |
---|---|
42 NGX_HTTP_EXPIRES_UNSET | 42 NGX_HTTP_EXPIRES_UNSET |
43 } ngx_http_expires_t; | 43 } ngx_http_expires_t; |
44 | 44 |
45 | 45 |
46 typedef struct { | 46 typedef struct { |
47 ngx_http_expires_t expires; | 47 ngx_http_expires_t expires; |
48 time_t expires_time; | 48 time_t expires_time; |
49 ngx_array_t *headers; | 49 ngx_http_complex_value_t *expires_value; |
50 ngx_array_t *headers; | |
50 } ngx_http_headers_conf_t; | 51 } ngx_http_headers_conf_t; |
51 | 52 |
52 | 53 |
53 static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r, | 54 static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r, |
54 ngx_http_headers_conf_t *conf); | 55 ngx_http_headers_conf_t *conf); |
56 static ngx_int_t ngx_http_parse_expires(ngx_str_t *value, | |
57 ngx_http_expires_t *expires, time_t *expires_time, char **err); | |
55 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r, | 58 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r, |
56 ngx_http_header_val_t *hv, ngx_str_t *value); | 59 ngx_http_header_val_t *hv, ngx_str_t *value); |
57 static ngx_int_t ngx_http_add_header(ngx_http_request_t *r, | 60 static ngx_int_t ngx_http_add_header(ngx_http_request_t *r, |
58 ngx_http_header_val_t *hv, ngx_str_t *value); | 61 ngx_http_header_val_t *hv, ngx_str_t *value); |
59 static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r, | 62 static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r, |
207 | 210 |
208 | 211 |
209 static ngx_int_t | 212 static ngx_int_t |
210 ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) | 213 ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) |
211 { | 214 { |
215 char *err; | |
212 size_t len; | 216 size_t len; |
213 time_t now, expires_time, max_age; | 217 time_t now, expires_time, max_age; |
218 ngx_str_t value; | |
219 ngx_int_t rc; | |
214 ngx_uint_t i; | 220 ngx_uint_t i; |
215 ngx_table_elt_t *e, *cc, **ccp; | 221 ngx_table_elt_t *e, *cc, **ccp; |
216 ngx_http_expires_t expires; | 222 ngx_http_expires_t expires; |
217 | 223 |
218 expires = conf->expires; | 224 expires = conf->expires; |
219 expires_time = conf->expires_time; | 225 expires_time = conf->expires_time; |
226 | |
227 if (conf->expires_value != NULL) { | |
228 | |
229 if (ngx_http_complex_value(r, conf->expires_value, &value) != NGX_OK) { | |
230 return NGX_ERROR; | |
231 } | |
232 | |
233 rc = ngx_http_parse_expires(&value, &expires, &expires_time, &err); | |
234 | |
235 if (rc != NGX_OK) { | |
236 return NGX_OK; | |
237 } | |
238 | |
239 if (expires == NGX_HTTP_EXPIRES_OFF) { | |
240 return NGX_OK; | |
241 } | |
242 } | |
220 | 243 |
221 e = r->headers_out.expires; | 244 e = r->headers_out.expires; |
222 | 245 |
223 if (e == NULL) { | 246 if (e == NULL) { |
224 | 247 |
330 return NGX_OK; | 353 return NGX_OK; |
331 } | 354 } |
332 | 355 |
333 | 356 |
334 static ngx_int_t | 357 static ngx_int_t |
358 ngx_http_parse_expires(ngx_str_t *value, ngx_http_expires_t *expires, | |
359 time_t *expires_time, char **err) | |
360 { | |
361 ngx_uint_t minus; | |
362 | |
363 if (*expires != NGX_HTTP_EXPIRES_MODIFIED) { | |
364 | |
365 if (value->len == 5 && ngx_strncmp(value->data, "epoch", 5) == 0) { | |
366 *expires = NGX_HTTP_EXPIRES_EPOCH; | |
367 return NGX_OK; | |
368 } | |
369 | |
370 if (value->len == 3 && ngx_strncmp(value->data, "max", 3) == 0) { | |
371 *expires = NGX_HTTP_EXPIRES_MAX; | |
372 return NGX_OK; | |
373 } | |
374 | |
375 if (value->len == 3 && ngx_strncmp(value->data, "off", 3) == 0) { | |
376 *expires = NGX_HTTP_EXPIRES_OFF; | |
377 return NGX_OK; | |
378 } | |
379 } | |
380 | |
381 if (value->data[0] == '@') { | |
382 value->data++; | |
383 value->len--; | |
384 minus = 0; | |
385 | |
386 if (*expires == NGX_HTTP_EXPIRES_MODIFIED) { | |
387 *err = "daily time cannot be used with \"modified\" parameter"; | |
388 return NGX_ERROR; | |
389 } | |
390 | |
391 *expires = NGX_HTTP_EXPIRES_DAILY; | |
392 | |
393 } else if (value->data[0] == '+') { | |
394 value->data++; | |
395 value->len--; | |
396 minus = 0; | |
397 | |
398 } else if (value->data[0] == '-') { | |
399 value->data++; | |
400 value->len--; | |
401 minus = 1; | |
402 | |
403 } else { | |
404 minus = 0; | |
405 } | |
406 | |
407 *expires_time = ngx_parse_time(value, 1); | |
408 | |
409 if (*expires_time == (time_t) NGX_ERROR) { | |
410 *err = "invalid value"; | |
411 return NGX_ERROR; | |
412 } | |
413 | |
414 if (*expires == NGX_HTTP_EXPIRES_DAILY | |
415 && *expires_time > 24 * 60 * 60) | |
416 { | |
417 *err = "daily time value must be less than 24 hours"; | |
418 return NGX_ERROR; | |
419 } | |
420 | |
421 if (minus) { | |
422 *expires_time = - *expires_time; | |
423 } | |
424 | |
425 return NGX_OK; | |
426 } | |
427 | |
428 | |
429 static ngx_int_t | |
335 ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv, | 430 ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv, |
336 ngx_str_t *value) | 431 ngx_str_t *value) |
337 { | 432 { |
338 ngx_table_elt_t *h; | 433 ngx_table_elt_t *h; |
339 | 434 |
459 /* | 554 /* |
460 * set by ngx_pcalloc(): | 555 * set by ngx_pcalloc(): |
461 * | 556 * |
462 * conf->headers = NULL; | 557 * conf->headers = NULL; |
463 * conf->expires_time = 0; | 558 * conf->expires_time = 0; |
559 * conf->expires_value = NULL; | |
464 */ | 560 */ |
465 | 561 |
466 conf->expires = NGX_HTTP_EXPIRES_UNSET; | 562 conf->expires = NGX_HTTP_EXPIRES_UNSET; |
467 | 563 |
468 return conf; | 564 return conf; |
476 ngx_http_headers_conf_t *conf = child; | 572 ngx_http_headers_conf_t *conf = child; |
477 | 573 |
478 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { | 574 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { |
479 conf->expires = prev->expires; | 575 conf->expires = prev->expires; |
480 conf->expires_time = prev->expires_time; | 576 conf->expires_time = prev->expires_time; |
577 conf->expires_value = prev->expires_value; | |
481 | 578 |
482 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { | 579 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { |
483 conf->expires = NGX_HTTP_EXPIRES_OFF; | 580 conf->expires = NGX_HTTP_EXPIRES_OFF; |
484 } | 581 } |
485 } | 582 } |
505 static char * | 602 static char * |
506 ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 603 ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
507 { | 604 { |
508 ngx_http_headers_conf_t *hcf = conf; | 605 ngx_http_headers_conf_t *hcf = conf; |
509 | 606 |
510 ngx_uint_t minus, n; | 607 char *err; |
511 ngx_str_t *value; | 608 ngx_str_t *value; |
609 ngx_int_t rc; | |
610 ngx_uint_t n; | |
611 ngx_http_complex_value_t cv; | |
612 ngx_http_compile_complex_value_t ccv; | |
512 | 613 |
513 if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) { | 614 if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) { |
514 return "is duplicate"; | 615 return "is duplicate"; |
515 } | 616 } |
516 | 617 |
517 value = cf->args->elts; | 618 value = cf->args->elts; |
518 | 619 |
519 if (cf->args->nelts == 2) { | 620 if (cf->args->nelts == 2) { |
520 | 621 |
521 if (ngx_strcmp(value[1].data, "epoch") == 0) { | |
522 hcf->expires = NGX_HTTP_EXPIRES_EPOCH; | |
523 return NGX_CONF_OK; | |
524 } | |
525 | |
526 if (ngx_strcmp(value[1].data, "max") == 0) { | |
527 hcf->expires = NGX_HTTP_EXPIRES_MAX; | |
528 return NGX_CONF_OK; | |
529 } | |
530 | |
531 if (ngx_strcmp(value[1].data, "off") == 0) { | |
532 hcf->expires = NGX_HTTP_EXPIRES_OFF; | |
533 return NGX_CONF_OK; | |
534 } | |
535 | |
536 hcf->expires = NGX_HTTP_EXPIRES_ACCESS; | 622 hcf->expires = NGX_HTTP_EXPIRES_ACCESS; |
537 | 623 |
538 n = 1; | 624 n = 1; |
539 | 625 |
540 } else { /* cf->args->nelts == 3 */ | 626 } else { /* cf->args->nelts == 3 */ |
546 hcf->expires = NGX_HTTP_EXPIRES_MODIFIED; | 632 hcf->expires = NGX_HTTP_EXPIRES_MODIFIED; |
547 | 633 |
548 n = 2; | 634 n = 2; |
549 } | 635 } |
550 | 636 |
551 if (value[n].data[0] == '@') { | 637 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
552 value[n].data++; | 638 |
553 value[n].len--; | 639 ccv.cf = cf; |
554 minus = 0; | 640 ccv.value = &value[n]; |
555 | 641 ccv.complex_value = &cv; |
556 if (hcf->expires == NGX_HTTP_EXPIRES_MODIFIED) { | 642 |
557 return "daily time cannot be used with \"modified\" parameter"; | 643 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
558 } | 644 return NGX_CONF_ERROR; |
559 | 645 } |
560 hcf->expires = NGX_HTTP_EXPIRES_DAILY; | 646 |
561 | 647 if (cv.lengths != NULL) { |
562 } else if (value[n].data[0] == '+') { | 648 |
563 value[n].data++; | 649 hcf->expires_value = ngx_palloc(cf->pool, |
564 value[n].len--; | 650 sizeof(ngx_http_complex_value_t)); |
565 minus = 0; | 651 if (hcf->expires_value == NULL) { |
566 | 652 return NGX_CONF_ERROR; |
567 } else if (value[n].data[0] == '-') { | 653 } |
568 value[n].data++; | 654 |
569 value[n].len--; | 655 *hcf->expires_value = cv; |
570 minus = 1; | 656 |
571 | 657 return NGX_CONF_OK; |
572 } else { | 658 } |
573 minus = 0; | 659 |
574 } | 660 rc = ngx_http_parse_expires(&value[n], &hcf->expires, &hcf->expires_time, |
575 | 661 &err); |
576 hcf->expires_time = ngx_parse_time(&value[n], 1); | 662 if (rc != NGX_OK) { |
577 | 663 return err; |
578 if (hcf->expires_time == (time_t) NGX_ERROR) { | |
579 return "invalid value"; | |
580 } | |
581 | |
582 if (hcf->expires == NGX_HTTP_EXPIRES_DAILY | |
583 && hcf->expires_time > 24 * 60 * 60) | |
584 { | |
585 return "daily time value must be less than 24 hours"; | |
586 } | |
587 | |
588 if (minus) { | |
589 hcf->expires_time = - hcf->expires_time; | |
590 } | 664 } |
591 | 665 |
592 return NGX_CONF_OK; | 666 return NGX_CONF_OK; |
593 } | 667 } |
594 | 668 |