comparison src/http/ngx_http_upstream.c @ 6050:a08fad30aeac

Request body: unbuffered reading. The r->request_body_no_buffering flag was introduced. It instructs client request body reading code to avoid reading the whole body, and to call post_handler early instead. The caller should use the ngx_http_read_unbuffered_request_body() function to read remaining parts of the body. Upstream module is now able to use this mode, if configured with the proxy_request_buffering directive.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 23 Mar 2015 21:09:19 +0300
parents c8acea7c7041
children 643f2ce02f1c
comparison
equal deleted inserted replaced
6049:42d9beeb22db 6050:a08fad30aeac
34 static void ngx_http_upstream_connect(ngx_http_request_t *r, 34 static void ngx_http_upstream_connect(ngx_http_request_t *r,
35 ngx_http_upstream_t *u); 35 ngx_http_upstream_t *u);
36 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r, 36 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
37 ngx_http_upstream_t *u); 37 ngx_http_upstream_t *u);
38 static void ngx_http_upstream_send_request(ngx_http_request_t *r, 38 static void ngx_http_upstream_send_request(ngx_http_request_t *r,
39 ngx_http_upstream_t *u); 39 ngx_http_upstream_t *u, ngx_uint_t do_write);
40 static ngx_int_t ngx_http_upstream_send_request_body(ngx_http_request_t *r,
41 ngx_http_upstream_t *u, ngx_uint_t do_write);
40 static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r, 42 static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
41 ngx_http_upstream_t *u); 43 ngx_http_upstream_t *u);
44 static void ngx_http_upstream_read_request_handler(ngx_http_request_t *r);
42 static void ngx_http_upstream_process_header(ngx_http_request_t *r, 45 static void ngx_http_upstream_process_header(ngx_http_request_t *r,
43 ngx_http_upstream_t *u); 46 ngx_http_upstream_t *u);
44 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r, 47 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
45 ngx_http_upstream_t *u); 48 ngx_http_upstream_t *u);
46 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, 49 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
566 569
567 u->output.alignment = clcf->directio_alignment; 570 u->output.alignment = clcf->directio_alignment;
568 u->output.pool = r->pool; 571 u->output.pool = r->pool;
569 u->output.bufs.num = 1; 572 u->output.bufs.num = 1;
570 u->output.bufs.size = clcf->client_body_buffer_size; 573 u->output.bufs.size = clcf->client_body_buffer_size;
571 u->output.output_filter = ngx_chain_writer; 574
572 u->output.filter_ctx = &u->writer; 575 if (u->output.output_filter == NULL) {
576 u->output.output_filter = ngx_chain_writer;
577 u->output.filter_ctx = &u->writer;
578 }
573 579
574 u->writer.pool = r->pool; 580 u->writer.pool = r->pool;
575 581
576 if (r->upstream_states == NULL) { 582 if (r->upstream_states == NULL) {
577 583
1430 return; 1436 return;
1431 } 1437 }
1432 1438
1433 #endif 1439 #endif
1434 1440
1435 ngx_http_upstream_send_request(r, u); 1441 ngx_http_upstream_send_request(r, u, 1);
1436 } 1442 }
1437 1443
1438 1444
1439 #if (NGX_HTTP_SSL) 1445 #if (NGX_HTTP_SSL)
1440 1446
1534 c->write->handler = ngx_http_upstream_handler; 1540 c->write->handler = ngx_http_upstream_handler;
1535 c->read->handler = ngx_http_upstream_handler; 1541 c->read->handler = ngx_http_upstream_handler;
1536 1542
1537 c = r->connection; 1543 c = r->connection;
1538 1544
1539 ngx_http_upstream_send_request(r, u); 1545 ngx_http_upstream_send_request(r, u, 1);
1540 1546
1541 ngx_http_run_posted_requests(c); 1547 ngx_http_run_posted_requests(c);
1542 return; 1548 return;
1543 } 1549 }
1544 1550
1722 return NGX_OK; 1728 return NGX_OK;
1723 } 1729 }
1724 1730
1725 1731
1726 static void 1732 static void
1727 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) 1733 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
1734 ngx_uint_t do_write)
1728 { 1735 {
1729 ngx_int_t rc; 1736 ngx_int_t rc;
1730 ngx_connection_t *c; 1737 ngx_connection_t *c;
1731 1738
1732 c = u->peer.connection; 1739 c = u->peer.connection;
1739 return; 1746 return;
1740 } 1747 }
1741 1748
1742 c->log->action = "sending request to upstream"; 1749 c->log->action = "sending request to upstream";
1743 1750
1744 rc = ngx_output_chain(&u->output, u->request_sent ? NULL : u->request_bufs); 1751 rc = ngx_http_upstream_send_request_body(r, u, do_write);
1745
1746 u->request_sent = 1;
1747 1752
1748 if (rc == NGX_ERROR) { 1753 if (rc == NGX_ERROR) {
1749 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); 1754 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1750 return; 1755 return;
1751 } 1756 }
1752 1757
1753 if (c->write->timer_set) { 1758 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
1754 ngx_del_timer(c->write); 1759 ngx_http_upstream_finalize_request(r, u, rc);
1760 return;
1755 } 1761 }
1756 1762
1757 if (rc == NGX_AGAIN) { 1763 if (rc == NGX_AGAIN) {
1758 ngx_add_timer(c->write, u->conf->send_timeout); 1764 if (!c->write->ready) {
1765 ngx_add_timer(c->write, u->conf->send_timeout);
1766
1767 } else if (c->write->timer_set) {
1768 ngx_del_timer(c->write);
1769 }
1759 1770
1760 if (ngx_handle_write_event(c->write, u->conf->send_lowat) != NGX_OK) { 1771 if (ngx_handle_write_event(c->write, u->conf->send_lowat) != NGX_OK) {
1761 ngx_http_upstream_finalize_request(r, u, 1772 ngx_http_upstream_finalize_request(r, u,
1762 NGX_HTTP_INTERNAL_SERVER_ERROR); 1773 NGX_HTTP_INTERNAL_SERVER_ERROR);
1763 return; 1774 return;
1765 1776
1766 return; 1777 return;
1767 } 1778 }
1768 1779
1769 /* rc == NGX_OK */ 1780 /* rc == NGX_OK */
1781
1782 if (c->write->timer_set) {
1783 ngx_del_timer(c->write);
1784 }
1770 1785
1771 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { 1786 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
1772 if (ngx_tcp_push(c->fd) == NGX_ERROR) { 1787 if (ngx_tcp_push(c->fd) == NGX_ERROR) {
1773 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, 1788 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
1774 ngx_tcp_push_n " failed"); 1789 ngx_tcp_push_n " failed");
1795 return; 1810 return;
1796 } 1811 }
1797 } 1812 }
1798 1813
1799 1814
1815 static ngx_int_t
1816 ngx_http_upstream_send_request_body(ngx_http_request_t *r,
1817 ngx_http_upstream_t *u, ngx_uint_t do_write)
1818 {
1819 int tcp_nodelay;
1820 ngx_int_t rc;
1821 ngx_chain_t *out, *cl, *ln;
1822 ngx_connection_t *c;
1823 ngx_http_core_loc_conf_t *clcf;
1824
1825 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1826 "http upstream send request body");
1827
1828 if (!r->request_body_no_buffering) {
1829
1830 /* buffered request body */
1831
1832 if (!u->request_sent) {
1833 u->request_sent = 1;
1834 out = u->request_bufs;
1835
1836 } else {
1837 out = NULL;
1838 }
1839
1840 return ngx_output_chain(&u->output, out);
1841 }
1842
1843 if (!u->request_sent) {
1844 u->request_sent = 1;
1845 out = u->request_bufs;
1846
1847 if (r->request_body->bufs) {
1848 for (cl = out; cl->next; cl = out->next) { /* void */ }
1849 cl->next = r->request_body->bufs;
1850 r->request_body->bufs = NULL;
1851 }
1852
1853 c = u->peer.connection;
1854 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1855
1856 if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
1857 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
1858
1859 tcp_nodelay = 1;
1860
1861 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
1862 (const void *) &tcp_nodelay, sizeof(int)) == -1)
1863 {
1864 ngx_connection_error(c, ngx_socket_errno,
1865 "setsockopt(TCP_NODELAY) failed");
1866 return NGX_ERROR;
1867 }
1868
1869 c->tcp_nodelay = NGX_TCP_NODELAY_SET;
1870 }
1871
1872 r->read_event_handler = ngx_http_upstream_read_request_handler;
1873
1874 } else {
1875 out = NULL;
1876 }
1877
1878 for ( ;; ) {
1879
1880 if (do_write) {
1881 rc = ngx_output_chain(&u->output, out);
1882
1883 if (rc == NGX_ERROR) {
1884 return NGX_ERROR;
1885 }
1886
1887 while (out) {
1888 ln = out;
1889 out = out->next;
1890 ngx_free_chain(r->pool, ln);
1891 }
1892
1893 if (rc == NGX_OK && !r->reading_body) {
1894 break;
1895 }
1896 }
1897
1898 if (r->reading_body) {
1899 /* read client request body */
1900
1901 rc = ngx_http_read_unbuffered_request_body(r);
1902
1903 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
1904 return rc;
1905 }
1906
1907 out = r->request_body->bufs;
1908 r->request_body->bufs = NULL;
1909 }
1910
1911 /* stop if there is nothing to send */
1912
1913 if (out == NULL) {
1914 rc = NGX_AGAIN;
1915 break;
1916 }
1917
1918 do_write = 1;
1919 }
1920
1921 if (!r->reading_body) {
1922 if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
1923 r->read_event_handler =
1924 ngx_http_upstream_rd_check_broken_connection;
1925 }
1926 }
1927
1928 return rc;
1929 }
1930
1931
1800 static void 1932 static void
1801 ngx_http_upstream_send_request_handler(ngx_http_request_t *r, 1933 ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
1802 ngx_http_upstream_t *u) 1934 ngx_http_upstream_t *u)
1803 { 1935 {
1804 ngx_connection_t *c; 1936 ngx_connection_t *c;
1828 (void) ngx_handle_write_event(c->write, 0); 1960 (void) ngx_handle_write_event(c->write, 0);
1829 1961
1830 return; 1962 return;
1831 } 1963 }
1832 1964
1833 ngx_http_upstream_send_request(r, u); 1965 ngx_http_upstream_send_request(r, u, 1);
1966 }
1967
1968
1969 static void
1970 ngx_http_upstream_read_request_handler(ngx_http_request_t *r)
1971 {
1972 ngx_connection_t *c;
1973 ngx_http_upstream_t *u;
1974
1975 c = r->connection;
1976 u = r->upstream;
1977
1978 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1979 "http upstream read request handler");
1980
1981 if (c->read->timedout) {
1982 c->timedout = 1;
1983 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
1984 return;
1985 }
1986
1987 ngx_http_upstream_send_request(r, u, 0);
1834 } 1988 }
1835 1989
1836 1990
1837 static void 1991 static void
1838 ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) 1992 ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
3624 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { 3778 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
3625 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, 3779 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
3626 "upstream timed out"); 3780 "upstream timed out");
3627 } 3781 }
3628 3782
3629 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { 3783 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR
3784 && (!u->request_sent || !r->request_body_no_buffering))
3785 {
3630 status = 0; 3786 status = 0;
3631 3787
3632 /* TODO: inform balancer instead */ 3788 /* TODO: inform balancer instead */
3633 3789
3634 u->peer.tries++; 3790 u->peer.tries++;
3672 u->state->status = status; 3828 u->state->status = status;
3673 timeout = u->conf->next_upstream_timeout; 3829 timeout = u->conf->next_upstream_timeout;
3674 3830
3675 if (u->peer.tries == 0 3831 if (u->peer.tries == 0
3676 || !(u->conf->next_upstream & ft_type) 3832 || !(u->conf->next_upstream & ft_type)
3833 || (u->request_sent && r->request_body_no_buffering)
3677 || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) 3834 || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
3678 { 3835 {
3679 #if (NGX_HTTP_CACHE) 3836 #if (NGX_HTTP_CACHE)
3680 3837
3681 if (u->cache_status == NGX_HTTP_CACHE_EXPIRED 3838 if (u->cache_status == NGX_HTTP_CACHE_EXPIRED