Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 2377:87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
*) now $upstream_addr, $upstream_status, $upstream_response_time can be used
with log_subrequest
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 08 Dec 2008 14:23:20 +0000 |
parents | 44039da1fae8 |
children | 3b89b17bcd9c |
comparison
equal
deleted
inserted
replaced
2376:29d89920a749 | 2377:87b8c44906b5 |
---|---|
36 u_char *host, size_t len); | 36 u_char *host, size_t len); |
37 | 37 |
38 static void ngx_http_request_handler(ngx_event_t *ev); | 38 static void ngx_http_request_handler(ngx_event_t *ev); |
39 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); | 39 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); |
40 static void ngx_http_writer(ngx_http_request_t *r); | 40 static void ngx_http_writer(ngx_http_request_t *r); |
41 static void ngx_http_request_finalizer(ngx_http_request_t *r); | |
41 | 42 |
42 static void ngx_http_set_keepalive(ngx_http_request_t *r); | 43 static void ngx_http_set_keepalive(ngx_http_request_t *r); |
43 static void ngx_http_keepalive_handler(ngx_event_t *ev); | 44 static void ngx_http_keepalive_handler(ngx_event_t *ev); |
44 static void ngx_http_set_lingering_close(ngx_http_request_t *r); | 45 static void ngx_http_set_lingering_close(ngx_http_request_t *r); |
45 static void ngx_http_lingering_close_handler(ngx_event_t *ev); | 46 static void ngx_http_lingering_close_handler(ngx_event_t *ev); |
1520 c->write->handler = ngx_http_request_handler; | 1521 c->write->handler = ngx_http_request_handler; |
1521 r->read_event_handler = ngx_http_block_reading; | 1522 r->read_event_handler = ngx_http_block_reading; |
1522 | 1523 |
1523 ngx_http_handler(r); | 1524 ngx_http_handler(r); |
1524 | 1525 |
1525 return; | 1526 ngx_http_run_posted_requests(c); |
1526 } | 1527 } |
1527 | 1528 |
1528 | 1529 |
1529 static ssize_t | 1530 static ssize_t |
1530 ngx_http_validate_host(u_char *host, size_t len) | 1531 ngx_http_validate_host(u_char *host, size_t len) |
1673 r = c->data; | 1674 r = c->data; |
1674 | 1675 |
1675 ctx = c->log->data; | 1676 ctx = c->log->data; |
1676 ctx->current_request = r; | 1677 ctx->current_request = r; |
1677 | 1678 |
1679 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1680 "http run request: \"%V?%V\"", &r->uri, &r->args); | |
1681 | |
1678 if (ev->write) { | 1682 if (ev->write) { |
1679 r->write_event_handler(r); | 1683 r->write_event_handler(r); |
1680 | 1684 |
1681 } else { | 1685 } else { |
1682 r->read_event_handler(r); | 1686 r->read_event_handler(r); |
1683 } | 1687 } |
1688 | |
1689 ngx_http_run_posted_requests(c); | |
1690 } | |
1691 | |
1692 | |
1693 void | |
1694 ngx_http_run_posted_requests(ngx_connection_t *c) | |
1695 { | |
1696 ngx_http_request_t *r; | |
1697 ngx_http_log_ctx_t *ctx; | |
1698 ngx_http_posted_request_t *pr; | |
1699 | |
1700 for ( ;; ) { | |
1701 | |
1702 if (c->destroyed) { | |
1703 return; | |
1704 } | |
1705 | |
1706 r = c->data; | |
1707 pr = r->main->posted_requests; | |
1708 | |
1709 if (pr == NULL) { | |
1710 return; | |
1711 } | |
1712 | |
1713 r->main->posted_requests = pr->next; | |
1714 | |
1715 r = pr->request; | |
1716 | |
1717 ctx = c->log->data; | |
1718 ctx->current_request = r; | |
1719 | |
1720 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1721 "http posted request: \"%V?%V\"", &r->uri, &r->args); | |
1722 | |
1723 r->write_event_handler(r); | |
1724 } | |
1725 } | |
1726 | |
1727 | |
1728 ngx_int_t | |
1729 ngx_http_post_request(ngx_http_request_t *r) | |
1730 { | |
1731 ngx_http_posted_request_t *pr, **p; | |
1732 | |
1733 pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t)); | |
1734 if (pr == NULL) { | |
1735 return NGX_ERROR; | |
1736 } | |
1737 | |
1738 pr->request = r; | |
1739 pr->next = NULL; | |
1740 | |
1741 for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ } | |
1742 | |
1743 *p = pr; | |
1744 | |
1745 return NGX_OK; | |
1684 } | 1746 } |
1685 | 1747 |
1686 | 1748 |
1687 void | 1749 void |
1688 ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) | 1750 ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) |
1689 { | 1751 { |
1690 ngx_connection_t *c; | 1752 ngx_connection_t *c; |
1691 ngx_http_request_t *pr; | 1753 ngx_http_request_t *pr; |
1692 ngx_http_log_ctx_t *ctx; | |
1693 ngx_http_core_loc_conf_t *clcf; | 1754 ngx_http_core_loc_conf_t *clcf; |
1694 | 1755 |
1695 if (rc == NGX_DONE) { | 1756 if (rc == NGX_DONE) { |
1696 /* the request pool may be already destroyed */ | 1757 /* the request pool may be already destroyed */ |
1697 return; | 1758 return; |
1698 } | 1759 } |
1699 | 1760 |
1700 c = r->connection; | 1761 c = r->connection; |
1701 | 1762 |
1702 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1763 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1703 "http finalize request: %d, \"%V?%V\"", | 1764 "http finalize request: %d, \"%V?%V\" %d", |
1704 rc, &r->uri, &r->args); | 1765 rc, &r->uri, &r->args, r == c->data); |
1705 | 1766 |
1706 if (rc == NGX_DECLINED) { | 1767 if (rc == NGX_DECLINED) { |
1707 r->content_handler = NULL; | 1768 r->content_handler = NULL; |
1708 r->write_event_handler = ngx_http_core_run_phases; | 1769 r->write_event_handler = ngx_http_core_run_phases; |
1709 ngx_http_core_run_phases(r); | 1770 ngx_http_core_run_phases(r); |
1755 | 1816 |
1756 ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc)); | 1817 ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc)); |
1757 return; | 1818 return; |
1758 } | 1819 } |
1759 | 1820 |
1760 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1821 if (r != r->main) { |
1761 | 1822 |
1762 if (r != r->main && !r->logged) { | 1823 if (r->buffered || r->postponed) { |
1763 | 1824 |
1764 if (clcf->log_subrequest) { | 1825 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1765 ngx_http_log_request(r); | 1826 ngx_http_close_request(r->main, 0); |
1766 } | 1827 } |
1767 | 1828 |
1768 r->logged = 1; | 1829 return; |
1769 } | 1830 } |
1770 | 1831 |
1771 if (r != r->main || rc == NGX_AGAIN) { | 1832 #if (NGX_DEBUG) |
1833 if (r != c->data) { | |
1834 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1835 "http finalize non-active request: \"%V?%V\"", | |
1836 &r->uri, &r->args); | |
1837 } | |
1838 #endif | |
1839 | |
1840 pr = r->parent; | |
1841 | |
1842 if (r == c->data) { | |
1843 | |
1844 if (!r->logged) { | |
1845 | |
1846 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1847 | |
1848 if (clcf->log_subrequest) { | |
1849 ngx_http_log_request(r); | |
1850 } | |
1851 | |
1852 r->logged = 1; | |
1853 | |
1854 } else { | |
1855 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
1856 "subrequest: \"%V?%V\" logged again", | |
1857 &r->uri, &r->args); | |
1858 } | |
1859 | |
1860 r->done = 1; | |
1861 | |
1862 if (pr->postponed && pr->postponed->request == r) { | |
1863 pr->postponed = pr->postponed->next; | |
1864 } | |
1865 | |
1866 c->data = pr; | |
1867 | |
1868 } else { | |
1869 | |
1870 r->write_event_handler = ngx_http_request_finalizer; | |
1871 | |
1872 if (r->waited) { | |
1873 r->done = 1; | |
1874 } | |
1875 } | |
1876 | |
1877 if (ngx_http_post_request(pr) != NGX_OK) { | |
1878 ngx_http_close_request(r->main, 0); | |
1879 return; | |
1880 } | |
1881 | |
1882 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1883 "http wake parent request: \"%V?%V\"", | |
1884 &pr->uri, &pr->args); | |
1885 | |
1886 ngx_http_run_posted_requests(c); | |
1887 | |
1888 return; | |
1889 } | |
1890 | |
1891 if (r->buffered || c->buffered || r->postponed) { | |
1892 | |
1772 if (ngx_http_set_write_handler(r) != NGX_OK) { | 1893 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1773 return; | 1894 ngx_http_close_request(r, 0); |
1774 } | 1895 } |
1896 | |
1897 return; | |
1898 } | |
1899 | |
1900 if (r != c->data) { | |
1901 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
1902 "http finalize non-active request: \"%V?%V\"", | |
1903 &r->uri, &r->args); | |
1904 return; | |
1775 } | 1905 } |
1776 | 1906 |
1777 r->done = 1; | 1907 r->done = 1; |
1778 | |
1779 if (r != c->data) { | |
1780 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1781 "http finalize non-active request: \"%V?%V\"", | |
1782 &r->uri, &r->args); | |
1783 return; | |
1784 } | |
1785 | |
1786 if (r != r->main) { | |
1787 | |
1788 pr = r->parent; | |
1789 | |
1790 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1791 "http parent request: \"%V?%V\"", &pr->uri, &pr->args); | |
1792 | |
1793 if (rc != NGX_AGAIN) { | |
1794 c->data = pr; | |
1795 } | |
1796 | |
1797 ctx = c->log->data; | |
1798 ctx->current_request = pr; | |
1799 | |
1800 if (pr->postponed) { | |
1801 | |
1802 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1803 "http request: \"%V?%V\" has postponed", | |
1804 &pr->uri, &pr->args); | |
1805 | |
1806 if (rc != NGX_AGAIN && pr->postponed->request == r) { | |
1807 pr->postponed = pr->postponed->next; | |
1808 } | |
1809 | |
1810 if (r->fast_subrequest) { | |
1811 | |
1812 if (rc == NGX_AGAIN) { | |
1813 r->fast_subrequest = 0; | |
1814 } | |
1815 | |
1816 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1817 "http fast subrequest: \"%V?%V\" done", | |
1818 &r->uri, &r->args); | |
1819 return; | |
1820 } | |
1821 | |
1822 if (rc != NGX_AGAIN) { | |
1823 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1824 "http wake parent request: \"%V?%V\"", | |
1825 &pr->uri, &pr->args); | |
1826 | |
1827 pr->write_event_handler(pr); | |
1828 } | |
1829 } | |
1830 | |
1831 return; | |
1832 } | |
1833 | |
1834 if (rc == NGX_AGAIN) { | |
1835 return; | |
1836 } | |
1837 | |
1838 if (c->buffered) { | |
1839 (void) ngx_http_set_write_handler(r); | |
1840 return; | |
1841 } | |
1842 | 1908 |
1843 if (!r->post_action) { | 1909 if (!r->post_action) { |
1844 r->request_complete = 1; | 1910 r->request_complete = 1; |
1845 } | 1911 } |
1846 | 1912 |
1863 | 1929 |
1864 if (c->read->eof) { | 1930 if (c->read->eof) { |
1865 ngx_http_close_request(r, 0); | 1931 ngx_http_close_request(r, 0); |
1866 return; | 1932 return; |
1867 } | 1933 } |
1934 | |
1935 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1868 | 1936 |
1869 if (!ngx_terminate | 1937 if (!ngx_terminate |
1870 && !ngx_exiting | 1938 && !ngx_exiting |
1871 && r->keepalive | 1939 && r->keepalive |
1872 && clcf->keepalive_timeout > 0) | 1940 && clcf->keepalive_timeout > 0) |
1926 wev = c->write; | 1994 wev = c->write; |
1927 | 1995 |
1928 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 1996 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1929 "http writer handler: \"%V?%V\"", &r->uri, &r->args); | 1997 "http writer handler: \"%V?%V\"", &r->uri, &r->args); |
1930 | 1998 |
1999 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | |
2000 | |
1931 if (wev->timedout) { | 2001 if (wev->timedout) { |
1932 if (!wev->delayed) { | 2002 if (!wev->delayed) { |
1933 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | 2003 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
1934 "client timed out"); | 2004 "client timed out"); |
1935 c->timedout = 1; | 2005 c->timedout = 1; |
1940 | 2010 |
1941 wev->timedout = 0; | 2011 wev->timedout = 0; |
1942 wev->delayed = 0; | 2012 wev->delayed = 0; |
1943 | 2013 |
1944 if (!wev->ready) { | 2014 if (!wev->ready) { |
1945 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | |
1946 ngx_add_timer(wev, clcf->send_timeout); | 2015 ngx_add_timer(wev, clcf->send_timeout); |
1947 | 2016 |
1948 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 2017 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1949 ngx_http_close_request(r, 0); | 2018 ngx_http_close_request(r, 0); |
1950 } | 2019 } |
1955 } else { | 2024 } else { |
1956 if (wev->delayed) { | 2025 if (wev->delayed) { |
1957 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2026 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1958 "http writer delayed"); | 2027 "http writer delayed"); |
1959 | 2028 |
1960 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | |
1961 | |
1962 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 2029 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1963 ngx_http_close_request(r, 0); | 2030 ngx_http_close_request(r, 0); |
1964 } | 2031 } |
1965 | 2032 |
1966 return; | 2033 return; |
1975 | 2042 |
1976 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2043 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1977 "http writer output filter: %d, \"%V?%V\"", | 2044 "http writer output filter: %d, \"%V?%V\"", |
1978 rc, &r->uri, &r->args); | 2045 rc, &r->uri, &r->args); |
1979 | 2046 |
1980 if (rc == NGX_AGAIN) { | 2047 if (r->buffered || r->postponed || (r == r->main && c->buffered)) { |
1981 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | 2048 |
1982 if (!wev->ready && !wev->delayed) { | 2049 if (!wev->ready && !wev->delayed) { |
1983 ngx_add_timer(wev, clcf->send_timeout); | 2050 ngx_add_timer(wev, clcf->send_timeout); |
1984 } | 2051 } |
1985 | 2052 |
1986 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 2053 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1987 ngx_http_close_request(r, 0); | 2054 ngx_http_close_request(r, 0); |
1988 } | 2055 } |
1989 | 2056 |
1990 if (r == r->main || r->buffered) { | 2057 return; |
1991 return; | |
1992 } | |
1993 | |
1994 rc = NGX_OK; | |
1995 } | 2058 } |
1996 | 2059 |
1997 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2060 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1998 "http writer done: \"%V?%V\"", &r->uri, &r->args); | 2061 "http writer done: \"%V?%V\"", &r->uri, &r->args); |
1999 | 2062 |
2000 ngx_http_finalize_request(r, rc); | 2063 ngx_http_finalize_request(r, rc); |
2064 } | |
2065 | |
2066 | |
2067 static void | |
2068 ngx_http_request_finalizer(ngx_http_request_t *r) | |
2069 { | |
2070 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2071 "http finalizer done: \"%V?%V\"", &r->uri, &r->args); | |
2072 | |
2073 ngx_http_finalize_request(r, 0); | |
2001 } | 2074 } |
2002 | 2075 |
2003 | 2076 |
2004 void | 2077 void |
2005 ngx_http_block_reading(ngx_http_request_t *r) | 2078 ngx_http_block_reading(ngx_http_request_t *r) |