Mercurial > hg > nginx-vendor-0-8
comparison src/http/ngx_http_upstream.c @ 260:0effe91f6083 NGINX_0_5_0
nginx 0.5.0
*) Change: the parameters in the "%name" form in the "log_format"
directive are not supported anymore.
*) Change: the "proxy_upstream_max_fails",
"proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails",
"fastcgi_upstream_fail_timeout", "memcached_upstream_max_fails", and
"memcached_upstream_fail_timeout" directives are not supported
anymore.
*) Feature: the "server" directive in the "upstream" context supports
the "max_fails", "fail_timeout", and "down" parameters.
*) Feature: the "ip_hash" directive inside the "upstream" block.
*) Feature: the WAIT status in the "Auth-Status" header line of the
IMAP/POP3 proxy authentication server response.
*) Bugfix: nginx could not be built on 64-bit platforms; bug appeared
in 0.4.14.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Dec 2006 00:00:00 +0300 |
parents | 6ae1357b7b7c |
children | e0b1d0a6c629 |
comparison
equal
deleted
inserted
replaced
259:c68f18041059 | 260:0effe91f6083 |
---|---|
68 #if (NGX_HTTP_GZIP) | 68 #if (NGX_HTTP_GZIP) |
69 static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, | 69 static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, |
70 ngx_table_elt_t *h, ngx_uint_t offset); | 70 ngx_table_elt_t *h, ngx_uint_t offset); |
71 #endif | 71 #endif |
72 | 72 |
73 static size_t ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, | |
74 uintptr_t data); | |
75 static u_char *ngx_http_upstream_log_status(ngx_http_request_t *r, | |
76 u_char *buf, ngx_http_log_op_t *op); | |
77 static size_t ngx_http_upstream_log_response_time_getlen(ngx_http_request_t *r, | |
78 uintptr_t data); | |
79 static u_char *ngx_http_upstream_log_response_time(ngx_http_request_t *r, | |
80 u_char *buf, ngx_http_log_op_t *op); | |
81 | |
82 static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf); | 73 static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf); |
83 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, | 74 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, |
84 ngx_http_variable_value_t *v, uintptr_t data); | 75 ngx_http_variable_value_t *v, uintptr_t data); |
85 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, | 76 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, |
86 ngx_http_variable_value_t *v, uintptr_t data); | 77 ngx_http_variable_value_t *v, uintptr_t data); |
94 | 85 |
95 #if (NGX_HTTP_SSL) | 86 #if (NGX_HTTP_SSL) |
96 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, | 87 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, |
97 ngx_http_upstream_t *u, ngx_connection_t *c); | 88 ngx_http_upstream_t *u, ngx_connection_t *c); |
98 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); | 89 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); |
99 static void ngx_http_upstream_ssl_shutdown(ngx_connection_t *c, | |
100 ngx_peer_t *peer); | |
101 #endif | 90 #endif |
102 | 91 |
103 | 92 |
104 ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { | 93 ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { |
105 | 94 |
222 0, | 211 0, |
223 0, | 212 0, |
224 NULL }, | 213 NULL }, |
225 | 214 |
226 { ngx_string("server"), | 215 { ngx_string("server"), |
227 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12, | 216 NGX_HTTP_UPS_CONF|NGX_CONF_1MORE, |
228 ngx_http_upstream_server, | 217 ngx_http_upstream_server, |
229 NGX_HTTP_SRV_CONF_OFFSET, | 218 NGX_HTTP_SRV_CONF_OFFSET, |
230 0, | 219 0, |
231 NULL }, | 220 NULL }, |
232 | 221 |
263 NULL, /* exit master */ | 252 NULL, /* exit master */ |
264 NGX_MODULE_V1_PADDING | 253 NGX_MODULE_V1_PADDING |
265 }; | 254 }; |
266 | 255 |
267 | 256 |
268 static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = { | |
269 { ngx_string("upstream_status"), 0, NULL, | |
270 ngx_http_upstream_log_status_getlen, | |
271 ngx_http_upstream_log_status }, | |
272 { ngx_string("upstream_response_time"), 0, NULL, | |
273 ngx_http_upstream_log_response_time_getlen, | |
274 ngx_http_upstream_log_response_time }, | |
275 { ngx_null_string, 0, NULL, NULL, NULL } | |
276 }; | |
277 | |
278 | |
279 static ngx_http_variable_t ngx_http_upstream_vars[] = { | 257 static ngx_http_variable_t ngx_http_upstream_vars[] = { |
280 | 258 |
281 { ngx_string("upstream_status"), NULL, | 259 { ngx_string("upstream_status"), NULL, |
282 ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, | 260 ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, |
283 | 261 |
326 | 304 |
327 if (r->request_body) { | 305 if (r->request_body) { |
328 u->request_bufs = r->request_body->bufs; | 306 u->request_bufs = r->request_body->bufs; |
329 } | 307 } |
330 | 308 |
309 if (u->conf->upstream->peer.init(r, u->conf->upstream) != NGX_OK) { | |
310 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
311 return; | |
312 } | |
313 | |
331 if (u->create_request(r) != NGX_OK) { | 314 if (u->create_request(r) != NGX_OK) { |
332 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 315 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
333 return; | 316 return; |
334 } | 317 } |
335 | |
336 u->peer.log = r->connection->log; | |
337 | 318 |
338 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 319 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
339 | 320 |
340 u->output.sendfile = r->connection->sendfile; | 321 u->output.sendfile = r->connection->sendfile; |
341 u->output.pool = r->pool; | 322 u->output.pool = r->pool; |
344 u->output.output_filter = ngx_chain_writer; | 325 u->output.output_filter = ngx_chain_writer; |
345 u->output.filter_ctx = &u->writer; | 326 u->output.filter_ctx = &u->writer; |
346 | 327 |
347 u->writer.pool = r->pool; | 328 u->writer.pool = r->pool; |
348 | 329 |
349 if (ngx_array_init(&u->states, r->pool, u->peer.peers->number, | 330 if (ngx_array_init(&u->states, r->pool, 1, |
350 sizeof(ngx_http_upstream_state_t)) | 331 sizeof(ngx_http_upstream_state_t)) |
351 != NGX_OK) | 332 != NGX_OK) |
352 { | 333 { |
353 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 334 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
354 return; | 335 return; |
546 ngx_http_upstream_finalize_request(r, u, | 527 ngx_http_upstream_finalize_request(r, u, |
547 NGX_HTTP_INTERNAL_SERVER_ERROR); | 528 NGX_HTTP_INTERNAL_SERVER_ERROR); |
548 return; | 529 return; |
549 } | 530 } |
550 | 531 |
551 u->state->peer = &u->peer.peers->peer[u->peer.cur_peer].name; | 532 u->state->peer = u->peer.name; |
552 | 533 |
553 if (rc == NGX_BUSY) { | 534 if (rc == NGX_BUSY) { |
554 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); | 535 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); |
555 } | 536 } |
556 | 537 |
635 | 616 |
636 static void | 617 static void |
637 ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, | 618 ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, |
638 ngx_http_upstream_t *u, ngx_connection_t *c) | 619 ngx_http_upstream_t *u, ngx_connection_t *c) |
639 { | 620 { |
640 ngx_int_t rc; | 621 ngx_int_t rc; |
641 ngx_peer_t *peer; | |
642 | 622 |
643 if (ngx_ssl_create_connection(u->conf->ssl, c, | 623 if (ngx_ssl_create_connection(u->conf->ssl, c, |
644 NGX_SSL_BUFFER|NGX_SSL_CLIENT) | 624 NGX_SSL_BUFFER|NGX_SSL_CLIENT) |
645 == NGX_ERROR) | 625 == NGX_ERROR) |
646 { | 626 { |
650 } | 630 } |
651 | 631 |
652 c->sendfile = 0; | 632 c->sendfile = 0; |
653 u->output.sendfile = 0; | 633 u->output.sendfile = 0; |
654 | 634 |
655 peer = &u->peer.peers->peer[u->peer.cur_peer]; | 635 if (ngx_ssl_set_session(c, u->peer.ssl_session) != NGX_OK) { |
656 | |
657 if (ngx_ssl_set_session(c, peer->ssl_session) != NGX_OK) { | |
658 ngx_http_upstream_finalize_request(r, u, | 636 ngx_http_upstream_finalize_request(r, u, |
659 NGX_HTTP_INTERNAL_SERVER_ERROR); | 637 NGX_HTTP_INTERNAL_SERVER_ERROR); |
660 return; | 638 return; |
661 } | 639 } |
662 | 640 |
681 | 659 |
682 r = c->data; | 660 r = c->data; |
683 u = r->upstream; | 661 u = r->upstream; |
684 | 662 |
685 if (c->ssl->handshaked) { | 663 if (c->ssl->handshaked) { |
664 | |
665 u->peer.save_session(&u->peer, u->peer.data); | |
686 | 666 |
687 c->write->handler = ngx_http_upstream_send_request_handler; | 667 c->write->handler = ngx_http_upstream_send_request_handler; |
688 c->read->handler = ngx_http_upstream_process_header; | 668 c->read->handler = ngx_http_upstream_process_header; |
689 | 669 |
690 ngx_http_upstream_send_request(r, u); | 670 ngx_http_upstream_send_request(r, u); |
990 } | 970 } |
991 #endif | 971 #endif |
992 } | 972 } |
993 | 973 |
994 n = u->peer.connection->recv(u->peer.connection, u->buffer.last, | 974 n = u->peer.connection->recv(u->peer.connection, u->buffer.last, |
995 u->buffer.end - u->buffer.last); | 975 u->buffer.end - u->buffer.last); |
996 | 976 |
997 if (n == NGX_AGAIN) { | 977 if (n == NGX_AGAIN) { |
998 #if 0 | 978 #if 0 |
999 ngx_add_timer(rev, u->read_timeout); | 979 ngx_add_timer(rev, u->read_timeout); |
1000 #endif | 980 #endif |
1603 size_t size; | 1583 size_t size; |
1604 ssize_t n; | 1584 ssize_t n; |
1605 ngx_buf_t *b; | 1585 ngx_buf_t *b; |
1606 ngx_int_t rc; | 1586 ngx_int_t rc; |
1607 ngx_uint_t do_write; | 1587 ngx_uint_t do_write; |
1608 ngx_connection_t *c, *client; | 1588 ngx_connection_t *c, *downstream, *upstream; |
1609 ngx_http_request_t *r; | 1589 ngx_http_request_t *r; |
1610 ngx_http_upstream_t *u; | 1590 ngx_http_upstream_t *u; |
1611 ngx_http_core_loc_conf_t *clcf; | 1591 ngx_http_core_loc_conf_t *clcf; |
1612 | 1592 |
1613 c = ev->data; | 1593 c = ev->data; |
1636 | 1616 |
1637 ngx_http_upstream_finalize_request(r, u, 0); | 1617 ngx_http_upstream_finalize_request(r, u, 0); |
1638 return; | 1618 return; |
1639 } | 1619 } |
1640 | 1620 |
1641 client = r->connection; | 1621 downstream = r->connection; |
1622 upstream = u->peer.connection; | |
1642 | 1623 |
1643 b = &u->buffer; | 1624 b = &u->buffer; |
1644 | 1625 |
1645 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1626 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1646 | 1627 |
1651 if (do_write) { | 1632 if (do_write) { |
1652 | 1633 |
1653 if (u->out_bufs || u->busy_bufs) { | 1634 if (u->out_bufs || u->busy_bufs) { |
1654 rc = ngx_http_output_filter(r, u->out_bufs); | 1635 rc = ngx_http_output_filter(r, u->out_bufs); |
1655 | 1636 |
1656 if (client->destroyed) { | 1637 if (downstream->destroyed) { |
1657 return; | 1638 return; |
1658 } | 1639 } |
1659 | 1640 |
1660 if (rc == NGX_ERROR) { | 1641 if (rc == NGX_ERROR) { |
1661 ngx_http_upstream_finalize_request(r, u, 0); | 1642 ngx_http_upstream_finalize_request(r, u, 0); |
1667 } | 1648 } |
1668 | 1649 |
1669 if (u->busy_bufs == NULL) { | 1650 if (u->busy_bufs == NULL) { |
1670 | 1651 |
1671 if (u->length == 0 | 1652 if (u->length == 0 |
1672 || u->peer.connection->read->eof | 1653 || upstream->read->eof |
1673 || u->peer.connection->read->error) | 1654 || upstream->read->error) |
1674 { | 1655 { |
1675 ngx_http_upstream_finalize_request(r, u, 0); | 1656 ngx_http_upstream_finalize_request(r, u, 0); |
1676 return; | 1657 return; |
1677 } | 1658 } |
1678 | 1659 |
1685 | 1666 |
1686 if (size > u->length) { | 1667 if (size > u->length) { |
1687 size = u->length; | 1668 size = u->length; |
1688 } | 1669 } |
1689 | 1670 |
1690 if (size && u->peer.connection->read->ready) { | 1671 if (size && upstream->read->ready) { |
1691 | 1672 |
1692 n = u->peer.connection->recv(u->peer.connection, b->last, size); | 1673 n = upstream->recv(upstream, b->last, size); |
1693 | 1674 |
1694 if (n == NGX_AGAIN) { | 1675 if (n == NGX_AGAIN) { |
1695 break; | 1676 break; |
1696 } | 1677 } |
1697 | 1678 |
1708 } | 1689 } |
1709 | 1690 |
1710 break; | 1691 break; |
1711 } | 1692 } |
1712 | 1693 |
1713 if (client->data == r) { | 1694 if (downstream->data == r) { |
1714 if (ngx_handle_write_event(client->write, clcf->send_lowat) | 1695 if (ngx_handle_write_event(downstream->write, clcf->send_lowat) |
1715 == NGX_ERROR) | 1696 == NGX_ERROR) |
1716 { | 1697 { |
1717 ngx_http_upstream_finalize_request(r, u, 0); | 1698 ngx_http_upstream_finalize_request(r, u, 0); |
1718 return; | 1699 return; |
1719 } | 1700 } |
1720 } | 1701 } |
1721 | 1702 |
1722 if (client->write->active) { | 1703 if (downstream->write->active) { |
1723 ngx_add_timer(client->write, clcf->send_timeout); | 1704 ngx_add_timer(downstream->write, clcf->send_timeout); |
1724 | 1705 |
1725 } else if (client->write->timer_set) { | 1706 } else if (downstream->write->timer_set) { |
1726 ngx_del_timer(client->write); | 1707 ngx_del_timer(downstream->write); |
1727 } | 1708 } |
1728 | 1709 |
1729 if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) { | 1710 if (ngx_handle_read_event(upstream->read, 0) == NGX_ERROR) { |
1730 ngx_http_upstream_finalize_request(r, u, 0); | 1711 ngx_http_upstream_finalize_request(r, u, 0); |
1731 return; | 1712 return; |
1732 } | 1713 } |
1733 | 1714 |
1734 if (u->peer.connection->read->active) { | 1715 if (upstream->read->active) { |
1735 ngx_add_timer(u->peer.connection->read, u->conf->read_timeout); | 1716 ngx_add_timer(upstream->read, u->conf->read_timeout); |
1736 | 1717 |
1737 } else if (u->peer.connection->read->timer_set) { | 1718 } else if (upstream->read->timer_set) { |
1738 ngx_del_timer(u->peer.connection->read); | 1719 ngx_del_timer(upstream->read); |
1739 } | 1720 } |
1740 } | 1721 } |
1741 | 1722 |
1742 | 1723 |
1743 static ngx_int_t | 1724 static ngx_int_t |
1940 | 1921 |
1941 static void | 1922 static void |
1942 ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, | 1923 ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, |
1943 ngx_uint_t ft_type) | 1924 ngx_uint_t ft_type) |
1944 { | 1925 { |
1945 ngx_uint_t status, down; | 1926 ngx_uint_t status, state; |
1946 | 1927 |
1947 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1928 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1948 "http next upstream, %xD", ft_type); | 1929 "http next upstream, %xi", ft_type); |
1949 | 1930 |
1950 #if 0 | 1931 #if 0 |
1951 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); | 1932 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); |
1952 #endif | 1933 #endif |
1953 | 1934 |
1954 if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) { | 1935 if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) { |
1955 down = 0; | 1936 state = NGX_PEER_NEXT; |
1956 } else { | 1937 } else { |
1957 down = 1; | 1938 state = NGX_PEER_FAILED; |
1958 } | 1939 } |
1959 | 1940 |
1960 ngx_event_connect_peer_failed(&u->peer, down); | 1941 u->peer.free(&u->peer, u->peer.data, state); |
1961 | 1942 |
1962 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { | 1943 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { |
1963 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, | 1944 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, |
1964 "upstream timed out"); | 1945 "upstream timed out"); |
1965 } | 1946 } |
2021 if (u->peer.connection) { | 2002 if (u->peer.connection) { |
2022 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2003 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2023 "close http upstream connection: %d", | 2004 "close http upstream connection: %d", |
2024 u->peer.connection->fd); | 2005 u->peer.connection->fd); |
2025 #if (NGX_HTTP_SSL) | 2006 #if (NGX_HTTP_SSL) |
2007 | |
2026 if (u->peer.connection->ssl) { | 2008 if (u->peer.connection->ssl) { |
2027 ngx_http_upstream_ssl_shutdown(u->peer.connection, | 2009 u->peer.connection->ssl->no_wait_shutdown = 1; |
2028 &u->peer.peers->peer[u->peer.cur_peer]); | 2010 u->peer.connection->ssl->no_send_shutdown = 1; |
2011 | |
2012 (void) ngx_ssl_shutdown(u->peer.connection); | |
2029 } | 2013 } |
2030 #endif | 2014 #endif |
2015 | |
2031 ngx_close_connection(u->peer.connection); | 2016 ngx_close_connection(u->peer.connection); |
2032 } | 2017 } |
2033 | 2018 |
2034 #if 0 | 2019 #if 0 |
2035 if (u->conf->busy_lock && !u->busy_locked) { | 2020 if (u->conf->busy_lock && !u->busy_locked) { |
2072 u->state->response_time = (ms >= 0) ? ms : 0; | 2057 u->state->response_time = (ms >= 0) ? ms : 0; |
2073 } | 2058 } |
2074 | 2059 |
2075 u->finalize_request(r, rc); | 2060 u->finalize_request(r, rc); |
2076 | 2061 |
2062 u->peer.free(&u->peer, u->peer.data, 0); | |
2063 | |
2077 if (u->peer.connection) { | 2064 if (u->peer.connection) { |
2065 | |
2066 #if (NGX_HTTP_SSL) | |
2067 | |
2068 /* TODO: do not shutdown persistent connection */ | |
2069 | |
2070 if (u->peer.connection->ssl) { | |
2071 | |
2072 /* | |
2073 * We send the "close notify" shutdown alert to the upstream only | |
2074 * and do not wait its "close notify" shutdown alert. | |
2075 * It is acceptable according to the TLS standard. | |
2076 */ | |
2077 | |
2078 u->peer.connection->ssl->no_wait_shutdown = 1; | |
2079 | |
2080 (void) ngx_ssl_shutdown(u->peer.connection); | |
2081 } | |
2082 #endif | |
2083 | |
2078 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2084 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2079 "close http upstream connection: %d", | 2085 "close http upstream connection: %d", |
2080 u->peer.connection->fd); | 2086 u->peer.connection->fd); |
2081 #if (NGX_HTTP_SSL) | 2087 |
2082 | |
2083 /* TODO: do not shutdown persistent connection */ | |
2084 | |
2085 if (u->peer.connection->ssl) { | |
2086 ngx_http_upstream_ssl_shutdown(u->peer.connection, | |
2087 &u->peer.peers->peer[u->peer.cur_peer]); | |
2088 } | |
2089 #endif | |
2090 ngx_close_connection(u->peer.connection); | 2088 ngx_close_connection(u->peer.connection); |
2091 } | 2089 } |
2092 | 2090 |
2093 u->peer.connection = NULL; | 2091 u->peer.connection = NULL; |
2094 | 2092 |
2123 | 2121 |
2124 ngx_http_finalize_request(r, rc); | 2122 ngx_http_finalize_request(r, rc); |
2125 } | 2123 } |
2126 | 2124 |
2127 | 2125 |
2128 #if (NGX_HTTP_SSL) | |
2129 | |
2130 static void | |
2131 ngx_http_upstream_ssl_shutdown(ngx_connection_t *c, ngx_peer_t *peer) | |
2132 { | |
2133 /* lock peer mutex */ | |
2134 | |
2135 if (peer->ssl_session) { | |
2136 ngx_ssl_free_session(peer->ssl_session); | |
2137 } | |
2138 | |
2139 peer->ssl_session = ngx_ssl_get_session(c); | |
2140 | |
2141 /* unlock peer mutex */ | |
2142 | |
2143 /* | |
2144 * We send the "close notify" shutdown alert to the upstream only | |
2145 * and do not wait its "close notify" shutdown alert. | |
2146 * It is acceptable according to the TLS standard. | |
2147 */ | |
2148 | |
2149 c->ssl->no_wait_shutdown = 1; | |
2150 | |
2151 (void) ngx_ssl_shutdown(c); | |
2152 } | |
2153 | |
2154 #endif | |
2155 | |
2156 | |
2157 static ngx_int_t | 2126 static ngx_int_t |
2158 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | 2127 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, |
2159 ngx_uint_t offset) | 2128 ngx_uint_t offset) |
2160 { | 2129 { |
2161 ngx_table_elt_t **ph; | 2130 ngx_table_elt_t **ph; |
2479 } | 2448 } |
2480 | 2449 |
2481 #endif | 2450 #endif |
2482 | 2451 |
2483 | 2452 |
2484 static size_t | |
2485 ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, uintptr_t data) | |
2486 { | |
2487 if (r->upstream) { | |
2488 return r->upstream->states.nelts * (3 + 2); | |
2489 } | |
2490 | |
2491 return 1; | |
2492 } | |
2493 | |
2494 | |
2495 static u_char * | |
2496 ngx_http_upstream_log_status(ngx_http_request_t *r, u_char *buf, | |
2497 ngx_http_log_op_t *op) | |
2498 { | |
2499 ngx_uint_t i; | |
2500 ngx_http_upstream_t *u; | |
2501 ngx_http_upstream_state_t *state; | |
2502 | |
2503 u = r->upstream; | |
2504 | |
2505 if (u == NULL || u->states.nelts == 0) { | |
2506 *buf = '-'; | |
2507 return buf + 1; | |
2508 } | |
2509 | |
2510 i = 0; | |
2511 state = u->states.elts; | |
2512 | |
2513 for ( ;; ) { | |
2514 if (state[i].status == 0) { | |
2515 *buf++ = '-'; | |
2516 | |
2517 } else { | |
2518 buf = ngx_sprintf(buf, "%ui", state[i].status); | |
2519 } | |
2520 | |
2521 if (++i == u->states.nelts) { | |
2522 return buf; | |
2523 } | |
2524 | |
2525 *buf++ = ','; | |
2526 *buf++ = ' '; | |
2527 } | |
2528 } | |
2529 | |
2530 | |
2531 static size_t | |
2532 ngx_http_upstream_log_response_time_getlen(ngx_http_request_t *r, | |
2533 uintptr_t data) | |
2534 { | |
2535 if (r->upstream) { | |
2536 return r->upstream->states.nelts * (NGX_TIME_T_LEN + 4 + 2); | |
2537 } | |
2538 | |
2539 return 1; | |
2540 } | |
2541 | |
2542 | |
2543 static u_char * | |
2544 ngx_http_upstream_log_response_time(ngx_http_request_t *r, u_char *buf, | |
2545 ngx_http_log_op_t *op) | |
2546 { | |
2547 ngx_uint_t i; | |
2548 ngx_http_upstream_t *u; | |
2549 ngx_http_upstream_state_t *state; | |
2550 | |
2551 u = r->upstream; | |
2552 | |
2553 if (u == NULL || u->states.nelts == 0) { | |
2554 *buf = '-'; | |
2555 return buf + 1; | |
2556 } | |
2557 | |
2558 i = 0; | |
2559 state = u->states.elts; | |
2560 | |
2561 for ( ;; ) { | |
2562 if (state[i].status == 0) { | |
2563 *buf++ = '-'; | |
2564 | |
2565 } else { | |
2566 buf = ngx_sprintf(buf, "%d.%03d", | |
2567 state[i].response_time / 1000, | |
2568 state[i].response_time % 1000); | |
2569 } | |
2570 | |
2571 if (++i == u->states.nelts) { | |
2572 return buf; | |
2573 } | |
2574 | |
2575 *buf++ = ','; | |
2576 *buf++ = ' '; | |
2577 } | |
2578 } | |
2579 | |
2580 | |
2581 static ngx_int_t | 2453 static ngx_int_t |
2582 ngx_http_upstream_add_variables(ngx_conf_t *cf) | 2454 ngx_http_upstream_add_variables(ngx_conf_t *cf) |
2583 { | 2455 { |
2584 ngx_http_variable_t *var, *v; | 2456 ngx_http_variable_t *var, *v; |
2585 ngx_http_log_op_name_t *op; | |
2586 | 2457 |
2587 for (v = ngx_http_upstream_vars; v->name.len; v++) { | 2458 for (v = ngx_http_upstream_vars; v->name.len; v++) { |
2588 var = ngx_http_add_variable(cf, &v->name, v->flags); | 2459 var = ngx_http_add_variable(cf, &v->name, v->flags); |
2589 if (var == NULL) { | 2460 if (var == NULL) { |
2590 return NGX_ERROR; | 2461 return NGX_ERROR; |
2591 } | 2462 } |
2592 | 2463 |
2593 var->get_handler = v->get_handler; | 2464 var->get_handler = v->get_handler; |
2594 var->data = v->data; | 2465 var->data = v->data; |
2595 } | 2466 } |
2596 | |
2597 for (op = ngx_http_upstream_log_fmt_ops; op->name.len; op++) { /* void */ } | |
2598 op->run = NULL; | |
2599 | |
2600 for (op = ngx_http_log_fmt_ops; op->run; op++) { | |
2601 if (op->name.len == 0) { | |
2602 op = (ngx_http_log_op_name_t *) op->run; | |
2603 } | |
2604 } | |
2605 | |
2606 op->run = (ngx_http_log_op_run_pt) ngx_http_upstream_log_fmt_ops; | |
2607 | 2467 |
2608 return NGX_OK; | 2468 return NGX_OK; |
2609 } | 2469 } |
2610 | 2470 |
2611 | 2471 |
2722 | 2582 |
2723 | 2583 |
2724 static char * | 2584 static char * |
2725 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | 2585 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) |
2726 { | 2586 { |
2727 char *rv; | 2587 char *rv; |
2728 void *mconf; | 2588 void *mconf; |
2729 ngx_str_t *value; | 2589 ngx_str_t *value; |
2730 ngx_url_t u; | 2590 ngx_url_t u; |
2731 ngx_uint_t i, j, m, n; | 2591 ngx_uint_t m; |
2732 ngx_conf_t pcf; | 2592 ngx_conf_t pcf; |
2733 ngx_peers_t **peers; | 2593 ngx_http_module_t *module; |
2734 ngx_http_module_t *module; | 2594 ngx_http_conf_ctx_t *ctx, *http_ctx; |
2735 ngx_http_conf_ctx_t *ctx; | 2595 ngx_http_upstream_srv_conf_t *uscf; |
2736 ngx_http_upstream_srv_conf_t *uscf; | 2596 |
2597 ngx_memzero(&u, sizeof(ngx_url_t)); | |
2598 | |
2599 value = cf->args->elts; | |
2600 u.host = value[1]; | |
2601 u.upstream = 1; | |
2602 u.no_resolve = 1; | |
2603 | |
2604 uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE | |
2605 |NGX_HTTP_UPSTREAM_WEIGHT | |
2606 |NGX_HTTP_UPSTREAM_MAX_FAILS | |
2607 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT | |
2608 |NGX_HTTP_UPSTREAM_DOWN | |
2609 |NGX_HTTP_UPSTREAM_BACKUP); | |
2610 if (uscf == NULL) { | |
2611 return NGX_CONF_ERROR; | |
2612 } | |
2613 | |
2737 | 2614 |
2738 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); | 2615 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); |
2739 if (ctx == NULL) { | 2616 if (ctx == NULL) { |
2740 return NGX_CONF_ERROR; | 2617 return NGX_CONF_ERROR; |
2741 } | 2618 } |
2742 | 2619 |
2743 ngx_memzero(&u, sizeof(ngx_url_t)); | 2620 http_ctx = cf->ctx; |
2744 | 2621 ctx->main_conf = http_ctx->main_conf; |
2745 value = cf->args->elts; | |
2746 u.host = value[1]; | |
2747 | |
2748 uscf = ngx_http_upstream_add(cf, &u); | |
2749 if (uscf == NULL) { | |
2750 return NGX_CONF_ERROR; | |
2751 } | |
2752 | 2622 |
2753 /* the upstream{}'s srv_conf */ | 2623 /* the upstream{}'s srv_conf */ |
2754 | 2624 |
2755 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | 2625 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); |
2756 if (ctx->srv_conf == NULL) { | 2626 if (ctx->srv_conf == NULL) { |
2757 return NGX_CONF_ERROR; | 2627 return NGX_CONF_ERROR; |
2758 } | 2628 } |
2759 | 2629 |
2760 ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf; | 2630 ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf; |
2761 | 2631 |
2632 uscf->srv_conf = ctx->srv_conf; | |
2633 | |
2762 | 2634 |
2763 /* the upstream{}'s loc_conf */ | 2635 /* the upstream{}'s loc_conf */ |
2764 | 2636 |
2765 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | 2637 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); |
2766 if (ctx->loc_conf == NULL) { | 2638 if (ctx->loc_conf == NULL) { |
2771 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { | 2643 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { |
2772 continue; | 2644 continue; |
2773 } | 2645 } |
2774 | 2646 |
2775 module = ngx_modules[m]->ctx; | 2647 module = ngx_modules[m]->ctx; |
2648 | |
2649 if (module->create_srv_conf) { | |
2650 mconf = module->create_srv_conf(cf); | |
2651 if (mconf == NULL) { | |
2652 return NGX_CONF_ERROR; | |
2653 } | |
2654 | |
2655 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; | |
2656 } | |
2776 | 2657 |
2777 if (module->create_loc_conf) { | 2658 if (module->create_loc_conf) { |
2778 mconf = module->create_loc_conf(cf); | 2659 mconf = module->create_loc_conf(cf); |
2779 if (mconf == NULL) { | 2660 if (mconf == NULL) { |
2780 return NGX_CONF_ERROR; | 2661 return NGX_CONF_ERROR; |
2803 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 2684 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2804 "no servers are inside upstream"); | 2685 "no servers are inside upstream"); |
2805 return NGX_CONF_ERROR; | 2686 return NGX_CONF_ERROR; |
2806 } | 2687 } |
2807 | 2688 |
2808 peers = uscf->servers->elts; | |
2809 | |
2810 if (uscf->servers->nelts == 1) { | |
2811 uscf->peers = peers[0]; | |
2812 } | |
2813 | |
2814 n = 0; | |
2815 | |
2816 for (i = 0; i < uscf->servers->nelts; i++) { | |
2817 n += peers[i]->number; | |
2818 } | |
2819 | |
2820 uscf->peers = ngx_pcalloc(cf->pool, | |
2821 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (n - 1)); | |
2822 if (uscf->peers == NULL) { | |
2823 return NGX_CONF_ERROR; | |
2824 } | |
2825 | |
2826 uscf->peers->number = n; | |
2827 | |
2828 n = 0; | |
2829 | |
2830 for (i = 0; i < uscf->servers->nelts; i++) { | |
2831 for (j = 0; j < peers[i]->number; j++) { | |
2832 uscf->peers->peer[n++] = peers[i]->peer[j]; | |
2833 } | |
2834 } | |
2835 | |
2836 return rv; | 2689 return rv; |
2837 } | 2690 } |
2838 | 2691 |
2839 | 2692 |
2840 static char * | 2693 static char * |
2841 ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 2694 ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
2842 { | 2695 { |
2843 ngx_http_upstream_srv_conf_t *uscf = conf; | 2696 ngx_http_upstream_srv_conf_t *uscf = conf; |
2844 | 2697 |
2845 ngx_str_t *value; | 2698 time_t fail_timeout; |
2846 ngx_url_t u; | 2699 ngx_str_t *value, s; |
2847 ngx_int_t weight; | 2700 ngx_url_t u; |
2848 ngx_uint_t i; | 2701 ngx_int_t weight, max_fails; |
2849 ngx_peers_t **peers; | 2702 ngx_uint_t i; |
2703 ngx_http_upstream_server_t *us; | |
2850 | 2704 |
2851 if (uscf->servers == NULL) { | 2705 if (uscf->servers == NULL) { |
2852 uscf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_peers_t *)); | 2706 uscf->servers = ngx_array_create(cf->pool, 4, |
2707 sizeof(ngx_http_upstream_server_t)); | |
2853 if (uscf->servers == NULL) { | 2708 if (uscf->servers == NULL) { |
2854 return NGX_CONF_ERROR; | 2709 return NGX_CONF_ERROR; |
2855 } | 2710 } |
2856 } | 2711 } |
2857 | 2712 |
2858 peers = ngx_array_push(uscf->servers); | 2713 us = ngx_array_push(uscf->servers); |
2859 if (peers == NULL) { | 2714 if (us == NULL) { |
2860 return NGX_CONF_ERROR; | 2715 return NGX_CONF_ERROR; |
2861 } | 2716 } |
2717 | |
2718 ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); | |
2862 | 2719 |
2863 value = cf->args->elts; | 2720 value = cf->args->elts; |
2864 | 2721 |
2865 ngx_memzero(&u, sizeof(ngx_url_t)); | 2722 ngx_memzero(&u, sizeof(ngx_url_t)); |
2866 | 2723 |
2875 | 2732 |
2876 return NGX_CONF_ERROR; | 2733 return NGX_CONF_ERROR; |
2877 } | 2734 } |
2878 | 2735 |
2879 weight = 1; | 2736 weight = 1; |
2880 | 2737 max_fails = 1; |
2881 if (cf->args->nelts == 3) { | 2738 fail_timeout = 10; |
2882 | 2739 |
2883 value = &value[2]; | 2740 for (i = 2; i < cf->args->nelts; i++) { |
2884 | 2741 |
2885 if (ngx_strncmp(value->data, "weight=", 7) == 0) { | 2742 if (ngx_strncmp(value[i].data, "weight=", 7) == 0) { |
2886 | 2743 |
2887 weight = ngx_atoi(&value->data[7], value->len - 7); | 2744 if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) { |
2745 goto invalid; | |
2746 } | |
2747 | |
2748 weight = ngx_atoi(&value[i].data[7], value[i].len - 7); | |
2888 | 2749 |
2889 if (weight == NGX_ERROR || weight == 0) { | 2750 if (weight == NGX_ERROR || weight == 0) { |
2890 goto invalid; | 2751 goto invalid; |
2891 } | 2752 } |
2892 | 2753 |
2893 } else { | 2754 continue; |
2894 goto invalid; | 2755 } |
2895 } | 2756 |
2896 } | 2757 if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { |
2897 | 2758 |
2898 for (i = 0; i < u.peers->number; i++) { | 2759 if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) { |
2899 u.peers->peer[i].weight = weight; | 2760 goto invalid; |
2900 u.peers->peer[i].current_weight = weight; | 2761 } |
2901 u.peers->peer[i].max_fails = NGX_CONF_UNSET_UINT; | 2762 |
2902 u.peers->peer[i].fail_timeout = NGX_CONF_UNSET; | 2763 max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10); |
2903 } | 2764 |
2904 | 2765 if (max_fails == NGX_ERROR) { |
2905 *peers = u.peers; | 2766 goto invalid; |
2767 } | |
2768 | |
2769 continue; | |
2770 } | |
2771 | |
2772 if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) { | |
2773 | |
2774 if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) { | |
2775 goto invalid; | |
2776 } | |
2777 | |
2778 s.len = value[i].len - 13; | |
2779 s.data = &value[i].data[13]; | |
2780 | |
2781 fail_timeout = ngx_parse_time(&s, 1); | |
2782 | |
2783 if (fail_timeout < 0) { | |
2784 goto invalid; | |
2785 } | |
2786 | |
2787 continue; | |
2788 } | |
2789 | |
2790 if (ngx_strncmp(value[i].data, "down", 4) == 0) { | |
2791 | |
2792 if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) { | |
2793 goto invalid; | |
2794 } | |
2795 | |
2796 us->down = 1; | |
2797 | |
2798 continue; | |
2799 } | |
2800 | |
2801 goto invalid; | |
2802 } | |
2803 | |
2804 us->addrs = u.addrs; | |
2805 us->naddrs = u.naddrs; | |
2806 us->weight = weight; | |
2807 us->max_fails = max_fails; | |
2808 us->fail_timeout = fail_timeout; | |
2906 | 2809 |
2907 return NGX_CONF_OK; | 2810 return NGX_CONF_OK; |
2908 | 2811 |
2909 invalid: | 2812 invalid: |
2910 | 2813 |
2911 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", value); | 2814 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2815 "invalid parameter \"%V\"", &value[i]); | |
2912 | 2816 |
2913 return NGX_CONF_ERROR; | 2817 return NGX_CONF_ERROR; |
2914 } | 2818 } |
2915 | 2819 |
2916 | 2820 |
2917 ngx_http_upstream_srv_conf_t * | 2821 ngx_http_upstream_srv_conf_t * |
2918 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u) | 2822 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) |
2919 { | 2823 { |
2920 ngx_uint_t i; | 2824 ngx_uint_t i; |
2825 ngx_http_upstream_server_t *us; | |
2921 ngx_http_upstream_srv_conf_t *uscf, **uscfp; | 2826 ngx_http_upstream_srv_conf_t *uscf, **uscfp; |
2922 ngx_http_upstream_main_conf_t *umcf; | 2827 ngx_http_upstream_main_conf_t *umcf; |
2923 | 2828 |
2924 if (u->upstream) { | 2829 if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) { |
2830 | |
2925 if (ngx_parse_url(cf, u) != NGX_OK) { | 2831 if (ngx_parse_url(cf, u) != NGX_OK) { |
2926 if (u->err) { | 2832 if (u->err) { |
2927 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 2833 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2928 "%s in upstream \"%V\"", u->err, &u->url); | 2834 "%s in upstream \"%V\"", u->err, &u->url); |
2929 } | 2835 } |
2930 | 2836 |
2931 return NULL; | 2837 return NULL; |
2932 } | 2838 } |
2933 | |
2934 if (u->peers) { | |
2935 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t)); | |
2936 if (uscf == NULL) { | |
2937 return NULL; | |
2938 } | |
2939 | |
2940 uscf->peers = u->peers; | |
2941 | |
2942 return uscf; | |
2943 } | |
2944 } | 2839 } |
2945 | 2840 |
2946 umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); | 2841 umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); |
2947 | 2842 |
2948 uscfp = umcf->upstreams.elts; | 2843 uscfp = umcf->upstreams.elts; |
2949 | 2844 |
2950 for (i = 0; i < umcf->upstreams.nelts; i++) { | 2845 for (i = 0; i < umcf->upstreams.nelts; i++) { |
2951 if (uscfp[i]->host.len != u->host.len) { | 2846 if (uscfp[i]->host.len != u->host.len |
2847 || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) | |
2848 != 0) | |
2849 { | |
2952 continue; | 2850 continue; |
2953 } | 2851 } |
2954 | 2852 |
2955 if (ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) | 2853 if ((flags & NGX_HTTP_UPSTREAM_CREATE) |
2956 == 0) | 2854 && (uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE)) |
2957 { | 2855 { |
2958 return uscfp[i]; | 2856 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2959 } | 2857 "duplicate upstream \"%V\"", &u->host); |
2858 return NULL; | |
2859 } | |
2860 | |
2861 if (uscfp[i]->port == 0 && u->portn && !u->no_port) { | |
2862 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
2863 "upstream \"%V\" port %d is ignored", | |
2864 &u->host, u->portn); | |
2865 } | |
2866 | |
2867 return uscfp[i]; | |
2960 } | 2868 } |
2961 | 2869 |
2962 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t)); | 2870 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t)); |
2963 if (uscf == NULL) { | 2871 if (uscf == NULL) { |
2964 return NULL; | 2872 return NULL; |
2965 } | 2873 } |
2966 | 2874 |
2875 uscf->flags = flags; | |
2967 uscf->host = u->host; | 2876 uscf->host = u->host; |
2968 uscf->file_name = cf->conf_file->file.name; | 2877 uscf->file_name = cf->conf_file->file.name; |
2969 uscf->line = cf->conf_file->line; | 2878 uscf->line = cf->conf_file->line; |
2970 uscf->port = u->default_portn; | 2879 uscf->port = u->portn; |
2880 | |
2881 if (u->naddrs == 1) { | |
2882 uscf->servers = ngx_array_create(cf->pool, 1, | |
2883 sizeof(ngx_http_upstream_server_t)); | |
2884 if (uscf->servers == NULL) { | |
2885 return NGX_CONF_ERROR; | |
2886 } | |
2887 | |
2888 us = ngx_array_push(uscf->servers); | |
2889 if (us == NULL) { | |
2890 return NGX_CONF_ERROR; | |
2891 } | |
2892 | |
2893 ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); | |
2894 | |
2895 us->addrs = u->addrs; | |
2896 us->naddrs = u->naddrs; | |
2897 } | |
2971 | 2898 |
2972 uscfp = ngx_array_push(&umcf->upstreams); | 2899 uscfp = ngx_array_push(&umcf->upstreams); |
2973 if (uscfp == NULL) { | 2900 if (uscfp == NULL) { |
2974 return NULL; | 2901 return NULL; |
2975 } | 2902 } |
3008 | 2935 |
3009 ngx_uint_t i; | 2936 ngx_uint_t i; |
3010 ngx_array_t headers_in; | 2937 ngx_array_t headers_in; |
3011 ngx_hash_key_t *hk; | 2938 ngx_hash_key_t *hk; |
3012 ngx_hash_init_t hash; | 2939 ngx_hash_init_t hash; |
2940 ngx_http_upstream_init_pt init; | |
3013 ngx_http_upstream_header_t *header; | 2941 ngx_http_upstream_header_t *header; |
3014 ngx_http_upstream_srv_conf_t **uscfp; | 2942 ngx_http_upstream_srv_conf_t **uscfp; |
3015 | 2943 |
3016 uscfp = umcf->upstreams.elts; | 2944 uscfp = umcf->upstreams.elts; |
3017 | 2945 |
3018 for (i = 0; i < umcf->upstreams.nelts; i++) { | 2946 for (i = 0; i < umcf->upstreams.nelts; i++) { |
3019 if (uscfp[i]->peers) { | 2947 |
3020 continue; | 2948 init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream: |
3021 } | 2949 ngx_http_upstream_init_round_robin; |
3022 | 2950 |
3023 uscfp[i]->peers = ngx_inet_resolve_peer(cf, &uscfp[i]->host, | 2951 if (init(cf, uscfp[i]) != NGX_OK) { |
3024 uscfp[i]->port); | |
3025 if (uscfp[i]->peers == NULL) { | |
3026 return NGX_CONF_ERROR; | 2952 return NGX_CONF_ERROR; |
3027 } | 2953 } |
3028 | 2954 } |
3029 if (uscfp[i]->peers == NGX_CONF_ERROR) { | 2955 |
3030 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | 2956 |
3031 "upstream host \"%V\" is not found in %s:%ui", | 2957 /* upstream_headers_in_hash */ |
3032 &uscfp[i]->host, uscfp[i]->file_name.data, | |
3033 uscfp[i]->line); | |
3034 return NGX_CONF_ERROR; | |
3035 } | |
3036 } | |
3037 | |
3038 | 2958 |
3039 if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) | 2959 if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) |
3040 != NGX_OK) | 2960 != NGX_OK) |
3041 { | 2961 { |
3042 return NGX_CONF_ERROR; | 2962 return NGX_CONF_ERROR; |