Hello, This changeset adds support for FastCGI FCGI_END_REQUEST record type. Now nginx does not process this type of FastCGI record. In case of usage php fastcgi upstream which finishes FastCGI requests before end of script using fastcgi_finish_request() call it leads to "upstream sent unexpected FastCGI record: 3 while reading response header from upstream" error messages and 502 for clients.
Changeset parses FCGI_END_REQUEST FastCGI records and ignores it if keep_conn is enabled and record has type FCGI_REQUEST_COMPLETE. Kind regards, Dmitry Saprykin
# HG changeset patch # User Dmitry Saprykin <[email protected]> # Date 1404466764 -14400 # Fri Jul 04 13:39:24 2014 +0400 # Branch keep_conn_fix # Node ID 1fa8e428eb6c6790203100e741987b925c2ecf25 # Parent 602c0d46a2bb4d86c036c75b3103b916a17380d1 * added FASTCGI_END_REQUEST processing diff -r 602c0d46a2bb -r 1fa8e428eb6c src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Fri Jul 04 13:31:17 2014 +0400 +++ b/src/http/modules/ngx_http_fastcgi_module.c Fri Jul 04 13:39:24 2014 +0400 @@ -53,6 +53,15 @@ ngx_http_fastcgi_st_padding } ngx_http_fastcgi_state_e; +typedef enum { + ngx_http_fastcgi_pst_request_complete = 0, + ngx_http_fastcgi_pst_cant_mpx_conn, + ngx_http_fastcgi_pst_overloaded, + ngx_http_fastcgi_pst_unknown_role +} ngx_http_fastcgi_protocol_status_e; + +#define NGX_HTTP_FASTCGI_END_REQUEST_CONTENT_LEN 8 +#define NGX_HTTP_FASTCGI_END_REQUEST_STATUS_OFFSET 4 typedef struct { u_char *start; @@ -62,6 +71,7 @@ typedef struct { ngx_http_fastcgi_state_e state; + ngx_http_fastcgi_protocol_status_e protocol_status; u_char *pos; u_char *last; ngx_uint_t type; @@ -1236,6 +1246,8 @@ ngx_http_fastcgi_split_part_t *part; ngx_http_upstream_main_conf_t *umcf; + ngx_http_fastcgi_protocol_status_e protocol_status; + f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); @@ -1263,7 +1275,8 @@ } if (f->type != NGX_HTTP_FASTCGI_STDOUT - && f->type != NGX_HTTP_FASTCGI_STDERR) + && f->type != NGX_HTTP_FASTCGI_STDERR + && f->type != NGX_HTTP_FASTCGI_END_REQUEST) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent unexpected FastCGI record: %d", @@ -1305,6 +1318,33 @@ /* f->state == ngx_http_fastcgi_st_data */ + if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + if (f->length != NGX_HTTP_FASTCGI_END_REQUEST_CONTENT_LEN) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent wrong fastcgi_end_request record"); + + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + protocol_status = (u_char)u->buffer.pos[NGX_HTTP_FASTCGI_END_REQUEST_STATUS_OFFSET]; + + flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); + if (!flcf->keep_conn || protocol_status != ngx_http_fastcgi_pst_request_complete) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent unexpected request_end fastcgi record %d", + protocol_status + ); + + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + u->buffer.pos += f->length; + f->length = 0; + f->state = ngx_http_fastcgi_st_padding; + + continue; + } + if (f->type == NGX_HTTP_FASTCGI_STDERR) { if (f->length) {
_______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
