Mercurial > hg > nginx
comparison src/http/modules/ngx_http_fastcgi_module.c @ 4122:c7fae0daeb57
Keepalive support in fastcgi.
By default follow the old behaviour, i.e. FASTCGI_KEEP_CONN flag isn't set
in request and application is responsible for closing connection once request
is done. To keep connections alive fastcgi_keep_conn must be activated.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 15 Sep 2011 19:05:23 +0000 |
parents | e0a435f5f504 |
children | 7898857ff34b |
comparison
equal
deleted
inserted
replaced
4121:16c60162c35b | 4122:c7fae0daeb57 |
---|---|
23 ngx_array_t *fastcgi_lengths; | 23 ngx_array_t *fastcgi_lengths; |
24 ngx_array_t *fastcgi_values; | 24 ngx_array_t *fastcgi_values; |
25 | 25 |
26 ngx_hash_t headers_hash; | 26 ngx_hash_t headers_hash; |
27 ngx_uint_t header_params; | 27 ngx_uint_t header_params; |
28 | |
29 ngx_flag_t keep_conn; | |
28 | 30 |
29 #if (NGX_HTTP_CACHE) | 31 #if (NGX_HTTP_CACHE) |
30 ngx_http_complex_value_t cache_key; | 32 ngx_http_complex_value_t cache_key; |
31 #endif | 33 #endif |
32 | 34 |
75 } ngx_http_fastcgi_ctx_t; | 77 } ngx_http_fastcgi_ctx_t; |
76 | 78 |
77 | 79 |
78 #define NGX_HTTP_FASTCGI_RESPONDER 1 | 80 #define NGX_HTTP_FASTCGI_RESPONDER 1 |
79 | 81 |
82 #define NGX_HTTP_FASTCGI_KEEP_CONN 1 | |
83 | |
80 #define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1 | 84 #define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1 |
81 #define NGX_HTTP_FASTCGI_ABORT_REQUEST 2 | 85 #define NGX_HTTP_FASTCGI_ABORT_REQUEST 2 |
82 #define NGX_HTTP_FASTCGI_END_REQUEST 3 | 86 #define NGX_HTTP_FASTCGI_END_REQUEST 3 |
83 #define NGX_HTTP_FASTCGI_PARAMS 4 | 87 #define NGX_HTTP_FASTCGI_PARAMS 4 |
84 #define NGX_HTTP_FASTCGI_STDIN 5 | 88 #define NGX_HTTP_FASTCGI_STDIN 5 |
128 static ngx_int_t ngx_http_fastcgi_create_key(ngx_http_request_t *r); | 132 static ngx_int_t ngx_http_fastcgi_create_key(ngx_http_request_t *r); |
129 #endif | 133 #endif |
130 static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r); | 134 static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r); |
131 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); | 135 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); |
132 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); | 136 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); |
137 static ngx_int_t ngx_http_fastcgi_input_filter_init(void *data); | |
133 static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, | 138 static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, |
134 ngx_buf_t *buf); | 139 ngx_buf_t *buf); |
135 static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r, | 140 static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r, |
136 ngx_http_fastcgi_ctx_t *f); | 141 ngx_http_fastcgi_ctx_t *f); |
137 static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r); | 142 static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r); |
433 { ngx_string("fastcgi_catch_stderr"), | 438 { ngx_string("fastcgi_catch_stderr"), |
434 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 439 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
435 ngx_conf_set_str_array_slot, | 440 ngx_conf_set_str_array_slot, |
436 NGX_HTTP_LOC_CONF_OFFSET, | 441 NGX_HTTP_LOC_CONF_OFFSET, |
437 offsetof(ngx_http_fastcgi_loc_conf_t, catch_stderr), | 442 offsetof(ngx_http_fastcgi_loc_conf_t, catch_stderr), |
443 NULL }, | |
444 | |
445 { ngx_string("fastcgi_keep_conn"), | |
446 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
447 ngx_conf_set_flag_slot, | |
448 NGX_HTTP_LOC_CONF_OFFSET, | |
449 offsetof(ngx_http_fastcgi_loc_conf_t, keep_conn), | |
438 NULL }, | 450 NULL }, |
439 | 451 |
440 ngx_null_command | 452 ngx_null_command |
441 }; | 453 }; |
442 | 454 |
597 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 609 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
598 } | 610 } |
599 | 611 |
600 u->pipe->input_filter = ngx_http_fastcgi_input_filter; | 612 u->pipe->input_filter = ngx_http_fastcgi_input_filter; |
601 u->pipe->input_ctx = r; | 613 u->pipe->input_ctx = r; |
614 | |
615 u->input_filter_init = ngx_http_fastcgi_input_filter_init; | |
602 | 616 |
603 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); | 617 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); |
604 | 618 |
605 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 619 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
606 return rc; | 620 return rc; |
839 return NGX_ERROR; | 853 return NGX_ERROR; |
840 } | 854 } |
841 | 855 |
842 cl->buf = b; | 856 cl->buf = b; |
843 | 857 |
858 ngx_http_fastcgi_request_start.br.flags = | |
859 flcf->keep_conn ? NGX_HTTP_FASTCGI_KEEP_CONN : 0; | |
860 | |
844 ngx_memcpy(b->pos, &ngx_http_fastcgi_request_start, | 861 ngx_memcpy(b->pos, &ngx_http_fastcgi_request_start, |
845 sizeof(ngx_http_fastcgi_request_start_t)); | 862 sizeof(ngx_http_fastcgi_request_start_t)); |
846 | 863 |
847 h = (ngx_http_fastcgi_header_t *) | 864 h = (ngx_http_fastcgi_header_t *) |
848 (b->pos + sizeof(ngx_http_fastcgi_header_t) | 865 (b->pos + sizeof(ngx_http_fastcgi_header_t) |
1572 } | 1589 } |
1573 } | 1590 } |
1574 | 1591 |
1575 | 1592 |
1576 static ngx_int_t | 1593 static ngx_int_t |
1594 ngx_http_fastcgi_input_filter_init(void *data) | |
1595 { | |
1596 ngx_http_request_t *r = data; | |
1597 ngx_http_fastcgi_loc_conf_t *flcf; | |
1598 | |
1599 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); | |
1600 | |
1601 r->upstream->pipe->length = flcf->keep_conn ? | |
1602 (off_t) sizeof(ngx_http_fastcgi_header_t) : -1; | |
1603 | |
1604 return NGX_OK; | |
1605 } | |
1606 | |
1607 | |
1608 static ngx_int_t | |
1577 ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) | 1609 ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) |
1578 { | 1610 { |
1579 u_char *m, *msg; | 1611 u_char *m, *msg; |
1580 ngx_int_t rc; | 1612 ngx_int_t rc; |
1581 ngx_buf_t *b, **prev; | 1613 ngx_buf_t *b, **prev; |
1582 ngx_chain_t *cl; | 1614 ngx_chain_t *cl; |
1583 ngx_http_request_t *r; | 1615 ngx_http_request_t *r; |
1584 ngx_http_fastcgi_ctx_t *f; | 1616 ngx_http_fastcgi_ctx_t *f; |
1617 ngx_http_fastcgi_loc_conf_t *flcf; | |
1585 | 1618 |
1586 if (buf->pos == buf->last) { | 1619 if (buf->pos == buf->last) { |
1587 return NGX_OK; | 1620 return NGX_OK; |
1588 } | 1621 } |
1589 | 1622 |
1590 r = p->input_ctx; | 1623 r = p->input_ctx; |
1591 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); | 1624 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); |
1625 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); | |
1592 | 1626 |
1593 b = NULL; | 1627 b = NULL; |
1594 prev = &buf->shadow; | 1628 prev = &buf->shadow; |
1595 | 1629 |
1596 f->pos = buf->pos; | 1630 f->pos = buf->pos; |
1609 return NGX_ERROR; | 1643 return NGX_ERROR; |
1610 } | 1644 } |
1611 | 1645 |
1612 if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { | 1646 if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { |
1613 f->state = ngx_http_fastcgi_st_version; | 1647 f->state = ngx_http_fastcgi_st_version; |
1614 p->upstream_done = 1; | 1648 |
1649 if (!flcf->keep_conn) { | |
1650 p->upstream_done = 1; | |
1651 } | |
1615 | 1652 |
1616 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, | 1653 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, |
1617 "http fastcgi closed stdout"); | 1654 "http fastcgi closed stdout"); |
1618 | 1655 |
1619 continue; | 1656 continue; |
1620 } | 1657 } |
1621 | 1658 |
1622 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { | 1659 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { |
1623 f->state = ngx_http_fastcgi_st_version; | 1660 f->state = ngx_http_fastcgi_st_version; |
1624 p->upstream_done = 1; | 1661 p->upstream_done = 1; |
1662 | |
1663 if (flcf->keep_conn) { | |
1664 r->upstream->keepalive = 1; | |
1665 } | |
1625 | 1666 |
1626 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, | 1667 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, |
1627 "http fastcgi sent end request"); | 1668 "http fastcgi sent end request"); |
1628 | 1669 |
1629 break; | 1670 break; |
1777 | 1818 |
1778 b->last = f->last; | 1819 b->last = f->last; |
1779 | 1820 |
1780 break; | 1821 break; |
1781 | 1822 |
1823 } | |
1824 | |
1825 if (flcf->keep_conn) { | |
1826 | |
1827 /* set p->length, minimal amount of data we want to see */ | |
1828 | |
1829 if (f->state < ngx_http_fastcgi_st_data) { | |
1830 p->length = 1; | |
1831 | |
1832 } else if (f->state == ngx_http_fastcgi_st_padding) { | |
1833 p->length = f->padding; | |
1834 | |
1835 } else { | |
1836 /* ngx_http_fastcgi_st_data */ | |
1837 | |
1838 p->length = f->length; | |
1839 } | |
1782 } | 1840 } |
1783 | 1841 |
1784 if (b) { | 1842 if (b) { |
1785 b->shadow = buf; | 1843 b->shadow = buf; |
1786 b->last_shadow = 1; | 1844 b->last_shadow = 1; |
2009 /* "fastcgi_cyclic_temp_file" is disabled */ | 2067 /* "fastcgi_cyclic_temp_file" is disabled */ |
2010 conf->upstream.cyclic_temp_file = 0; | 2068 conf->upstream.cyclic_temp_file = 0; |
2011 | 2069 |
2012 conf->catch_stderr = NGX_CONF_UNSET_PTR; | 2070 conf->catch_stderr = NGX_CONF_UNSET_PTR; |
2013 | 2071 |
2072 conf->keep_conn = NGX_CONF_UNSET; | |
2073 | |
2014 ngx_str_set(&conf->upstream.module, "fastcgi"); | 2074 ngx_str_set(&conf->upstream.module, "fastcgi"); |
2015 | 2075 |
2016 return conf; | 2076 return conf; |
2017 } | 2077 } |
2018 | 2078 |
2252 ngx_conf_merge_value(conf->upstream.intercept_errors, | 2312 ngx_conf_merge_value(conf->upstream.intercept_errors, |
2253 prev->upstream.intercept_errors, 0); | 2313 prev->upstream.intercept_errors, 0); |
2254 | 2314 |
2255 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL); | 2315 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL); |
2256 | 2316 |
2317 ngx_conf_merge_value(conf->keep_conn, prev->keep_conn, 0); | |
2318 | |
2257 | 2319 |
2258 ngx_conf_merge_str_value(conf->index, prev->index, ""); | 2320 ngx_conf_merge_str_value(conf->index, prev->index, ""); |
2259 | 2321 |
2260 hash.max_size = 512; | 2322 hash.max_size = 512; |
2261 hash.bucket_size = ngx_align(64, ngx_cacheline_size); | 2323 hash.bucket_size = ngx_align(64, ngx_cacheline_size); |