Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 3049:67254117b774
request reference counter
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 26 Aug 2009 16:04:05 +0000 |
parents | 66ef86affbb8 |
children | f54b02dbb12b |
comparison
equal
deleted
inserted
replaced
3048:846d0e2fa483 | 3049:67254117b774 |
---|---|
34 static ssize_t ngx_http_validate_host(u_char *host, size_t len); | 34 static ssize_t ngx_http_validate_host(u_char *host, size_t len); |
35 static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, | 35 static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, |
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 void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); | |
40 static void ngx_http_terminate_handler(ngx_http_request_t *r); | |
41 static void ngx_http_finalize_connection(ngx_http_request_t *r); | |
39 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); | 42 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); | 43 static void ngx_http_writer(ngx_http_request_t *r); |
41 static void ngx_http_request_finalizer(ngx_http_request_t *r); | 44 static void ngx_http_request_finalizer(ngx_http_request_t *r); |
42 | 45 |
43 static void ngx_http_set_keepalive(ngx_http_request_t *r); | 46 static void ngx_http_set_keepalive(ngx_http_request_t *r); |
44 static void ngx_http_keepalive_handler(ngx_event_t *ev); | 47 static void ngx_http_keepalive_handler(ngx_event_t *ev); |
45 static void ngx_http_set_lingering_close(ngx_http_request_t *r); | 48 static void ngx_http_set_lingering_close(ngx_http_request_t *r); |
46 static void ngx_http_lingering_close_handler(ngx_event_t *ev); | 49 static void ngx_http_lingering_close_handler(ngx_event_t *ev); |
47 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); | 50 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); |
48 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); | 51 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); |
49 static void ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error); | 52 static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error); |
50 static void ngx_http_log_request(ngx_http_request_t *r); | 53 static void ngx_http_log_request(ngx_http_request_t *r); |
51 static void ngx_http_close_connection(ngx_connection_t *c); | 54 static void ngx_http_close_connection(ngx_connection_t *c); |
52 | 55 |
53 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); | 56 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); |
54 static u_char *ngx_http_log_error_handler(ngx_http_request_t *r, | 57 static u_char *ngx_http_log_error_handler(ngx_http_request_t *r, |
476 | 479 |
477 c->single_connection = 1; | 480 c->single_connection = 1; |
478 c->destroyed = 0; | 481 c->destroyed = 0; |
479 | 482 |
480 r->main = r; | 483 r->main = r; |
484 r->count = 1; | |
481 | 485 |
482 tp = ngx_timeofday(); | 486 tp = ngx_timeofday(); |
483 r->start_sec = tp->sec; | 487 r->start_sec = tp->sec; |
484 r->start_msec = tp->msec; | 488 r->start_msec = tp->msec; |
485 | 489 |
1826 { | 1830 { |
1827 ngx_connection_t *c; | 1831 ngx_connection_t *c; |
1828 ngx_http_request_t *pr; | 1832 ngx_http_request_t *pr; |
1829 ngx_http_core_loc_conf_t *clcf; | 1833 ngx_http_core_loc_conf_t *clcf; |
1830 | 1834 |
1835 c = r->connection; | |
1836 | |
1837 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1838 "http finalize request: %d, \"%V?%V\" a:%d, c:%d", | |
1839 rc, &r->uri, &r->args, r == c->data, r->main->count); | |
1840 | |
1831 if (rc == NGX_DONE) { | 1841 if (rc == NGX_DONE) { |
1832 /* the request pool may be already destroyed */ | 1842 ngx_http_finalize_connection(r); |
1833 return; | 1843 return; |
1834 } | 1844 } |
1835 | |
1836 c = r->connection; | |
1837 | |
1838 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1839 "http finalize request: %d, \"%V?%V\" %d", | |
1840 rc, &r->uri, &r->args, r == c->data); | |
1841 | 1845 |
1842 if (rc == NGX_OK && r->filter_finalize) { | 1846 if (rc == NGX_OK && r->filter_finalize) { |
1843 c->error = 1; | 1847 c->error = 1; |
1844 return; | 1848 return; |
1845 } | 1849 } |
1858 if (rc == NGX_ERROR | 1862 if (rc == NGX_ERROR |
1859 || rc == NGX_HTTP_REQUEST_TIME_OUT | 1863 || rc == NGX_HTTP_REQUEST_TIME_OUT |
1860 || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST | 1864 || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST |
1861 || c->error) | 1865 || c->error) |
1862 { | 1866 { |
1863 if (rc > 0 && r->headers_out.status == 0) { | |
1864 r->headers_out.status = rc; | |
1865 } | |
1866 | |
1867 if (ngx_http_post_action(r) == NGX_OK) { | 1867 if (ngx_http_post_action(r) == NGX_OK) { |
1868 return; | 1868 return; |
1869 } | 1869 } |
1870 | 1870 |
1871 ngx_http_close_request(r, 0); | 1871 ngx_http_terminate_request(r, rc); |
1872 return; | 1872 return; |
1873 } | 1873 } |
1874 | 1874 |
1875 if (rc >= NGX_HTTP_SPECIAL_RESPONSE | 1875 if (rc >= NGX_HTTP_SPECIAL_RESPONSE |
1876 || rc == NGX_HTTP_CREATED | 1876 || rc == NGX_HTTP_CREATED |
1877 || rc == NGX_HTTP_NO_CONTENT) | 1877 || rc == NGX_HTTP_NO_CONTENT) |
1878 { | 1878 { |
1879 if (rc == NGX_HTTP_CLOSE) { | 1879 if (rc == NGX_HTTP_CLOSE) { |
1880 ngx_http_close_request(r, rc); | 1880 ngx_http_terminate_request(r, rc); |
1881 return; | 1881 return; |
1882 } | 1882 } |
1883 | 1883 |
1884 if (r == r->main) { | 1884 if (r == r->main) { |
1885 if (c->read->timer_set) { | 1885 if (c->read->timer_set) { |
1901 if (r != r->main) { | 1901 if (r != r->main) { |
1902 | 1902 |
1903 if (r->buffered || r->postponed) { | 1903 if (r->buffered || r->postponed) { |
1904 | 1904 |
1905 if (ngx_http_set_write_handler(r) != NGX_OK) { | 1905 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1906 ngx_http_close_request(r->main, 0); | 1906 ngx_http_terminate_request(r, 0); |
1907 } | 1907 } |
1908 | 1908 |
1909 return; | 1909 return; |
1910 } | 1910 } |
1911 | 1911 |
1919 | 1919 |
1920 pr = r->parent; | 1920 pr = r->parent; |
1921 | 1921 |
1922 if (r == c->data) { | 1922 if (r == c->data) { |
1923 | 1923 |
1924 r->main->count--; | |
1925 | |
1924 if (!r->logged) { | 1926 if (!r->logged) { |
1925 | 1927 |
1926 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1928 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1927 | 1929 |
1928 if (clcf->log_subrequest) { | 1930 if (clcf->log_subrequest) { |
1953 r->done = 1; | 1955 r->done = 1; |
1954 } | 1956 } |
1955 } | 1957 } |
1956 | 1958 |
1957 if (ngx_http_post_request(pr) != NGX_OK) { | 1959 if (ngx_http_post_request(pr) != NGX_OK) { |
1958 ngx_http_close_request(r->main, 0); | 1960 r->main->count++; |
1961 ngx_http_terminate_request(r, 0); | |
1959 return; | 1962 return; |
1960 } | 1963 } |
1961 | 1964 |
1962 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1965 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1963 "http wake parent request: \"%V?%V\"", | 1966 "http wake parent request: \"%V?%V\"", |
1967 } | 1970 } |
1968 | 1971 |
1969 if (r->buffered || c->buffered || r->postponed) { | 1972 if (r->buffered || c->buffered || r->postponed) { |
1970 | 1973 |
1971 if (ngx_http_set_write_handler(r) != NGX_OK) { | 1974 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1972 ngx_http_close_request(r, 0); | 1975 ngx_http_terminate_request(r, 0); |
1973 } | 1976 } |
1974 | 1977 |
1975 return; | 1978 return; |
1976 } | 1979 } |
1977 | 1980 |
2004 if (c->destroyed) { | 2007 if (c->destroyed) { |
2005 return; | 2008 return; |
2006 } | 2009 } |
2007 | 2010 |
2008 if (c->read->eof) { | 2011 if (c->read->eof) { |
2012 ngx_http_close_request(r, 0); | |
2013 return; | |
2014 } | |
2015 | |
2016 ngx_http_finalize_connection(r); | |
2017 } | |
2018 | |
2019 | |
2020 static void | |
2021 ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc) | |
2022 { | |
2023 ngx_http_cleanup_t *cln; | |
2024 ngx_http_request_t *mr; | |
2025 | |
2026 mr = r->main; | |
2027 | |
2028 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2029 "http terminate request count: %d", mr->count); | |
2030 | |
2031 cln = mr->cleanup; | |
2032 mr->cleanup = NULL; | |
2033 | |
2034 while (cln) { | |
2035 if (cln->handler) { | |
2036 cln->handler(cln->data); | |
2037 } | |
2038 | |
2039 cln = cln->next; | |
2040 } | |
2041 | |
2042 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2043 "http terminate cleanup count: %d", mr->count); | |
2044 | |
2045 if (mr->write_event_handler) { | |
2046 mr->posted_requests = NULL; | |
2047 mr->write_event_handler = ngx_http_terminate_handler; | |
2048 (void) ngx_http_post_request(mr); | |
2049 return; | |
2050 } | |
2051 | |
2052 ngx_http_close_request(mr, rc); | |
2053 } | |
2054 | |
2055 | |
2056 static void | |
2057 ngx_http_terminate_handler(ngx_http_request_t *r) | |
2058 { | |
2059 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2060 "http terminate handler count: %d", r->count); | |
2061 | |
2062 r->count = 1; | |
2063 | |
2064 ngx_http_close_request(r, 0); | |
2065 } | |
2066 | |
2067 | |
2068 static void | |
2069 ngx_http_finalize_connection(ngx_http_request_t *r) | |
2070 { | |
2071 ngx_http_core_loc_conf_t *clcf; | |
2072 | |
2073 if (r->main->count != 1) { | |
2009 ngx_http_close_request(r, 0); | 2074 ngx_http_close_request(r, 0); |
2010 return; | 2075 return; |
2011 } | 2076 } |
2012 | 2077 |
2013 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2078 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
2317 hc->busy[0] = b; | 2382 hc->busy[0] = b; |
2318 hc->nbusy = 1; | 2383 hc->nbusy = 1; |
2319 } | 2384 } |
2320 } | 2385 } |
2321 | 2386 |
2322 ngx_http_request_done(r, 0); | 2387 ngx_http_free_request(r, 0); |
2323 | 2388 |
2324 c->data = hc; | 2389 c->data = hc; |
2325 | 2390 |
2326 ngx_add_timer(rev, clcf->keepalive_timeout); | 2391 ngx_add_timer(rev, clcf->keepalive_timeout); |
2327 | 2392 |
2764 return NGX_OK; | 2829 return NGX_OK; |
2765 } | 2830 } |
2766 | 2831 |
2767 | 2832 |
2768 static void | 2833 static void |
2769 ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error) | 2834 ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc) |
2770 { | 2835 { |
2771 ngx_connection_t *c; | 2836 ngx_connection_t *c; |
2772 | 2837 |
2838 r = r->main; | |
2773 c = r->connection; | 2839 c = r->connection; |
2774 | 2840 |
2775 ngx_http_request_done(r->main, error); | 2841 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2842 "http request count: %d", r->count); | |
2843 | |
2844 if (r->count == 0) { | |
2845 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero"); | |
2846 } | |
2847 | |
2848 r->count--; | |
2849 | |
2850 if (r->count) { | |
2851 return; | |
2852 } | |
2853 | |
2854 ngx_http_free_request(r, rc); | |
2776 ngx_http_close_connection(c); | 2855 ngx_http_close_connection(c); |
2777 } | 2856 } |
2778 | 2857 |
2779 | 2858 |
2780 static void | 2859 static void |
2781 ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error) | 2860 ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) |
2782 { | 2861 { |
2783 ngx_log_t *log; | 2862 ngx_log_t *log; |
2784 struct linger linger; | 2863 struct linger linger; |
2785 ngx_http_cleanup_t *cln; | 2864 ngx_http_cleanup_t *cln; |
2786 ngx_http_log_ctx_t *ctx; | 2865 ngx_http_log_ctx_t *ctx; |
2811 (void) ngx_atomic_fetch_add(ngx_stat_writing, -1); | 2890 (void) ngx_atomic_fetch_add(ngx_stat_writing, -1); |
2812 } | 2891 } |
2813 | 2892 |
2814 #endif | 2893 #endif |
2815 | 2894 |
2816 if (error && r->headers_out.status == 0) { | 2895 if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) { |
2817 r->headers_out.status = error; | 2896 r->headers_out.status = rc; |
2818 } | 2897 } |
2819 | 2898 |
2820 log->action = "logging request"; | 2899 log->action = "logging request"; |
2821 | 2900 |
2822 ngx_http_log_request(r); | 2901 ngx_http_log_request(r); |