Mercurial > hg > nginx-mail
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 { |