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 {