Mercurial > hg > nginx-mail
comparison src/http/ngx_http_request.c @ 455:e7dbea1ee115 NGINX_0_7_25
nginx 0.7.25
*) Change: in subrequest processing.
*) Change: now POSTs without "Content-Length" header line are allowed.
*) Bugfix: now the "limit_req" and "limit_conn" directives log a
prohibition reason.
*) Bugfix: in the "delete" parameter of the "geo" directive.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 08 Dec 2008 00:00:00 +0300 |
parents | b4f69f2ef02c |
children | dac47e9ef0d5 |
comparison
equal
deleted
inserted
replaced
454:f64d9e30046c | 455:e7dbea1ee115 |
---|---|
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); |
1409 ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); | 1410 ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); |
1410 return NGX_ERROR; | 1411 return NGX_ERROR; |
1411 } | 1412 } |
1412 } | 1413 } |
1413 | 1414 |
1414 if (r->method & (NGX_HTTP_POST|NGX_HTTP_PUT) | 1415 if (r->method & NGX_HTTP_PUT && r->headers_in.content_length_n == -1) { |
1415 && r->headers_in.content_length_n == -1) | |
1416 { | |
1417 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 1416 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1418 "client sent %V method without \"Content-Length\" header", | 1417 "client sent %V method without \"Content-Length\" header", |
1419 &r->method_name); | 1418 &r->method_name); |
1420 ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); | 1419 ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); |
1421 return NGX_ERROR; | 1420 return NGX_ERROR; |
1522 c->write->handler = ngx_http_request_handler; | 1521 c->write->handler = ngx_http_request_handler; |
1523 r->read_event_handler = ngx_http_block_reading; | 1522 r->read_event_handler = ngx_http_block_reading; |
1524 | 1523 |
1525 ngx_http_handler(r); | 1524 ngx_http_handler(r); |
1526 | 1525 |
1527 return; | 1526 ngx_http_run_posted_requests(c); |
1528 } | 1527 } |
1529 | 1528 |
1530 | 1529 |
1531 static ssize_t | 1530 static ssize_t |
1532 ngx_http_validate_host(u_char *host, size_t len) | 1531 ngx_http_validate_host(u_char *host, size_t len) |
1675 r = c->data; | 1674 r = c->data; |
1676 | 1675 |
1677 ctx = c->log->data; | 1676 ctx = c->log->data; |
1678 ctx->current_request = r; | 1677 ctx->current_request = r; |
1679 | 1678 |
1679 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1680 "http run request: \"%V?%V\"", &r->uri, &r->args); | |
1681 | |
1680 if (ev->write) { | 1682 if (ev->write) { |
1681 r->write_event_handler(r); | 1683 r->write_event_handler(r); |
1682 | 1684 |
1683 } else { | 1685 } else { |
1684 r->read_event_handler(r); | 1686 r->read_event_handler(r); |
1685 } | 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; | |
1686 } | 1746 } |
1687 | 1747 |
1688 | 1748 |
1689 void | 1749 void |
1690 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) |
1691 { | 1751 { |
1692 ngx_connection_t *c; | 1752 ngx_connection_t *c; |
1693 ngx_http_request_t *pr; | 1753 ngx_http_request_t *pr; |
1694 ngx_http_log_ctx_t *ctx; | |
1695 ngx_http_core_loc_conf_t *clcf; | 1754 ngx_http_core_loc_conf_t *clcf; |
1696 | 1755 |
1697 if (rc == NGX_DONE) { | 1756 if (rc == NGX_DONE) { |
1698 /* the request pool may be already destroyed */ | 1757 /* the request pool may be already destroyed */ |
1699 return; | 1758 return; |
1700 } | 1759 } |
1701 | 1760 |
1702 c = r->connection; | 1761 c = r->connection; |
1703 | 1762 |
1704 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1763 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1705 "http finalize request: %d, \"%V?%V\"", | 1764 "http finalize request: %d, \"%V?%V\" %d", |
1706 rc, &r->uri, &r->args); | 1765 rc, &r->uri, &r->args, r == c->data); |
1707 | 1766 |
1708 if (rc == NGX_DECLINED) { | 1767 if (rc == NGX_DECLINED) { |
1709 r->content_handler = NULL; | 1768 r->content_handler = NULL; |
1710 r->write_event_handler = ngx_http_core_run_phases; | 1769 r->write_event_handler = ngx_http_core_run_phases; |
1711 ngx_http_core_run_phases(r); | 1770 ngx_http_core_run_phases(r); |
1757 | 1816 |
1758 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)); |
1759 return; | 1818 return; |
1760 } | 1819 } |
1761 | 1820 |
1762 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1821 if (r != r->main) { |
1763 | 1822 |
1764 if (r != r->main && !r->logged) { | 1823 if (r->buffered || r->postponed) { |
1765 | 1824 |
1766 if (clcf->log_subrequest) { | 1825 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1767 ngx_http_log_request(r); | 1826 ngx_http_close_request(r->main, 0); |
1768 } | 1827 } |
1769 | 1828 |
1770 r->logged = 1; | 1829 return; |
1771 } | 1830 } |
1772 | 1831 |
1773 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 | |
1774 if (ngx_http_set_write_handler(r) != NGX_OK) { | 1893 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1775 return; | 1894 ngx_http_close_request(r, 0); |
1776 } | 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; | |
1777 } | 1905 } |
1778 | 1906 |
1779 r->done = 1; | 1907 r->done = 1; |
1780 | |
1781 if (r != c->data) { | |
1782 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1783 "http finalize non-active request: \"%V?%V\"", | |
1784 &r->uri, &r->args); | |
1785 return; | |
1786 } | |
1787 | |
1788 if (r != r->main) { | |
1789 | |
1790 pr = r->parent; | |
1791 | |
1792 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1793 "http parent request: \"%V?%V\"", &pr->uri, &pr->args); | |
1794 | |
1795 if (rc != NGX_AGAIN) { | |
1796 c->data = pr; | |
1797 } | |
1798 | |
1799 ctx = c->log->data; | |
1800 ctx->current_request = pr; | |
1801 | |
1802 if (pr->postponed) { | |
1803 | |
1804 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1805 "http request: \"%V?%V\" has postponed", | |
1806 &pr->uri, &pr->args); | |
1807 | |
1808 if (rc != NGX_AGAIN && pr->postponed->request == r) { | |
1809 pr->postponed = pr->postponed->next; | |
1810 } | |
1811 | |
1812 if (r->fast_subrequest) { | |
1813 | |
1814 if (rc == NGX_AGAIN) { | |
1815 r->fast_subrequest = 0; | |
1816 } | |
1817 | |
1818 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1819 "http fast subrequest: \"%V?%V\" done", | |
1820 &r->uri, &r->args); | |
1821 return; | |
1822 } | |
1823 | |
1824 if (rc != NGX_AGAIN) { | |
1825 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1826 "http wake parent request: \"%V?%V\"", | |
1827 &pr->uri, &pr->args); | |
1828 | |
1829 pr->write_event_handler(pr); | |
1830 } | |
1831 } | |
1832 | |
1833 return; | |
1834 } | |
1835 | |
1836 if (rc == NGX_AGAIN) { | |
1837 return; | |
1838 } | |
1839 | |
1840 if (c->buffered) { | |
1841 (void) ngx_http_set_write_handler(r); | |
1842 return; | |
1843 } | |
1844 | 1908 |
1845 if (!r->post_action) { | 1909 if (!r->post_action) { |
1846 r->request_complete = 1; | 1910 r->request_complete = 1; |
1847 } | 1911 } |
1848 | 1912 |
1865 | 1929 |
1866 if (c->read->eof) { | 1930 if (c->read->eof) { |
1867 ngx_http_close_request(r, 0); | 1931 ngx_http_close_request(r, 0); |
1868 return; | 1932 return; |
1869 } | 1933 } |
1934 | |
1935 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1870 | 1936 |
1871 if (!ngx_terminate | 1937 if (!ngx_terminate |
1872 && !ngx_exiting | 1938 && !ngx_exiting |
1873 && r->keepalive | 1939 && r->keepalive |
1874 && clcf->keepalive_timeout > 0) | 1940 && clcf->keepalive_timeout > 0) |
1928 wev = c->write; | 1994 wev = c->write; |
1929 | 1995 |
1930 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 1996 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1931 "http writer handler: \"%V?%V\"", &r->uri, &r->args); | 1997 "http writer handler: \"%V?%V\"", &r->uri, &r->args); |
1932 | 1998 |
1999 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | |
2000 | |
1933 if (wev->timedout) { | 2001 if (wev->timedout) { |
1934 if (!wev->delayed) { | 2002 if (!wev->delayed) { |
1935 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | 2003 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
1936 "client timed out"); | 2004 "client timed out"); |
1937 c->timedout = 1; | 2005 c->timedout = 1; |
1942 | 2010 |
1943 wev->timedout = 0; | 2011 wev->timedout = 0; |
1944 wev->delayed = 0; | 2012 wev->delayed = 0; |
1945 | 2013 |
1946 if (!wev->ready) { | 2014 if (!wev->ready) { |
1947 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | |
1948 ngx_add_timer(wev, clcf->send_timeout); | 2015 ngx_add_timer(wev, clcf->send_timeout); |
1949 | 2016 |
1950 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 2017 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1951 ngx_http_close_request(r, 0); | 2018 ngx_http_close_request(r, 0); |
1952 } | 2019 } |
1957 } else { | 2024 } else { |
1958 if (wev->delayed) { | 2025 if (wev->delayed) { |
1959 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2026 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1960 "http writer delayed"); | 2027 "http writer delayed"); |
1961 | 2028 |
1962 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | |
1963 | |
1964 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 2029 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1965 ngx_http_close_request(r, 0); | 2030 ngx_http_close_request(r, 0); |
1966 } | 2031 } |
1967 | 2032 |
1968 return; | 2033 return; |
1977 | 2042 |
1978 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2043 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1979 "http writer output filter: %d, \"%V?%V\"", | 2044 "http writer output filter: %d, \"%V?%V\"", |
1980 rc, &r->uri, &r->args); | 2045 rc, &r->uri, &r->args); |
1981 | 2046 |
1982 if (rc == NGX_AGAIN) { | 2047 if (r->buffered || r->postponed || (r == r->main && c->buffered)) { |
1983 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | 2048 |
1984 if (!wev->ready && !wev->delayed) { | 2049 if (!wev->ready && !wev->delayed) { |
1985 ngx_add_timer(wev, clcf->send_timeout); | 2050 ngx_add_timer(wev, clcf->send_timeout); |
1986 } | 2051 } |
1987 | 2052 |
1988 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 2053 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1989 ngx_http_close_request(r, 0); | 2054 ngx_http_close_request(r, 0); |
1990 } | 2055 } |
1991 | 2056 |
1992 if (r == r->main || r->buffered) { | 2057 return; |
1993 return; | |
1994 } | |
1995 | |
1996 rc = NGX_OK; | |
1997 } | 2058 } |
1998 | 2059 |
1999 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2060 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
2000 "http writer done: \"%V?%V\"", &r->uri, &r->args); | 2061 "http writer done: \"%V?%V\"", &r->uri, &r->args); |
2001 | 2062 |
2002 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); | |
2003 } | 2074 } |
2004 | 2075 |
2005 | 2076 |
2006 void | 2077 void |
2007 ngx_http_block_reading(ngx_http_request_t *r) | 2078 ngx_http_block_reading(ngx_http_request_t *r) |