Mercurial > hg > nginx
comparison src/http/ngx_http_upstream.c @ 3092:4f28e63e42b4 stable-0.7
merge r2953, r2958, r3084:
*) $upstream_cache_status
*) clean cache updating state if a response has uncacheable code or
cache prohibitive headers
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 07 Sep 2009 09:49:51 +0000 |
parents | b0c1ce16b5bd |
children | df9d91bb1e5a |
comparison
equal
deleted
inserted
replaced
3091:ecc8d537e9a9 | 3092:4f28e63e42b4 |
---|---|
12 #if (NGX_HTTP_CACHE) | 12 #if (NGX_HTTP_CACHE) |
13 static ngx_int_t ngx_http_upstream_cache(ngx_http_request_t *r, | 13 static ngx_int_t ngx_http_upstream_cache(ngx_http_request_t *r, |
14 ngx_http_upstream_t *u); | 14 ngx_http_upstream_t *u); |
15 static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r, | 15 static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r, |
16 ngx_http_upstream_t *u); | 16 ngx_http_upstream_t *u); |
17 static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r, | |
18 ngx_http_variable_value_t *v, uintptr_t data); | |
17 #endif | 19 #endif |
18 | 20 |
19 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); | 21 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); |
20 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); | 22 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); |
21 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); | 23 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); |
314 | 316 |
315 { ngx_string("upstream_response_length"), NULL, | 317 { ngx_string("upstream_response_length"), NULL, |
316 ngx_http_upstream_response_length_variable, 0, | 318 ngx_http_upstream_response_length_variable, 0, |
317 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 319 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
318 | 320 |
321 #if (NGX_HTTP_CACHE) | |
322 | |
323 { ngx_string("upstream_cache_status"), NULL, | |
324 ngx_http_upstream_cache_status, 0, | |
325 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
326 | |
327 #endif | |
328 | |
319 { ngx_null_string, NULL, NULL, 0, 0, 0 } | 329 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
320 }; | 330 }; |
321 | 331 |
322 | 332 |
323 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = { | 333 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = { |
573 | 583 |
574 c->min_uses = u->conf->cache_min_uses; | 584 c->min_uses = u->conf->cache_min_uses; |
575 c->body_start = u->conf->buffer_size; | 585 c->body_start = u->conf->buffer_size; |
576 c->file_cache = u->conf->cache->data; | 586 c->file_cache = u->conf->cache->data; |
577 | 587 |
588 u->cache_status = NGX_HTTP_CACHE_MISS; | |
589 | |
578 rc = ngx_http_file_cache_open(r); | 590 rc = ngx_http_file_cache_open(r); |
579 | 591 |
580 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 592 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
581 "http upstream cache: %i", rc); | 593 "http upstream cache: %i", rc); |
582 | 594 |
583 if (rc == NGX_HTTP_CACHE_UPDATING) { | 595 switch (rc) { |
596 | |
597 case NGX_HTTP_CACHE_UPDATING: | |
598 | |
584 if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) { | 599 if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) { |
600 u->cache_status = rc; | |
585 rc = NGX_OK; | 601 rc = NGX_OK; |
586 | 602 |
587 } else { | 603 } else { |
588 rc = NGX_HTTP_CACHE_STALE; | 604 rc = NGX_HTTP_CACHE_STALE; |
589 } | 605 } |
590 } | 606 |
591 | 607 break; |
592 if (rc == NGX_OK) { | 608 |
609 case NGX_OK: | |
610 u->cache_status = NGX_HTTP_CACHE_HIT; | |
611 } | |
612 | |
613 switch (rc) { | |
614 | |
615 case NGX_OK: | |
593 | 616 |
594 rc = ngx_http_upstream_cache_send(r, u); | 617 rc = ngx_http_upstream_cache_send(r, u); |
595 | 618 |
596 if (rc != NGX_HTTP_UPSTREAM_INVALID_HEADER) { | 619 if (rc != NGX_HTTP_UPSTREAM_INVALID_HEADER) { |
597 return rc; | 620 return rc; |
598 } | 621 } |
599 | 622 |
600 } else if (rc == NGX_ERROR) { | 623 break; |
624 | |
625 case NGX_ERROR: | |
601 | 626 |
602 return NGX_ERROR; | 627 return NGX_ERROR; |
603 | 628 |
604 } else if (rc == NGX_HTTP_CACHE_STALE) { | 629 case NGX_HTTP_CACHE_STALE: |
605 | 630 |
606 c->valid_sec = 0; | 631 c->valid_sec = 0; |
607 u->stale_cache = 1; | |
608 u->buffer.start = NULL; | 632 u->buffer.start = NULL; |
609 | 633 u->cache_status = NGX_HTTP_CACHE_EXPIRED; |
610 } else if (rc == NGX_DECLINED) { | 634 |
635 break; | |
636 | |
637 case NGX_DECLINED: | |
611 | 638 |
612 if ((size_t) (u->buffer.end - u->buffer.start) < u->conf->buffer_size) { | 639 if ((size_t) (u->buffer.end - u->buffer.start) < u->conf->buffer_size) { |
613 u->buffer.start = NULL; | 640 u->buffer.start = NULL; |
614 | 641 |
615 } else { | 642 } else { |
616 u->buffer.pos = u->buffer.start + c->header_start; | 643 u->buffer.pos = u->buffer.start + c->header_start; |
617 u->buffer.last = u->buffer.pos; | 644 u->buffer.last = u->buffer.pos; |
618 } | 645 } |
619 | 646 |
620 } else if (rc == NGX_AGAIN) { | 647 break; |
648 | |
649 case NGX_AGAIN: | |
621 | 650 |
622 u->cacheable = 0; | 651 u->cacheable = 0; |
623 | 652 |
624 } else { | 653 break; |
654 | |
655 default: | |
625 | 656 |
626 /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */ | 657 /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */ |
658 | |
659 u->cache_status = NGX_HTTP_CACHE_HIT; | |
627 | 660 |
628 return rc; | 661 return rc; |
629 } | 662 } |
630 | 663 |
631 r->cached = 0; | 664 r->cached = 0; |
638 ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u) | 671 ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u) |
639 { | 672 { |
640 ngx_int_t rc; | 673 ngx_int_t rc; |
641 ngx_http_cache_t *c; | 674 ngx_http_cache_t *c; |
642 | 675 |
676 r->cached = 1; | |
643 c = r->cache; | 677 c = r->cache; |
644 | 678 |
645 /* TODO: cache stack */ | 679 /* TODO: cache stack */ |
646 | 680 |
647 u->buffer = *c->buf; | 681 u->buffer = *c->buf; |
1519 return NGX_OK; | 1553 return NGX_OK; |
1520 } | 1554 } |
1521 | 1555 |
1522 #if (NGX_HTTP_CACHE) | 1556 #if (NGX_HTTP_CACHE) |
1523 | 1557 |
1524 if (u->stale_cache && (u->conf->cache_use_stale & un->mask)) { | 1558 if (u->cache_status == NGX_HTTP_CACHE_EXPIRED |
1559 && (u->conf->cache_use_stale & un->mask)) | |
1560 { | |
1525 ngx_int_t rc; | 1561 ngx_int_t rc; |
1526 | 1562 |
1527 rc = u->reinit_request(r); | 1563 rc = u->reinit_request(r); |
1528 | 1564 |
1529 if (rc == NGX_OK) { | 1565 if (rc == NGX_OK) { |
1566 u->cache_status = NGX_HTTP_CACHE_STALE; | |
1530 rc = ngx_http_upstream_cache_send(r, u); | 1567 rc = ngx_http_upstream_cache_send(r, u); |
1531 } | 1568 } |
1532 | 1569 |
1533 ngx_http_upstream_finalize_request(r, u, rc); | 1570 ngx_http_upstream_finalize_request(r, u, rc); |
1534 return NGX_OK; | 1571 return NGX_OK; |
2004 } | 2041 } |
2005 } | 2042 } |
2006 | 2043 |
2007 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2044 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2008 "http cacheable: %d", u->cacheable); | 2045 "http cacheable: %d", u->cacheable); |
2046 | |
2047 if (u->cacheable == 0 && r->cache) { | |
2048 ngx_http_file_cache_free(r, u->pipe->temp_file); | |
2049 } | |
2009 | 2050 |
2010 #endif | 2051 #endif |
2011 | 2052 |
2012 p = u->pipe; | 2053 p = u->pipe; |
2013 | 2054 |
2679 | 2720 |
2680 if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) { | 2721 if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) { |
2681 | 2722 |
2682 #if (NGX_HTTP_CACHE) | 2723 #if (NGX_HTTP_CACHE) |
2683 | 2724 |
2684 if (u->stale_cache && (u->conf->cache_use_stale & ft_type)) { | 2725 if (u->cache_status == NGX_HTTP_CACHE_EXPIRED |
2726 && (u->conf->cache_use_stale & ft_type)) | |
2727 { | |
2685 ngx_int_t rc; | 2728 ngx_int_t rc; |
2686 | 2729 |
2687 rc = u->reinit_request(r); | 2730 rc = u->reinit_request(r); |
2688 | 2731 |
2689 if (rc == NGX_OK) { | 2732 if (rc == NGX_OK) { |
2733 u->cache_status = NGX_HTTP_CACHE_STALE; | |
2690 rc = ngx_http_upstream_cache_send(r, u); | 2734 rc = ngx_http_upstream_cache_send(r, u); |
2691 } | 2735 } |
2692 | 2736 |
2693 ngx_http_upstream_finalize_request(r, u, rc); | 2737 ngx_http_upstream_finalize_request(r, u, rc); |
2694 return; | 2738 return; |
3261 | 3305 |
3262 *ho = *h; | 3306 *ho = *h; |
3263 | 3307 |
3264 #if (NGX_HTTP_CACHE) | 3308 #if (NGX_HTTP_CACHE) |
3265 | 3309 |
3266 if (r->cached || r->upstream->cacheable) { | 3310 if (r->upstream->cacheable) { |
3267 r->headers_out.last_modified = ho; | 3311 r->headers_out.last_modified = ho; |
3268 r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data, | 3312 r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data, |
3269 h->value.len); | 3313 h->value.len); |
3270 } | 3314 } |
3271 | 3315 |
3710 | 3754 |
3711 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, | 3755 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, |
3712 &r->upstream->headers_in.headers.part, | 3756 &r->upstream->headers_in.headers.part, |
3713 sizeof("upstream_http_") - 1); | 3757 sizeof("upstream_http_") - 1); |
3714 } | 3758 } |
3759 | |
3760 | |
3761 #if (NGX_HTTP_CACHE) | |
3762 | |
3763 ngx_int_t | |
3764 ngx_http_upstream_cache_status(ngx_http_request_t *r, | |
3765 ngx_http_variable_value_t *v, uintptr_t data) | |
3766 { | |
3767 ngx_uint_t n; | |
3768 | |
3769 if (r->upstream == NULL || r->upstream->cache_status == 0) { | |
3770 v->not_found = 1; | |
3771 return NGX_OK; | |
3772 } | |
3773 | |
3774 n = r->upstream->cache_status - 1; | |
3775 | |
3776 v->valid = 1; | |
3777 v->no_cacheable = 0; | |
3778 v->not_found = 0; | |
3779 v->len = ngx_http_cache_status[n].len; | |
3780 v->data = ngx_http_cache_status[n].data; | |
3781 | |
3782 return NGX_OK; | |
3783 } | |
3784 | |
3785 #endif | |
3715 | 3786 |
3716 | 3787 |
3717 static char * | 3788 static char * |
3718 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | 3789 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) |
3719 { | 3790 { |