comparison src/http/modules/ngx_http_fastcgi_module.c @ 640:eb208e0cf44d NGINX_1_1_4

nginx 1.1.4 *) Feature: the ngx_http_upstream_keepalive module. *) Feature: the "proxy_http_version" directive. *) Feature: the "fastcgi_keep_conn" directive. *) Feature: the "worker_aio_requests" directive. *) Bugfix: if nginx was built --with-file-aio it could not be run on Linux kernel which did not support AIO. *) Bugfix: in Linux AIO error processing. Thanks to Hagai Avrahami. *) Bugfix: reduced memory consumption for long-lived requests. *) Bugfix: the module ngx_http_mp4_module did not support 64-bit MP4 "co64" atom.
author Igor Sysoev <http://sysoev.ru>
date Tue, 20 Sep 2011 00:00:00 +0400
parents 23ef0645ea57
children f200748c0ac8
comparison
equal deleted inserted replaced
639:b516b4e38bc9 640:eb208e0cf44d
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;
1701 if (f->pos == f->last) { 1742 if (f->pos == f->last) {
1702 break; 1743 break;
1703 } 1744 }
1704 1745
1705 if (p->free) { 1746 if (p->free) {
1706 b = p->free->buf; 1747 cl = p->free;
1707 p->free = p->free->next; 1748 b = cl->buf;
1749 p->free = cl->next;
1750 ngx_free_chain(p->pool, cl);
1708 1751
1709 } else { 1752 } else {
1710 b = ngx_alloc_buf(p->pool); 1753 b = ngx_alloc_buf(p->pool);
1711 if (b == NULL) { 1754 if (b == NULL) {
1712 return NGX_ERROR; 1755 return NGX_ERROR;
1777 1820
1778 b->last = f->last; 1821 b->last = f->last;
1779 1822
1780 break; 1823 break;
1781 1824
1825 }
1826
1827 if (flcf->keep_conn) {
1828
1829 /* set p->length, minimal amount of data we want to see */
1830
1831 if (f->state < ngx_http_fastcgi_st_data) {
1832 p->length = 1;
1833
1834 } else if (f->state == ngx_http_fastcgi_st_padding) {
1835 p->length = f->padding;
1836
1837 } else {
1838 /* ngx_http_fastcgi_st_data */
1839
1840 p->length = f->length;
1841 }
1782 } 1842 }
1783 1843
1784 if (b) { 1844 if (b) {
1785 b->shadow = buf; 1845 b->shadow = buf;
1786 b->last_shadow = 1; 1846 b->last_shadow = 1;
2009 /* "fastcgi_cyclic_temp_file" is disabled */ 2069 /* "fastcgi_cyclic_temp_file" is disabled */
2010 conf->upstream.cyclic_temp_file = 0; 2070 conf->upstream.cyclic_temp_file = 0;
2011 2071
2012 conf->catch_stderr = NGX_CONF_UNSET_PTR; 2072 conf->catch_stderr = NGX_CONF_UNSET_PTR;
2013 2073
2074 conf->keep_conn = NGX_CONF_UNSET;
2075
2014 ngx_str_set(&conf->upstream.module, "fastcgi"); 2076 ngx_str_set(&conf->upstream.module, "fastcgi");
2015 2077
2016 return conf; 2078 return conf;
2017 } 2079 }
2018 2080
2252 ngx_conf_merge_value(conf->upstream.intercept_errors, 2314 ngx_conf_merge_value(conf->upstream.intercept_errors,
2253 prev->upstream.intercept_errors, 0); 2315 prev->upstream.intercept_errors, 0);
2254 2316
2255 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL); 2317 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL);
2256 2318
2319 ngx_conf_merge_value(conf->keep_conn, prev->keep_conn, 0);
2320
2257 2321
2258 ngx_conf_merge_str_value(conf->index, prev->index, ""); 2322 ngx_conf_merge_str_value(conf->index, prev->index, "");
2259 2323
2260 hash.max_size = 512; 2324 hash.max_size = 512;
2261 hash.bucket_size = ngx_align(64, ngx_cacheline_size); 2325 hash.bucket_size = ngx_align(64, ngx_cacheline_size);