comparison src/http/ngx_http_upstream.c @ 665:0b460e61bdcd default tip

Merge with nginx 1.0.0.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:22:17 +0400
parents b9763778e212
children
comparison
equal deleted inserted replaced
572:06419a2298a9 665:0b460e61bdcd
70 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, 70 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
71 ngx_http_upstream_t *u, ngx_int_t rc); 71 ngx_http_upstream_t *u, ngx_int_t rc);
72 72
73 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, 73 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
74 ngx_table_elt_t *h, ngx_uint_t offset); 74 ngx_table_elt_t *h, ngx_uint_t offset);
75 static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
76 ngx_table_elt_t *h, ngx_uint_t offset);
75 static ngx_int_t 77 static ngx_int_t
76 ngx_http_upstream_process_cache_control(ngx_http_request_t *r, 78 ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
77 ngx_table_elt_t *h, ngx_uint_t offset); 79 ngx_table_elt_t *h, ngx_uint_t offset);
78 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, 80 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
79 ngx_table_elt_t *h, ngx_uint_t offset); 81 ngx_table_elt_t *h, ngx_uint_t offset);
187 { ngx_string("Refresh"), 189 { ngx_string("Refresh"),
188 ngx_http_upstream_ignore_header_line, 0, 190 ngx_http_upstream_ignore_header_line, 0,
189 ngx_http_upstream_rewrite_refresh, 0, 0 }, 191 ngx_http_upstream_rewrite_refresh, 0, 0 },
190 192
191 { ngx_string("Set-Cookie"), 193 { ngx_string("Set-Cookie"),
192 ngx_http_upstream_ignore_header_line, 0, 194 ngx_http_upstream_process_set_cookie, 0,
193 ngx_http_upstream_copy_header_line, 0, 1 }, 195 ngx_http_upstream_copy_header_line, 0, 1 },
194 196
195 { ngx_string("Content-Disposition"), 197 { ngx_string("Content-Disposition"),
196 ngx_http_upstream_ignore_header_line, 0, 198 ngx_http_upstream_ignore_header_line, 0,
197 ngx_http_upstream_copy_header_line, 0, 1 }, 199 ngx_http_upstream_copy_header_line, 0, 1 },
353 { ngx_string("POST"), NGX_HTTP_POST }, 355 { ngx_string("POST"), NGX_HTTP_POST },
354 { ngx_null_string, 0 } 356 { ngx_null_string, 0 }
355 }; 357 };
356 358
357 359
360 ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = {
361 { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT },
362 { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES },
363 { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
364 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
365 { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
366 { ngx_null_string, 0 }
367 };
368
369
358 ngx_int_t 370 ngx_int_t
359 ngx_http_upstream_create(ngx_http_request_t *r) 371 ngx_http_upstream_create(ngx_http_request_t *r)
360 { 372 {
361 ngx_http_upstream_t *u; 373 ngx_http_upstream_t *u;
362 374
363 u = r->upstream; 375 u = r->upstream;
364 376
365 if (u && u->cleanup) { 377 if (u && u->cleanup) {
366 r->main->count++; 378 r->main->count++;
367 ngx_http_upstream_cleanup(r); 379 ngx_http_upstream_cleanup(r);
368 *u->cleanup = NULL;
369 } 380 }
370 381
371 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); 382 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
372 if (u == NULL) { 383 if (u == NULL) {
373 return NGX_ERROR; 384 return NGX_ERROR;
477 if (u->create_request(r) != NGX_OK) { 488 if (u->create_request(r) != NGX_OK) {
478 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 489 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
479 return; 490 return;
480 } 491 }
481 492
493 u->peer.local = u->conf->local;
494
482 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 495 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
483 496
484 u->output.alignment = clcf->directio_alignment; 497 u->output.alignment = clcf->directio_alignment;
485 u->output.pool = r->pool; 498 u->output.pool = r->pool;
486 u->output.bufs.num = 1; 499 u->output.bufs.num = 1;
530 if (u->resolved->sockaddr) { 543 if (u->resolved->sockaddr) {
531 544
532 if (ngx_http_upstream_create_round_robin_peer(r, u->resolved) 545 if (ngx_http_upstream_create_round_robin_peer(r, u->resolved)
533 != NGX_OK) 546 != NGX_OK)
534 { 547 {
535 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 548 ngx_http_upstream_finalize_request(r, u,
549 NGX_HTTP_INTERNAL_SERVER_ERROR);
536 return; 550 return;
537 } 551 }
538 552
539 ngx_http_upstream_connect(r, u); 553 ngx_http_upstream_connect(r, u);
540 554
558 { 572 {
559 goto found; 573 goto found;
560 } 574 }
561 } 575 }
562 576
577 if (u->resolved->port == 0) {
578 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
579 "no port in upstream \"%V\"", host);
580 ngx_http_upstream_finalize_request(r, u,
581 NGX_HTTP_INTERNAL_SERVER_ERROR);
582 return;
583 }
584
563 temp.name = *host; 585 temp.name = *host;
564 586
565 ctx = ngx_resolve_start(clcf->resolver, &temp); 587 ctx = ngx_resolve_start(clcf->resolver, &temp);
566 if (ctx == NULL) { 588 if (ctx == NULL) {
567 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 589 ngx_http_upstream_finalize_request(r, u,
590 NGX_HTTP_INTERNAL_SERVER_ERROR);
568 return; 591 return;
569 } 592 }
570 593
571 if (ctx == NGX_NO_RESOLVER) { 594 if (ctx == NGX_NO_RESOLVER) {
572 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 595 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
573 "no resolver defined to resolve %V", host); 596 "no resolver defined to resolve %V", host);
574 597
575 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); 598 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
576 return; 599 return;
577 } 600 }
578 601
579 ctx->name = *host; 602 ctx->name = *host;
580 ctx->type = NGX_RESOLVE_A; 603 ctx->type = NGX_RESOLVE_A;
584 607
585 u->resolved->ctx = ctx; 608 u->resolved->ctx = ctx;
586 609
587 if (ngx_resolve_name(ctx) != NGX_OK) { 610 if (ngx_resolve_name(ctx) != NGX_OK) {
588 u->resolved->ctx = NULL; 611 u->resolved->ctx = NULL;
589 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 612 ngx_http_upstream_finalize_request(r, u,
613 NGX_HTTP_INTERNAL_SERVER_ERROR);
590 return; 614 return;
591 } 615 }
592 616
593 return; 617 return;
594 } 618 }
595 619
596 found: 620 found:
597 621
598 if (uscf->peer.init(r, uscf) != NGX_OK) { 622 if (uscf->peer.init(r, uscf) != NGX_OK) {
599 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 623 ngx_http_upstream_finalize_request(r, u,
624 NGX_HTTP_INTERNAL_SERVER_ERROR);
600 return; 625 return;
601 } 626 }
602 627
603 ngx_http_upstream_connect(r, u); 628 ngx_http_upstream_connect(r, u);
604 } 629 }
614 639
615 c = r->cache; 640 c = r->cache;
616 641
617 if (c == NULL) { 642 if (c == NULL) {
618 643
644 switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
645
646 case NGX_ERROR:
647 return NGX_ERROR;
648
649 case NGX_DECLINED:
650 u->cache_status = NGX_HTTP_CACHE_BYPASS;
651 return NGX_DECLINED;
652
653 default: /* NGX_OK */
654 break;
655 }
656
619 if (!(r->method & u->conf->cache_methods)) { 657 if (!(r->method & u->conf->cache_methods)) {
620 return NGX_DECLINED; 658 return NGX_DECLINED;
621 } 659 }
622 660
623 if (r->method & NGX_HTTP_HEAD) { 661 if (r->method & NGX_HTTP_HEAD) {
624 u->method = ngx_http_core_get_method; 662 u->method = ngx_http_core_get_method;
625 } 663 }
626 664
627 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); 665 if (ngx_http_file_cache_new(r) != NGX_OK) {
628 if (c == NULL) {
629 return NGX_ERROR; 666 return NGX_ERROR;
630 } 667 }
631
632 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
633 return NGX_ERROR;
634 }
635
636 r->cache = c;
637 c->file.log = r->connection->log;
638 668
639 if (u->create_key(r) != NGX_OK) { 669 if (u->create_key(r) != NGX_OK) {
640 return NGX_ERROR; 670 return NGX_ERROR;
641 } 671 }
642 672
643 /* TODO: add keys */ 673 /* TODO: add keys */
644 674
645 ngx_http_file_cache_create_key(r); 675 ngx_http_file_cache_create_key(r);
646 676
647 u->cacheable = 1; 677 u->cacheable = 1;
678
679 c = r->cache;
648 680
649 c->min_uses = u->conf->cache_min_uses; 681 c->min_uses = u->conf->cache_min_uses;
650 c->body_start = u->conf->buffer_size; 682 c->body_start = u->conf->buffer_size;
651 c->file_cache = u->conf->cache->data; 683 c->file_cache = u->conf->cache->data;
652 684
743 ngx_int_t rc; 775 ngx_int_t rc;
744 ngx_http_cache_t *c; 776 ngx_http_cache_t *c;
745 777
746 r->cached = 1; 778 r->cached = 1;
747 c = r->cache; 779 c = r->cache;
780
781 if (c->header_start == c->body_start) {
782 r->http_version = NGX_HTTP_VERSION_9;
783 return ngx_http_cache_send(r);
784 }
748 785
749 /* TODO: cache stack */ 786 /* TODO: cache stack */
750 787
751 u->buffer = *c->buf; 788 u->buffer = *c->buf;
752 u->buffer.pos += c->header_start; 789 u->buffer.pos += c->header_start;
787 824
788 static void 825 static void
789 ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx) 826 ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
790 { 827 {
791 ngx_http_request_t *r; 828 ngx_http_request_t *r;
829 ngx_http_upstream_t *u;
792 ngx_http_upstream_resolved_t *ur; 830 ngx_http_upstream_resolved_t *ur;
793 831
794 r = ctx->data; 832 r = ctx->data;
795 833
796 r->upstream->resolved->ctx = NULL; 834 u = r->upstream;
835 ur = u->resolved;
797 836
798 if (ctx->state) { 837 if (ctx->state) {
799 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 838 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
800 "%V could not be resolved (%i: %s)", 839 "%V could not be resolved (%i: %s)",
801 &ctx->name, ctx->state, 840 &ctx->name, ctx->state,
802 ngx_resolver_strerror(ctx->state)); 841 ngx_resolver_strerror(ctx->state));
803 842
804 ngx_resolve_name_done(ctx); 843 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
805 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); 844 return;
806 return; 845 }
807 } 846
808
809 ur = r->upstream->resolved;
810 ur->naddrs = ctx->naddrs; 847 ur->naddrs = ctx->naddrs;
811 ur->addrs = ctx->addrs; 848 ur->addrs = ctx->addrs;
812 849
813 #if (NGX_DEBUG) 850 #if (NGX_DEBUG)
814 { 851 {
825 } 862 }
826 } 863 }
827 #endif 864 #endif
828 865
829 if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) { 866 if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
830 ngx_resolve_name_done(ctx); 867 ngx_http_upstream_finalize_request(r, u,
831 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 868 NGX_HTTP_INTERNAL_SERVER_ERROR);
832 return; 869 return;
833 } 870 }
834 871
835 ngx_resolve_name_done(ctx); 872 ngx_resolve_name_done(ctx);
836 873 ur->ctx = NULL;
837 ngx_http_upstream_connect(r, r->upstream); 874
875 ngx_http_upstream_connect(r, u);
838 } 876 }
839 877
840 878
841 static void 879 static void
842 ngx_http_upstream_handler(ngx_event_t *ev) 880 ngx_http_upstream_handler(ngx_event_t *ev)
916 if (!u->cacheable) { 954 if (!u->cacheable) {
917 ngx_http_upstream_finalize_request(r, u, 955 ngx_http_upstream_finalize_request(r, u,
918 NGX_HTTP_CLIENT_CLOSED_REQUEST); 956 NGX_HTTP_CLIENT_CLOSED_REQUEST);
919 } 957 }
920 958
921 return;
922 }
923
924 if (u->peer.connection == NULL) {
925 return; 959 return;
926 } 960 }
927 961
928 #if (NGX_HAVE_KQUEUE) 962 #if (NGX_HAVE_KQUEUE)
929 963
954 "prematurely connection"); 988 "prematurely connection");
955 989
956 if (u->peer.connection == NULL) { 990 if (u->peer.connection == NULL) {
957 ngx_http_upstream_finalize_request(r, u, 991 ngx_http_upstream_finalize_request(r, u,
958 NGX_HTTP_CLIENT_CLOSED_REQUEST); 992 NGX_HTTP_CLIENT_CLOSED_REQUEST);
959 return;
960 } 993 }
961 994
962 return; 995 return;
963 } 996 }
964 997
1017 "client closed prematurely connection"); 1050 "client closed prematurely connection");
1018 1051
1019 if (u->peer.connection == NULL) { 1052 if (u->peer.connection == NULL) {
1020 ngx_http_upstream_finalize_request(r, u, 1053 ngx_http_upstream_finalize_request(r, u,
1021 NGX_HTTP_CLIENT_CLOSED_REQUEST); 1054 NGX_HTTP_CLIENT_CLOSED_REQUEST);
1022 return;
1023 } 1055 }
1024 } 1056 }
1025 1057
1026 1058
1027 static void 1059 static void
1540 return; 1572 return;
1541 } 1573 }
1542 1574
1543 /* rc == NGX_OK */ 1575 /* rc == NGX_OK */
1544 1576
1545 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) { 1577 if (u->headers_in.status_n > NGX_HTTP_SPECIAL_RESPONSE) {
1546 1578
1547 if (r->subrequest_in_memory) { 1579 if (r->subrequest_in_memory) {
1548 u->buffer.last = u->buffer.pos; 1580 u->buffer.last = u->buffer.pos;
1549 } 1581 }
1550 1582
1694 *h = *u->headers_in.www_authenticate; 1726 *h = *u->headers_in.www_authenticate;
1695 1727
1696 r->headers_out.www_authenticate = h; 1728 r->headers_out.www_authenticate = h;
1697 } 1729 }
1698 1730
1731 #if (NGX_HTTP_CACHE)
1732
1733 if (r->cache) {
1734 time_t valid;
1735
1736 valid = ngx_http_file_cache_valid(u->conf->cache_valid, status);
1737
1738 if (valid) {
1739 r->cache->valid_sec = ngx_time() + valid;
1740 r->cache->error = status;
1741 }
1742
1743 ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
1744 }
1745 #endif
1699 ngx_http_upstream_finalize_request(r, u, status); 1746 ngx_http_upstream_finalize_request(r, u, status);
1700 1747
1701 return NGX_OK; 1748 return NGX_OK;
1702 } 1749 }
1703 } 1750 }
1793 } 1840 }
1794 } 1841 }
1795 } 1842 }
1796 1843
1797 uri = &u->headers_in.x_accel_redirect->value; 1844 uri = &u->headers_in.x_accel_redirect->value;
1798 args.len = 0; 1845 ngx_str_null(&args);
1799 args.data = NULL; 1846 flags = NGX_HTTP_LOG_UNSAFE;
1800 flags = 0;
1801 1847
1802 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { 1848 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
1803 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); 1849 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
1804 return NGX_DONE; 1850 return NGX_DONE;
1805 }
1806
1807 if (flags & NGX_HTTP_ZERO_IN_URI) {
1808 r->zero_in_uri = 1;
1809 } 1851 }
1810 1852
1811 if (r->method != NGX_HTTP_HEAD) { 1853 if (r->method != NGX_HTTP_HEAD) {
1812 r->method = NGX_HTTP_GET; 1854 r->method = NGX_HTTP_GET;
1813 } 1855 }
1912 1954
1913 size = b->end - b->last; 1955 size = b->end - b->last;
1914 1956
1915 if (size == 0) { 1957 if (size == 0) {
1916 ngx_log_error(NGX_LOG_ALERT, c->log, 0, 1958 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
1917 "upstream buffer is too small to read repsonse"); 1959 "upstream buffer is too small to read response");
1918 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 1960 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1919 return; 1961 return;
1920 } 1962 }
1921 1963
1922 n = c->recv(c, b->last, size); 1964 n = c->recv(c, b->last, size);
2077 if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) { 2119 if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) {
2078 ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd); 2120 ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd);
2079 r->cache->file.fd = NGX_INVALID_FILE; 2121 r->cache->file.fd = NGX_INVALID_FILE;
2080 } 2122 }
2081 2123
2124 switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
2125
2126 case NGX_ERROR:
2127 ngx_http_upstream_finalize_request(r, u, 0);
2128 return;
2129
2130 case NGX_DECLINED:
2131 u->cacheable = 0;
2132 break;
2133
2134 default: /* NGX_OK */
2135
2136 if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
2137
2138 if (ngx_http_file_cache_new(r) != NGX_OK) {
2139 ngx_http_upstream_finalize_request(r, u, 0);
2140 return;
2141 }
2142
2143 if (u->create_key(r) != NGX_OK) {
2144 ngx_http_upstream_finalize_request(r, u, 0);
2145 return;
2146 }
2147
2148 /* TODO: add keys */
2149
2150 r->cache->min_uses = u->conf->cache_min_uses;
2151 r->cache->body_start = u->conf->buffer_size;
2152 r->cache->file_cache = u->conf->cache->data;
2153
2154 if (ngx_http_file_cache_create(r) != NGX_OK) {
2155 ngx_http_upstream_finalize_request(r, u, 0);
2156 return;
2157 }
2158
2159 u->cacheable = 1;
2160 }
2161
2162 break;
2163 }
2164
2082 if (u->cacheable) { 2165 if (u->cacheable) {
2083 time_t now, valid; 2166 time_t now, valid;
2084 2167
2085 now = ngx_time(); 2168 now = ngx_time();
2086 2169
2097 if (valid) { 2180 if (valid) {
2098 r->cache->last_modified = r->headers_out.last_modified_time; 2181 r->cache->last_modified = r->headers_out.last_modified_time;
2099 r->cache->date = now; 2182 r->cache->date = now;
2100 r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start); 2183 r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
2101 2184
2102 if (r->headers_out.content_length_n != -1) {
2103 r->cache->length = r->cache->body_start
2104 + r->headers_out.content_length_n;
2105 }
2106
2107 ngx_http_file_cache_set_header(r, u->buffer.start); 2185 ngx_http_file_cache_set_header(r, u->buffer.start);
2108 2186
2109 } else { 2187 } else {
2110 u->cacheable = 0; 2188 u->cacheable = 0;
2111 r->headers_out.last_modified_time = -1; 2189 r->headers_out.last_modified_time = -1;
2114 2192
2115 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 2193 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
2116 "http cacheable: %d", u->cacheable); 2194 "http cacheable: %d", u->cacheable);
2117 2195
2118 if (u->cacheable == 0 && r->cache) { 2196 if (u->cacheable == 0 && r->cache) {
2119 ngx_http_file_cache_free(r, u->pipe->temp_file); 2197 ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
2120 } 2198 }
2121 2199
2122 #endif 2200 #endif
2123 2201
2124 p = u->pipe; 2202 p = u->pipe;
2589 /* TODO: check length & update cache */ 2667 /* TODO: check length & update cache */
2590 2668
2591 ngx_http_file_cache_update(r, u->pipe->temp_file); 2669 ngx_http_file_cache_update(r, u->pipe->temp_file);
2592 2670
2593 } else if (p->upstream_error) { 2671 } else if (p->upstream_error) {
2594 ngx_http_file_cache_free(r, u->pipe->temp_file); 2672 ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
2595 } 2673 }
2596 } 2674 }
2597 2675
2598 #endif 2676 #endif
2599 2677
2835 2913
2836 u = r->upstream; 2914 u = r->upstream;
2837 2915
2838 if (u->resolved && u->resolved->ctx) { 2916 if (u->resolved && u->resolved->ctx) {
2839 ngx_resolve_name_done(u->resolved->ctx); 2917 ngx_resolve_name_done(u->resolved->ctx);
2918 u->resolved->ctx = NULL;
2840 } 2919 }
2841 2920
2842 ngx_http_upstream_finalize_request(r, u, NGX_DONE); 2921 ngx_http_upstream_finalize_request(r, u, NGX_DONE);
2843 } 2922 }
2844 2923
2852 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 2931 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2853 "finalize http upstream request: %i", rc); 2932 "finalize http upstream request: %i", rc);
2854 2933
2855 if (u->cleanup) { 2934 if (u->cleanup) {
2856 *u->cleanup = NULL; 2935 *u->cleanup = NULL;
2936 u->cleanup = NULL;
2937 }
2938
2939 if (u->resolved && u->resolved->ctx) {
2940 ngx_resolve_name_done(u->resolved->ctx);
2941 u->resolved->ctx = NULL;
2857 } 2942 }
2858 2943
2859 if (u->state && u->state->response_sec) { 2944 if (u->state && u->state->response_sec) {
2860 tp = ngx_timeofday(); 2945 tp = ngx_timeofday();
2861 u->state->response_sec = tp->sec - u->state->response_sec; 2946 u->state->response_sec = tp->sec - u->state->response_sec;
2910 #if (NGX_HTTP_CACHE) 2995 #if (NGX_HTTP_CACHE)
2911 2996
2912 if (u->cacheable && r->cache) { 2997 if (u->cacheable && r->cache) {
2913 time_t valid; 2998 time_t valid;
2914 2999
2915 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2916 "http upstream cache fd: %d",
2917 r->cache->file.fd);
2918
2919 if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) { 3000 if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
2920 3001
2921 valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc); 3002 valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
2922 3003
2923 if (valid) { 3004 if (valid) {
2924 r->cache->valid_sec = ngx_time() + valid; 3005 r->cache->valid_sec = ngx_time() + valid;
2925 r->cache->error = rc; 3006 r->cache->error = rc;
2926 } 3007 }
2927 } 3008 }
2928 3009
2929 ngx_http_file_cache_free(r, u->pipe->temp_file); 3010 ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
2930 } 3011 }
2931 3012
2932 #endif 3013 #endif
2933 3014
2934 if (u->header_sent 3015 if (u->header_sent
2969 3050
2970 static ngx_int_t 3051 static ngx_int_t
2971 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, 3052 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
2972 ngx_uint_t offset) 3053 ngx_uint_t offset)
2973 { 3054 {
3055 return NGX_OK;
3056 }
3057
3058
3059 static ngx_int_t
3060 ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
3061 ngx_uint_t offset)
3062 {
3063 #if (NGX_HTTP_CACHE)
3064 ngx_http_upstream_t *u;
3065
3066 u = r->upstream;
3067
3068 if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
3069 u->cacheable = 0;
3070 }
3071 #endif
3072
2974 return NGX_OK; 3073 return NGX_OK;
2975 } 3074 }
2976 3075
2977 3076
2978 static ngx_int_t 3077 static ngx_int_t
3015 3114
3016 if (r->cache->valid_sec != 0) { 3115 if (r->cache->valid_sec != 0) {
3017 return NGX_OK; 3116 return NGX_OK;
3018 } 3117 }
3019 3118
3020 last = h->value.data + h->value.len; 3119 p = h->value.data;
3021 3120 last = p + h->value.len;
3022 if (ngx_strlcasestrn(h->value.data, last, (u_char *) "no-cache", 8 - 1) 3121
3023 != NULL) 3122 if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL
3123 || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL
3124 || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL)
3024 { 3125 {
3025 u->cacheable = 0; 3126 u->cacheable = 0;
3026 return NGX_OK; 3127 return NGX_OK;
3027 } 3128 }
3028 3129
3029 p = ngx_strlcasestrn(h->value.data, last, (u_char *) "max-age=", 8 - 1); 3130 p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1);
3030 3131
3031 if (p == NULL) { 3132 if (p == NULL) {
3032 return NGX_OK; 3133 return NGX_OK;
3033 } 3134 }
3034 3135
3035 n = 0; 3136 n = 0;
3036 3137
3037 for (p += 8; p < last; p++) { 3138 for (p += 8; p < last; p++) {
3038 if (*p == ';' || *p == ' ') { 3139 if (*p == ',' || *p == ';' || *p == ' ') {
3039 break; 3140 break;
3040 } 3141 }
3041 3142
3042 if (*p >= '0' && *p <= '9') { 3143 if (*p >= '0' && *p <= '9') {
3043 n = n * 10 + *p - '0'; 3144 n = n * 10 + *p - '0';
3701 3802
3702 for ( ;; ) { 3803 for ( ;; ) {
3703 if (state[i].status) { 3804 if (state[i].status) {
3704 ms = (ngx_msec_int_t) 3805 ms = (ngx_msec_int_t)
3705 (state[i].response_sec * 1000 + state[i].response_msec); 3806 (state[i].response_sec * 1000 + state[i].response_msec);
3706 ms = (ms >= 0) ? ms : 0; 3807 ms = ngx_max(ms, 0);
3707 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); 3808 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
3708 3809
3709 } else { 3810 } else {
3710 *p++ = '-'; 3811 *p++ = '-';
3711 } 3812 }
4194 4295
4195 return uscf; 4296 return uscf;
4196 } 4297 }
4197 4298
4198 4299
4300 char *
4301 ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4302 void *conf)
4303 {
4304 char *p = conf;
4305
4306 ngx_int_t rc;
4307 ngx_str_t *value;
4308 ngx_addr_t **paddr;
4309
4310 paddr = (ngx_addr_t **) (p + cmd->offset);
4311
4312 *paddr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
4313 if (*paddr == NULL) {
4314 return NGX_CONF_ERROR;
4315 }
4316
4317 value = cf->args->elts;
4318
4319 rc = ngx_parse_addr(cf->pool, *paddr, value[1].data, value[1].len);
4320
4321 switch (rc) {
4322 case NGX_OK:
4323 (*paddr)->name = value[1];
4324 return NGX_CONF_OK;
4325
4326 case NGX_DECLINED:
4327 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4328 "invalid address \"%V\"", &value[1]);
4329 default:
4330 return NGX_CONF_ERROR;
4331 }
4332 }
4333
4334
4199 ngx_int_t 4335 ngx_int_t
4200 ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf, 4336 ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
4201 ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, 4337 ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
4202 ngx_str_t *default_hide_headers, ngx_hash_init_t *hash) 4338 ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
4203 { 4339 {