Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_fastcgi_module.c @ 5394:8c827bb1b2b6
FastCGI: non-buffered mode support.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 27 Sep 2013 16:50:40 +0400 |
parents | e65be17e3a3e |
children | 43ccaf8e8728 |
comparison
equal
deleted
inserted
replaced
5393:1a070e89b97a | 5394:8c827bb1b2b6 |
---|---|
136 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); | 136 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); |
137 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); | 137 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); |
138 static ngx_int_t ngx_http_fastcgi_input_filter_init(void *data); | 138 static ngx_int_t ngx_http_fastcgi_input_filter_init(void *data); |
139 static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, | 139 static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, |
140 ngx_buf_t *buf); | 140 ngx_buf_t *buf); |
141 static ngx_int_t ngx_http_fastcgi_non_buffered_filter(void *data, | |
142 ssize_t bytes); | |
141 static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r, | 143 static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r, |
142 ngx_http_fastcgi_ctx_t *f); | 144 ngx_http_fastcgi_ctx_t *f); |
143 static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r); | 145 static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r); |
144 static void ngx_http_fastcgi_finalize_request(ngx_http_request_t *r, | 146 static void ngx_http_fastcgi_finalize_request(ngx_http_request_t *r, |
145 ngx_int_t rc); | 147 ngx_int_t rc); |
229 { ngx_string("fastcgi_store_access"), | 231 { ngx_string("fastcgi_store_access"), |
230 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, | 232 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, |
231 ngx_conf_set_access_slot, | 233 ngx_conf_set_access_slot, |
232 NGX_HTTP_LOC_CONF_OFFSET, | 234 NGX_HTTP_LOC_CONF_OFFSET, |
233 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.store_access), | 235 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.store_access), |
236 NULL }, | |
237 | |
238 { ngx_string("fastcgi_buffering"), | |
239 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
240 ngx_conf_set_flag_slot, | |
241 NGX_HTTP_LOC_CONF_OFFSET, | |
242 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.buffering), | |
234 NULL }, | 243 NULL }, |
235 | 244 |
236 { ngx_string("fastcgi_ignore_client_abort"), | 245 { ngx_string("fastcgi_ignore_client_abort"), |
237 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 246 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
238 ngx_conf_set_flag_slot, | 247 ngx_conf_set_flag_slot, |
577 ngx_int_t rc; | 586 ngx_int_t rc; |
578 ngx_http_upstream_t *u; | 587 ngx_http_upstream_t *u; |
579 ngx_http_fastcgi_ctx_t *f; | 588 ngx_http_fastcgi_ctx_t *f; |
580 ngx_http_fastcgi_loc_conf_t *flcf; | 589 ngx_http_fastcgi_loc_conf_t *flcf; |
581 | 590 |
582 if (r->subrequest_in_memory) { | |
583 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
584 "ngx_http_fastcgi_module does not support " | |
585 "subrequest in memory"); | |
586 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
587 } | |
588 | |
589 if (ngx_http_upstream_create(r) != NGX_OK) { | 591 if (ngx_http_upstream_create(r) != NGX_OK) { |
590 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 592 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
591 } | 593 } |
592 | 594 |
593 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); | 595 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); |
620 u->process_header = ngx_http_fastcgi_process_header; | 622 u->process_header = ngx_http_fastcgi_process_header; |
621 u->abort_request = ngx_http_fastcgi_abort_request; | 623 u->abort_request = ngx_http_fastcgi_abort_request; |
622 u->finalize_request = ngx_http_fastcgi_finalize_request; | 624 u->finalize_request = ngx_http_fastcgi_finalize_request; |
623 r->state = 0; | 625 r->state = 0; |
624 | 626 |
625 u->buffering = 1; | 627 u->buffering = flcf->upstream.buffering; |
626 | 628 |
627 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); | 629 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); |
628 if (u->pipe == NULL) { | 630 if (u->pipe == NULL) { |
629 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 631 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
630 } | 632 } |
631 | 633 |
632 u->pipe->input_filter = ngx_http_fastcgi_input_filter; | 634 u->pipe->input_filter = ngx_http_fastcgi_input_filter; |
633 u->pipe->input_ctx = r; | 635 u->pipe->input_ctx = r; |
634 | 636 |
635 u->input_filter_init = ngx_http_fastcgi_input_filter_init; | 637 u->input_filter_init = ngx_http_fastcgi_input_filter_init; |
638 u->input_filter = ngx_http_fastcgi_non_buffered_filter; | |
639 u->input_filter_ctx = r; | |
636 | 640 |
637 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); | 641 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); |
638 | 642 |
639 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 643 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
640 return rc; | 644 return rc; |
1913 return NGX_OK; | 1917 return NGX_OK; |
1914 } | 1918 } |
1915 | 1919 |
1916 | 1920 |
1917 static ngx_int_t | 1921 static ngx_int_t |
1922 ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes) | |
1923 { | |
1924 u_char *m, *msg; | |
1925 ngx_int_t rc; | |
1926 ngx_buf_t *b, *buf; | |
1927 ngx_chain_t *cl, **ll; | |
1928 ngx_http_request_t *r; | |
1929 ngx_http_upstream_t *u; | |
1930 ngx_http_fastcgi_ctx_t *f; | |
1931 | |
1932 r = data; | |
1933 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); | |
1934 | |
1935 u = r->upstream; | |
1936 buf = &u->buffer; | |
1937 | |
1938 buf->pos = buf->last; | |
1939 buf->last += bytes; | |
1940 | |
1941 for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { | |
1942 ll = &cl->next; | |
1943 } | |
1944 | |
1945 f->pos = buf->pos; | |
1946 f->last = buf->last; | |
1947 | |
1948 for ( ;; ) { | |
1949 if (f->state < ngx_http_fastcgi_st_data) { | |
1950 | |
1951 rc = ngx_http_fastcgi_process_record(r, f); | |
1952 | |
1953 if (rc == NGX_AGAIN) { | |
1954 break; | |
1955 } | |
1956 | |
1957 if (rc == NGX_ERROR) { | |
1958 return NGX_ERROR; | |
1959 } | |
1960 | |
1961 if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { | |
1962 f->state = ngx_http_fastcgi_st_padding; | |
1963 | |
1964 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1965 "http fastcgi closed stdout"); | |
1966 | |
1967 continue; | |
1968 } | |
1969 } | |
1970 | |
1971 if (f->state == ngx_http_fastcgi_st_padding) { | |
1972 | |
1973 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { | |
1974 | |
1975 if (f->pos + f->padding < f->last) { | |
1976 u->length = 0; | |
1977 break; | |
1978 } | |
1979 | |
1980 if (f->pos + f->padding == f->last) { | |
1981 u->length = 0; | |
1982 u->keepalive = 1; | |
1983 break; | |
1984 } | |
1985 | |
1986 f->padding -= f->last - f->pos; | |
1987 | |
1988 break; | |
1989 } | |
1990 | |
1991 if (f->pos + f->padding < f->last) { | |
1992 f->state = ngx_http_fastcgi_st_version; | |
1993 f->pos += f->padding; | |
1994 | |
1995 continue; | |
1996 } | |
1997 | |
1998 if (f->pos + f->padding == f->last) { | |
1999 f->state = ngx_http_fastcgi_st_version; | |
2000 | |
2001 break; | |
2002 } | |
2003 | |
2004 f->padding -= f->last - f->pos; | |
2005 | |
2006 break; | |
2007 } | |
2008 | |
2009 | |
2010 /* f->state == ngx_http_fastcgi_st_data */ | |
2011 | |
2012 if (f->type == NGX_HTTP_FASTCGI_STDERR) { | |
2013 | |
2014 if (f->length) { | |
2015 | |
2016 if (f->pos == f->last) { | |
2017 break; | |
2018 } | |
2019 | |
2020 msg = f->pos; | |
2021 | |
2022 if (f->pos + f->length <= f->last) { | |
2023 f->pos += f->length; | |
2024 f->length = 0; | |
2025 f->state = ngx_http_fastcgi_st_padding; | |
2026 | |
2027 } else { | |
2028 f->length -= f->last - f->pos; | |
2029 f->pos = f->last; | |
2030 } | |
2031 | |
2032 for (m = f->pos - 1; msg < m; m--) { | |
2033 if (*m != LF && *m != CR && *m != '.' && *m != ' ') { | |
2034 break; | |
2035 } | |
2036 } | |
2037 | |
2038 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
2039 "FastCGI sent in stderr: \"%*s\"", | |
2040 m + 1 - msg, msg); | |
2041 | |
2042 } else { | |
2043 f->state = ngx_http_fastcgi_st_padding; | |
2044 } | |
2045 | |
2046 continue; | |
2047 } | |
2048 | |
2049 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { | |
2050 | |
2051 if (f->pos + f->length <= f->last) { | |
2052 f->state = ngx_http_fastcgi_st_padding; | |
2053 f->pos += f->length; | |
2054 | |
2055 continue; | |
2056 } | |
2057 | |
2058 f->length -= f->last - f->pos; | |
2059 | |
2060 break; | |
2061 } | |
2062 | |
2063 | |
2064 /* f->type == NGX_HTTP_FASTCGI_STDOUT */ | |
2065 | |
2066 if (f->pos == f->last) { | |
2067 break; | |
2068 } | |
2069 | |
2070 cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs); | |
2071 if (cl == NULL) { | |
2072 return NGX_ERROR; | |
2073 } | |
2074 | |
2075 *ll = cl; | |
2076 ll = &cl->next; | |
2077 | |
2078 b = cl->buf; | |
2079 | |
2080 b->flush = 1; | |
2081 b->memory = 1; | |
2082 | |
2083 b->pos = f->pos; | |
2084 b->tag = u->output.tag; | |
2085 | |
2086 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2087 "http fastcgi output buf %p", b->pos); | |
2088 | |
2089 if (f->pos + f->length <= f->last) { | |
2090 f->state = ngx_http_fastcgi_st_padding; | |
2091 f->pos += f->length; | |
2092 b->last = f->pos; | |
2093 | |
2094 continue; | |
2095 } | |
2096 | |
2097 f->length -= f->last - f->pos; | |
2098 b->last = f->last; | |
2099 | |
2100 break; | |
2101 } | |
2102 | |
2103 /* provide continuous buffer for subrequests in memory */ | |
2104 | |
2105 if (r->subrequest_in_memory) { | |
2106 | |
2107 cl = u->out_bufs; | |
2108 | |
2109 if (cl) { | |
2110 buf->pos = cl->buf->pos; | |
2111 } | |
2112 | |
2113 buf->last = buf->pos; | |
2114 | |
2115 for (cl = u->out_bufs; cl; cl = cl->next) { | |
2116 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2117 "http fastcgi in memory %p-%p %uz", | |
2118 cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf)); | |
2119 | |
2120 if (buf->last == cl->buf->pos) { | |
2121 buf->last = cl->buf->last; | |
2122 continue; | |
2123 } | |
2124 | |
2125 buf->last = ngx_movemem(buf->last, cl->buf->pos, | |
2126 cl->buf->last - cl->buf->pos); | |
2127 | |
2128 cl->buf->pos = buf->last - (cl->buf->last - cl->buf->pos); | |
2129 cl->buf->last = buf->last; | |
2130 } | |
2131 } | |
2132 | |
2133 return NGX_OK; | |
2134 } | |
2135 | |
2136 | |
2137 static ngx_int_t | |
1918 ngx_http_fastcgi_process_record(ngx_http_request_t *r, | 2138 ngx_http_fastcgi_process_record(ngx_http_request_t *r, |
1919 ngx_http_fastcgi_ctx_t *f) | 2139 ngx_http_fastcgi_ctx_t *f) |
1920 { | 2140 { |
1921 u_char ch, *p; | 2141 u_char ch, *p; |
1922 ngx_http_fastcgi_state_e state; | 2142 ngx_http_fastcgi_state_e state; |
2124 conf->upstream.intercept_errors = NGX_CONF_UNSET; | 2344 conf->upstream.intercept_errors = NGX_CONF_UNSET; |
2125 | 2345 |
2126 /* "fastcgi_cyclic_temp_file" is disabled */ | 2346 /* "fastcgi_cyclic_temp_file" is disabled */ |
2127 conf->upstream.cyclic_temp_file = 0; | 2347 conf->upstream.cyclic_temp_file = 0; |
2128 | 2348 |
2349 conf->upstream.change_buffering = 1; | |
2350 | |
2129 conf->catch_stderr = NGX_CONF_UNSET_PTR; | 2351 conf->catch_stderr = NGX_CONF_UNSET_PTR; |
2130 | 2352 |
2131 conf->keep_conn = NGX_CONF_UNSET; | 2353 conf->keep_conn = NGX_CONF_UNSET; |
2132 | 2354 |
2133 ngx_str_set(&conf->upstream.module, "fastcgi"); | 2355 ngx_str_set(&conf->upstream.module, "fastcgi"); |