Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_request.c @ 539:5f4de8cf0d9d
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 15 Sep 2009 03:43:40 +0400 |
parents | 80f7156c2965 |
children | 005a70f9573b |
comparison
equal
deleted
inserted
replaced
522:40fd8d7b82f9 | 539:5f4de8cf0d9d |
---|---|
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 |
887 | 891 |
888 | 892 |
889 static void | 893 static void |
890 ngx_http_process_request_headers(ngx_event_t *rev) | 894 ngx_http_process_request_headers(ngx_event_t *rev) |
891 { | 895 { |
896 u_char *p; | |
897 size_t len; | |
892 ssize_t n; | 898 ssize_t n; |
893 ngx_int_t rc, rv; | 899 ngx_int_t rc, rv; |
894 ngx_str_t header; | |
895 ngx_table_elt_t *h; | 900 ngx_table_elt_t *h; |
896 ngx_connection_t *c; | 901 ngx_connection_t *c; |
897 ngx_http_header_t *hh; | 902 ngx_http_header_t *hh; |
898 ngx_http_request_t *r; | 903 ngx_http_request_t *r; |
899 ngx_http_core_srv_conf_t *cscf; | 904 ngx_http_core_srv_conf_t *cscf; |
929 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 934 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
930 return; | 935 return; |
931 } | 936 } |
932 | 937 |
933 if (rv == NGX_DECLINED) { | 938 if (rv == NGX_DECLINED) { |
934 header.len = r->header_in->end - r->header_name_start; | 939 len = r->header_in->end - r->header_name_start; |
935 header.data = r->header_name_start; | 940 p = r->header_name_start; |
936 | 941 |
937 if (header.len > NGX_MAX_ERROR_STR - 300) { | 942 if (len > NGX_MAX_ERROR_STR - 300) { |
938 header.len = NGX_MAX_ERROR_STR - 300; | 943 len = NGX_MAX_ERROR_STR - 300; |
939 header.data[header.len++] = '.'; | 944 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; |
940 header.data[header.len++] = '.'; | |
941 header.data[header.len++] = '.'; | |
942 } | 945 } |
943 | 946 |
944 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 947 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
945 "client sent too long header line: \"%V\"", | 948 "client sent too long header line: \"%*s\"", |
946 &header); | 949 len, r->header_name_start); |
947 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 950 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
948 return; | 951 return; |
949 } | 952 } |
950 } | 953 } |
951 | 954 |
963 | 966 |
964 if (r->invalid_header && cscf->ignore_invalid_headers) { | 967 if (r->invalid_header && cscf->ignore_invalid_headers) { |
965 | 968 |
966 /* there was error while a header line parsing */ | 969 /* there was error while a header line parsing */ |
967 | 970 |
968 header.len = r->header_end - r->header_name_start; | |
969 header.data = r->header_name_start; | |
970 | |
971 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 971 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
972 "client sent invalid header line: \"%V\"", | 972 "client sent invalid header line: \"%*s\"", |
973 &header); | 973 r->header_end - r->header_name_start, |
974 r->header_name_start); | |
974 continue; | 975 continue; |
975 } | 976 } |
976 | 977 |
977 /* a header line has been parsed successfully */ | 978 /* a header line has been parsed successfully */ |
978 | 979 |
1048 continue; | 1049 continue; |
1049 } | 1050 } |
1050 | 1051 |
1051 /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */ | 1052 /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */ |
1052 | 1053 |
1053 header.len = r->header_end - r->header_name_start; | |
1054 header.data = r->header_name_start; | |
1055 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 1054 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
1056 "client sent invalid header line: \"%V\\r...\"", | 1055 "client sent invalid header line: \"%*s\\r...\"", |
1057 &header); | 1056 r->header_end - r->header_name_start, |
1057 r->header_name_start); | |
1058 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 1058 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
1059 return; | 1059 return; |
1060 } | 1060 } |
1061 } | 1061 } |
1062 | 1062 |
1380 switch (msie[5]) { | 1380 switch (msie[5]) { |
1381 case '4': | 1381 case '4': |
1382 r->headers_in.msie4 = 1; | 1382 r->headers_in.msie4 = 1; |
1383 /* fall through */ | 1383 /* fall through */ |
1384 case '5': | 1384 case '5': |
1385 r->headers_in.msie6 = 1; | |
1386 break; | |
1385 case '6': | 1387 case '6': |
1386 r->headers_in.msie6 = 1; | 1388 if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) { |
1389 r->headers_in.msie6 = 1; | |
1390 } | |
1391 break; | |
1387 } | 1392 } |
1388 } | 1393 } |
1389 | 1394 |
1390 #if 0 | 1395 #if 0 |
1391 /* MSIE ignores the SSL "close notify" alert */ | 1396 /* MSIE ignores the SSL "close notify" alert */ |
1799 } | 1804 } |
1800 } | 1805 } |
1801 | 1806 |
1802 | 1807 |
1803 ngx_int_t | 1808 ngx_int_t |
1804 ngx_http_post_request(ngx_http_request_t *r) | 1809 ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr) |
1805 { | 1810 { |
1806 ngx_http_posted_request_t *pr, **p; | 1811 ngx_http_posted_request_t **p; |
1807 | 1812 |
1808 pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t)); | |
1809 if (pr == NULL) { | 1813 if (pr == NULL) { |
1810 return NGX_ERROR; | 1814 pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t)); |
1815 if (pr == NULL) { | |
1816 return NGX_ERROR; | |
1817 } | |
1811 } | 1818 } |
1812 | 1819 |
1813 pr->request = r; | 1820 pr->request = r; |
1814 pr->next = NULL; | 1821 pr->next = NULL; |
1815 | 1822 |
1826 { | 1833 { |
1827 ngx_connection_t *c; | 1834 ngx_connection_t *c; |
1828 ngx_http_request_t *pr; | 1835 ngx_http_request_t *pr; |
1829 ngx_http_core_loc_conf_t *clcf; | 1836 ngx_http_core_loc_conf_t *clcf; |
1830 | 1837 |
1838 c = r->connection; | |
1839 | |
1840 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1841 "http finalize request: %d, \"%V?%V\" a:%d, c:%d", | |
1842 rc, &r->uri, &r->args, r == c->data, r->main->count); | |
1843 | |
1831 if (rc == NGX_DONE) { | 1844 if (rc == NGX_DONE) { |
1832 /* the request pool may be already destroyed */ | 1845 ngx_http_finalize_connection(r); |
1833 return; | 1846 return; |
1834 } | 1847 } |
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 | 1848 |
1842 if (rc == NGX_OK && r->filter_finalize) { | 1849 if (rc == NGX_OK && r->filter_finalize) { |
1843 c->error = 1; | 1850 c->error = 1; |
1844 return; | 1851 return; |
1845 } | 1852 } |
1858 if (rc == NGX_ERROR | 1865 if (rc == NGX_ERROR |
1859 || rc == NGX_HTTP_REQUEST_TIME_OUT | 1866 || rc == NGX_HTTP_REQUEST_TIME_OUT |
1860 || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST | 1867 || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST |
1861 || c->error) | 1868 || c->error) |
1862 { | 1869 { |
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) { | 1870 if (ngx_http_post_action(r) == NGX_OK) { |
1868 return; | 1871 return; |
1869 } | 1872 } |
1870 | 1873 |
1871 ngx_http_close_request(r, 0); | 1874 if (r->main->blocked) { |
1875 r->write_event_handler = ngx_http_request_finalizer; | |
1876 } | |
1877 | |
1878 ngx_http_terminate_request(r, rc); | |
1872 return; | 1879 return; |
1873 } | 1880 } |
1874 | 1881 |
1875 if (rc >= NGX_HTTP_SPECIAL_RESPONSE | 1882 if (rc >= NGX_HTTP_SPECIAL_RESPONSE |
1876 || rc == NGX_HTTP_CREATED | 1883 || rc == NGX_HTTP_CREATED |
1877 || rc == NGX_HTTP_NO_CONTENT) | 1884 || rc == NGX_HTTP_NO_CONTENT) |
1878 { | 1885 { |
1879 if (rc == NGX_HTTP_CLOSE) { | 1886 if (rc == NGX_HTTP_CLOSE) { |
1880 ngx_http_close_request(r, rc); | 1887 ngx_http_terminate_request(r, rc); |
1881 return; | 1888 return; |
1882 } | 1889 } |
1883 | 1890 |
1884 if (r == r->main) { | 1891 if (r == r->main) { |
1885 if (c->read->timer_set) { | 1892 if (c->read->timer_set) { |
1901 if (r != r->main) { | 1908 if (r != r->main) { |
1902 | 1909 |
1903 if (r->buffered || r->postponed) { | 1910 if (r->buffered || r->postponed) { |
1904 | 1911 |
1905 if (ngx_http_set_write_handler(r) != NGX_OK) { | 1912 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1906 ngx_http_close_request(r->main, 0); | 1913 ngx_http_terminate_request(r, 0); |
1907 } | 1914 } |
1908 | 1915 |
1909 return; | 1916 return; |
1910 } | 1917 } |
1911 | 1918 |
1919 | 1926 |
1920 pr = r->parent; | 1927 pr = r->parent; |
1921 | 1928 |
1922 if (r == c->data) { | 1929 if (r == c->data) { |
1923 | 1930 |
1931 r->main->count--; | |
1932 | |
1924 if (!r->logged) { | 1933 if (!r->logged) { |
1925 | 1934 |
1926 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1935 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1927 | 1936 |
1928 if (clcf->log_subrequest) { | 1937 if (clcf->log_subrequest) { |
1952 if (r->waited) { | 1961 if (r->waited) { |
1953 r->done = 1; | 1962 r->done = 1; |
1954 } | 1963 } |
1955 } | 1964 } |
1956 | 1965 |
1957 if (ngx_http_post_request(pr) != NGX_OK) { | 1966 if (ngx_http_post_request(pr, NULL) != NGX_OK) { |
1958 ngx_http_close_request(r->main, 0); | 1967 r->main->count++; |
1968 ngx_http_terminate_request(r, 0); | |
1959 return; | 1969 return; |
1960 } | 1970 } |
1961 | 1971 |
1962 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1972 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1963 "http wake parent request: \"%V?%V\"", | 1973 "http wake parent request: \"%V?%V\"", |
1964 &pr->uri, &pr->args); | 1974 &pr->uri, &pr->args); |
1965 | 1975 |
1966 return; | 1976 return; |
1967 } | 1977 } |
1968 | 1978 |
1969 if (r->buffered || c->buffered || r->postponed) { | 1979 if (r->buffered || c->buffered || r->postponed || r->blocked) { |
1970 | 1980 |
1971 if (ngx_http_set_write_handler(r) != NGX_OK) { | 1981 if (ngx_http_set_write_handler(r) != NGX_OK) { |
1972 ngx_http_close_request(r, 0); | 1982 ngx_http_terminate_request(r, 0); |
1973 } | 1983 } |
1974 | 1984 |
1975 return; | 1985 return; |
1976 } | 1986 } |
1977 | 1987 |
1999 if (c->write->timer_set) { | 2009 if (c->write->timer_set) { |
2000 c->write->delayed = 0; | 2010 c->write->delayed = 0; |
2001 ngx_del_timer(c->write); | 2011 ngx_del_timer(c->write); |
2002 } | 2012 } |
2003 | 2013 |
2004 if (c->destroyed) { | |
2005 return; | |
2006 } | |
2007 | |
2008 if (c->read->eof) { | 2014 if (c->read->eof) { |
2015 ngx_http_close_request(r, 0); | |
2016 return; | |
2017 } | |
2018 | |
2019 ngx_http_finalize_connection(r); | |
2020 } | |
2021 | |
2022 | |
2023 static void | |
2024 ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc) | |
2025 { | |
2026 ngx_http_cleanup_t *cln; | |
2027 ngx_http_request_t *mr; | |
2028 ngx_http_ephemeral_t *e; | |
2029 | |
2030 mr = r->main; | |
2031 | |
2032 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2033 "http terminate request count:%d", mr->count); | |
2034 | |
2035 cln = mr->cleanup; | |
2036 mr->cleanup = NULL; | |
2037 | |
2038 while (cln) { | |
2039 if (cln->handler) { | |
2040 cln->handler(cln->data); | |
2041 } | |
2042 | |
2043 cln = cln->next; | |
2044 } | |
2045 | |
2046 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2047 "http terminate cleanup count:%d blk:%d", | |
2048 mr->count, mr->blocked); | |
2049 | |
2050 if (mr->write_event_handler) { | |
2051 | |
2052 if (mr->blocked) { | |
2053 return; | |
2054 } | |
2055 | |
2056 e = ngx_http_ephemeral(mr); | |
2057 mr->posted_requests = NULL; | |
2058 mr->write_event_handler = ngx_http_terminate_handler; | |
2059 (void) ngx_http_post_request(mr, &e->terminal_posted_request); | |
2060 return; | |
2061 } | |
2062 | |
2063 ngx_http_close_request(mr, rc); | |
2064 } | |
2065 | |
2066 | |
2067 static void | |
2068 ngx_http_terminate_handler(ngx_http_request_t *r) | |
2069 { | |
2070 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2071 "http terminate handler count:%d", r->count); | |
2072 | |
2073 r->count = 1; | |
2074 | |
2075 ngx_http_close_request(r, 0); | |
2076 } | |
2077 | |
2078 | |
2079 static void | |
2080 ngx_http_finalize_connection(ngx_http_request_t *r) | |
2081 { | |
2082 ngx_http_core_loc_conf_t *clcf; | |
2083 | |
2084 if (r->main->count != 1) { | |
2009 ngx_http_close_request(r, 0); | 2085 ngx_http_close_request(r, 0); |
2010 return; | 2086 return; |
2011 } | 2087 } |
2012 | 2088 |
2013 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2089 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
2098 | 2174 |
2099 return; | 2175 return; |
2100 } | 2176 } |
2101 | 2177 |
2102 } else { | 2178 } else { |
2103 if (wev->delayed) { | 2179 if (wev->delayed || r->aio) { |
2104 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2180 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
2105 "http writer delayed"); | 2181 "http writer delayed"); |
2106 | 2182 |
2107 if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { | 2183 if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { |
2108 ngx_http_close_request(r, 0); | 2184 ngx_http_close_request(r, 0); |
2111 return; | 2187 return; |
2112 } | 2188 } |
2113 } | 2189 } |
2114 | 2190 |
2115 rc = ngx_http_output_filter(r, NULL); | 2191 rc = ngx_http_output_filter(r, NULL); |
2116 | |
2117 if (c->destroyed) { | |
2118 return; | |
2119 } | |
2120 | 2192 |
2121 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2193 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2122 "http writer output filter: %d, \"%V?%V\"", | 2194 "http writer output filter: %d, \"%V?%V\"", |
2123 rc, &r->uri, &r->args); | 2195 rc, &r->uri, &r->args); |
2124 | 2196 |
2317 hc->busy[0] = b; | 2389 hc->busy[0] = b; |
2318 hc->nbusy = 1; | 2390 hc->nbusy = 1; |
2319 } | 2391 } |
2320 } | 2392 } |
2321 | 2393 |
2322 ngx_http_request_done(r, 0); | 2394 ngx_http_free_request(r, 0); |
2323 | 2395 |
2324 c->data = hc; | 2396 c->data = hc; |
2325 | 2397 |
2326 ngx_add_timer(rev, clcf->keepalive_timeout); | 2398 ngx_add_timer(rev, clcf->keepalive_timeout); |
2327 | 2399 |
2764 return NGX_OK; | 2836 return NGX_OK; |
2765 } | 2837 } |
2766 | 2838 |
2767 | 2839 |
2768 static void | 2840 static void |
2769 ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error) | 2841 ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc) |
2770 { | 2842 { |
2771 ngx_connection_t *c; | 2843 ngx_connection_t *c; |
2772 | 2844 |
2845 r = r->main; | |
2773 c = r->connection; | 2846 c = r->connection; |
2774 | 2847 |
2775 ngx_http_request_done(r->main, error); | 2848 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2849 "http request count:%d blk:%d", r->count, r->blocked); | |
2850 | |
2851 if (r->count == 0) { | |
2852 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero"); | |
2853 } | |
2854 | |
2855 r->count--; | |
2856 | |
2857 if (r->count || r->blocked) { | |
2858 return; | |
2859 } | |
2860 | |
2861 ngx_http_free_request(r, rc); | |
2776 ngx_http_close_connection(c); | 2862 ngx_http_close_connection(c); |
2777 } | 2863 } |
2778 | 2864 |
2779 | 2865 |
2780 static void | 2866 static void |
2781 ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error) | 2867 ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) |
2782 { | 2868 { |
2783 ngx_log_t *log; | 2869 ngx_log_t *log; |
2784 struct linger linger; | 2870 struct linger linger; |
2785 ngx_http_cleanup_t *cln; | 2871 ngx_http_cleanup_t *cln; |
2786 ngx_http_log_ctx_t *ctx; | 2872 ngx_http_log_ctx_t *ctx; |
2811 (void) ngx_atomic_fetch_add(ngx_stat_writing, -1); | 2897 (void) ngx_atomic_fetch_add(ngx_stat_writing, -1); |
2812 } | 2898 } |
2813 | 2899 |
2814 #endif | 2900 #endif |
2815 | 2901 |
2816 if (error && r->headers_out.status == 0) { | 2902 if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) { |
2817 r->headers_out.status = error; | 2903 r->headers_out.status = rc; |
2818 } | 2904 } |
2819 | 2905 |
2820 log->action = "logging request"; | 2906 log->action = "logging request"; |
2821 | 2907 |
2822 ngx_http_log_request(r); | 2908 ngx_http_log_request(r); |