# HG changeset patch # User Igor Sysoev # Date 1108587600 -10800 # Node ID bc4fc02c96a3e24b4f11762d15b1700bd5216d1b # Parent 9a816ccfbf63a91fd638ff0b049954f9d6773bf4 nginx 0.1.20 *) Feature: the new "script_filename" and "remote_port" parameters of the fastcgi_params directive. *) Bugfix: the FastCGI stderr stream was handled incorrectly. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ + +Changes with nginx 0.1.20 17 Feb 2005 + + *) Feature: the new "script_filename" and "remote_port" parameters + ofthe fastcgi_params directive. + + *) Bugfix: the FastCGI stderr stream was handled incorreсtly. + Changes with nginx 0.1.19 16 Feb 2005 diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,3 +1,12 @@ + +Изменения в nginx 0.1.20 17.02.2005 + + *) Добавление: новые параметры script_filename и remote_port в + директиве fastcgi_params. + + *) Исправление: неправильно обрабатывался поток stderr от + FastCGI-сервера. + Изменения в nginx 0.1.19 16.02.2005 diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.1.19" +#define NGINX_VER "nginx/0.1.20" #define NGINX_VAR "NGINX" #define NGX_NEWPID_EXT ".newbin" diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -112,7 +112,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char continue; } - if (*s == '\n' || *s == '\r') { + if (*s == LF || *s == CR) { continue; } diff --git a/src/http/modules/ngx_http_fastcgi_handler.c b/src/http/modules/ngx_http_fastcgi_handler.c --- a/src/http/modules/ngx_http_fastcgi_handler.c +++ b/src/http/modules/ngx_http_fastcgi_handler.c @@ -68,23 +68,27 @@ typedef struct { size_t length; size_t padding; + ngx_uint_t header; + ngx_http_fastcgi_upstream_t *upstream; } ngx_http_fastcgi_ctx_t; -#define NGX_HTTP_FASTCGI_REMOTE_ADDR 0x0002 -#define NGX_HTTP_FASTCGI_REMOTE_USER 0x0004 -#define NGX_HTTP_FASTCGI_SERVER_NAME 0x0008 -#define NGX_HTTP_FASTCGI_SERVER_ADDR 0x0010 -#define NGX_HTTP_FASTCGI_SERVER_PORT 0x0020 -#define NGX_HTTP_FASTCGI_SCRIPT_NAME 0x0040 -#define NGX_HTTP_FASTCGI_AUTH_TYPE 0x0080 -#define NGX_HTTP_FASTCGI_SERVER_PROTOCOL 0x0100 -#define NGX_HTTP_FASTCGI_SERVER_SOFTWARE 0x0200 -#define NGX_HTTP_FASTCGI_GATEWAY_INTERFACE 0x0400 -#define NGX_HTTP_FASTCGI_REQUEST_URI 0x0800 -#define NGX_HTTP_FASTCGI_REDIRECT_STATUS 0x1000 -#define NGX_HTTP_FASTCGI_DOCUMENT_ROOT 0x2000 +#define NGX_HTTP_FASTCGI_REMOTE_ADDR 0x00000002 +#define NGX_HTTP_FASTCGI_REMOTE_USER 0x00000004 +#define NGX_HTTP_FASTCGI_SERVER_NAME 0x00000008 +#define NGX_HTTP_FASTCGI_SERVER_ADDR 0x00000010 +#define NGX_HTTP_FASTCGI_SERVER_PORT 0x00000020 +#define NGX_HTTP_FASTCGI_SCRIPT_NAME 0x00000040 +#define NGX_HTTP_FASTCGI_AUTH_TYPE 0x00000080 +#define NGX_HTTP_FASTCGI_SERVER_PROTOCOL 0x00000100 +#define NGX_HTTP_FASTCGI_SERVER_SOFTWARE 0x00000200 +#define NGX_HTTP_FASTCGI_GATEWAY_INTERFACE 0x00000400 +#define NGX_HTTP_FASTCGI_REQUEST_URI 0x00000800 +#define NGX_HTTP_FASTCGI_REDIRECT_STATUS 0x00001000 +#define NGX_HTTP_FASTCGI_DOCUMENT_ROOT 0x00002000 +#define NGX_HTTP_FASTCGI_SCRIPT_FILENAME 0x00004000 +#define NGX_HTTP_FASTCGI_REMOTE_PORT 0x00008000 #define NGX_HTTP_FASTCGI_RESPONDER 1 @@ -199,7 +203,10 @@ static ngx_conf_bitmask_t ngx_http_fast { ngx_string("redirect_status"), NGX_HTTP_FASTCGI_REDIRECT_STATUS }, { ngx_string("request_uri"), NGX_HTTP_FASTCGI_REQUEST_URI }, + { ngx_string("document_root"), NGX_HTTP_FASTCGI_DOCUMENT_ROOT }, + { ngx_string("script_filename"), NGX_HTTP_FASTCGI_SCRIPT_FILENAME }, + { ngx_string("remote_port"), NGX_HTTP_FASTCGI_REMOTE_PORT }, { ngx_null_string, 0 } }; @@ -421,16 +428,18 @@ ngx_http_fastcgi_handler(ngx_http_reques static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r) { - u_char ch, *pos, addr_text[INET_ADDRSTRLEN]; - size_t size, len, index, padding, addr_len; + u_char ch, *pos, addr_text[INET_ADDRSTRLEN], + port_text[sizeof("65535") - 1]; + size_t size, len, index, padding, + addr_len, port_len; off_t file_pos; ngx_buf_t *b; socklen_t slen; ngx_chain_t *cl, *body; - ngx_uint_t i, n, next, *vindex; + ngx_uint_t i, n, next, *vindex, port; ngx_list_part_t *part; ngx_table_elt_t *header; - struct sockaddr_in sin; + struct sockaddr_in sin, *sinp; ngx_http_variable_t *var; ngx_http_variable_value_t *value; ngx_http_core_loc_conf_t *clcf; @@ -520,6 +529,12 @@ ngx_http_fastcgi_create_request(ngx_http + sizeof("DOCUMENT_ROOT") - 1 + clcf->root.len; } + if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_FILENAME) { + len += 1 + ((flcf->root.len + r->uri.len + index > 127) ? 4 : 1) + + sizeof("SCRIPT_FILENAME") - 1 + + flcf->root.len + r->uri.len + index; + } + if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_NAME) { len += 1 + ((r->uri.len + index > 127) ? 4 : 1) + sizeof("SCRIPT_NAME") - 1 + r->uri.len + index ; @@ -529,6 +544,25 @@ ngx_http_fastcgi_create_request(ngx_http len += 1 + 1 + sizeof("REMOTE_ADDR") - 1 + r->connection->addr_text.len; } + port_len = 0; + + if (flcf->params & NGX_HTTP_FASTCGI_REMOTE_PORT) { + + /* AF_INET only */ + + if (r->connection->sockaddr->sa_family == AF_INET) { + sinp = (struct sockaddr_in *) r->connection->sockaddr; + + port = ntohs(sinp->sin_port); + + if (port > 0 && port < 65536) { + port_len = ngx_sprintf(port_text, "%ui", port) - port_text; + } + + len += 1 + 1 + sizeof("REMOTE_PORT") - 1 + port_len; + } + } + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_NAME) { len += 1 + 1 + sizeof("SERVER_NAME") - 1 + r->server_name.len; } @@ -831,6 +865,31 @@ ngx_http_fastcgi_create_request(ngx_http } + if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_FILENAME) { + *b->last++ = sizeof("SCRIPT_FILENAME") - 1; + + len = flcf->root.len + r->uri.len + index; + if (len > 127) { + *b->last++ = (u_char) (((len >> 24) & 0x7f) | 0x80); + *b->last++ = (u_char) ((len >> 16) & 0xff); + *b->last++ = (u_char) ((len >> 8) & 0xff); + *b->last++ = (u_char) (len & 0xff); + + } else { + *b->last++ = (u_char) len; + } + + b->last = ngx_cpymem(b->last, "SCRIPT_FILENAME", + sizeof("SCRIPT_FILENAME") - 1); + b->last = ngx_cpymem(b->last, flcf->root.data, flcf->root.len); + b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); + + if (index) { + b->last = ngx_cpymem(b->last, flcf->index.data, index); + } + } + + if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_NAME) { *b->last++ = sizeof("SCRIPT_NAME") - 1; @@ -863,6 +922,14 @@ ngx_http_fastcgi_create_request(ngx_http } + if (port_len) { + *b->last++ = sizeof("REMOTE_PORT") - 1; + *b->last++ = (u_char) port_len; + b->last = ngx_cpymem(b->last, "REMOTE_PORT", sizeof("REMOTE_PORT") - 1); + b->last = ngx_cpymem(b->last, port_text, port_len); + } + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_NAME) { *b->last++ = sizeof("SERVER_NAME") - 1; *b->last++ = (u_char) r->server_name.len; @@ -1151,12 +1218,13 @@ ngx_http_fastcgi_reinit_request(ngx_http } f->state = ngx_http_fastcgi_st_version; + f->header = 0; ngx_memzero(&f->upstream->headers_in, sizeof(ngx_http_fastcgi_headers_in_t)); if (f->upstream->headers_in.headers.part.elts) { - if (ngx_list_init(&f->upstream->headers_in.headers, r->pool, 5, + if (ngx_list_init(&f->upstream->headers_in.headers, r->pool, 8, sizeof(ngx_table_elt_t)) == NGX_ERROR) { return NGX_ERROR; @@ -1170,7 +1238,7 @@ ngx_http_fastcgi_reinit_request(ngx_http static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r) { u_char *start, *last; - ngx_str_t *status_line; + ngx_str_t *status_line, line; ngx_int_t rc, status; ngx_uint_t i; ngx_table_elt_t *h; @@ -1191,7 +1259,7 @@ static ngx_int_t ngx_http_fastcgi_proces return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (ngx_list_init(&f->upstream->headers_in.headers, r->pool, 5, + if (ngx_list_init(&f->upstream->headers_in.headers, r->pool, 8, sizeof(ngx_table_elt_t)) == NGX_ERROR) { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -1220,7 +1288,9 @@ static ngx_int_t ngx_http_fastcgi_proces return NGX_HTTP_UPSTREAM_INVALID_HEADER; } - if (f->type != NGX_HTTP_FASTCGI_STDOUT) { + if (f->type != NGX_HTTP_FASTCGI_STDOUT + && f->type != NGX_HTTP_FASTCGI_STDERR) + { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent unexpected FastCGI record: %d", f->type); @@ -1228,7 +1298,7 @@ static ngx_int_t ngx_http_fastcgi_proces return NGX_HTTP_UPSTREAM_INVALID_HEADER; } - if (f->length == 0) { + if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream closed prematurely FastCGI stdout"); @@ -1258,8 +1328,58 @@ static ngx_int_t ngx_http_fastcgi_proces return NGX_AGAIN; } + /* f->state == ngx_http_fastcgi_st_data */ + if (f->type == NGX_HTTP_FASTCGI_STDERR) { + + if (f->header) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "upstream split a header in FastCGI records"); + + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + if (f->length) { + line.data = u->header_in.pos; + + if (u->header_in.pos + f->length <= u->header_in.last) { + line.len = f->length; + u->header_in.pos += f->length; + f->length = 0; + f->state = ngx_http_fastcgi_st_padding; + + } else { + line.len = u->header_in.last - u->header_in.pos; + f->length -= u->header_in.last - u->header_in.pos; + u->header_in.pos = u->header_in.last; + } + + while (line.data[line.len - 1] == LF + || line.data[line.len - 1] == CR + || line.data[line.len - 1] == '.' + || line.data[line.len - 1] == ' ') + { + line.len--; + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "FastCGI sent in stderr: \"%V\"", &line); + + if (u->header_in.pos == u->header_in.last) { + return NGX_AGAIN; + } + + } else { + f->state = ngx_http_fastcgi_st_version; + } + + continue; + } + + + /* f->type == NGX_HTTP_FASTCGI_STDOUT */ + start = u->header_in.pos; if (u->header_in.pos + f->length < u->header_in.last) { @@ -1276,6 +1396,8 @@ static ngx_int_t ngx_http_fastcgi_proces last = NULL; } + f->header = 1; + for ( ;; ) { rc = ngx_http_parse_header_line(r, &u->header_in); @@ -1572,6 +1694,8 @@ ngx_http_fastcgi_input_filter(ngx_event_ if (f->pos + f->length <= f->last) { line.len = f->length; f->pos += f->length; + f->length = 0; + f->state = ngx_http_fastcgi_st_padding; } else { line.len = f->last - f->pos; @@ -1579,21 +1703,25 @@ ngx_http_fastcgi_input_filter(ngx_event_ f->pos = f->last; } - /* - * TODO: copy split stderr output into buffer, - * clean it up - */ + while (line.data[line.len - 1] == LF + || line.data[line.len - 1] == CR + || line.data[line.len - 1] == '.' + || line.data[line.len - 1] == ' ') + { + line.len--; + } ngx_log_error(NGX_LOG_ERR, p->log, 0, - "FastCGI stderr: %V", &line); + "FastCGI sent in stderr: \"%V\"", &line); if (f->pos == f->last) { break; } + + } else { + f->state = ngx_http_fastcgi_st_version; } - f->state = ngx_http_fastcgi_st_version; - continue; }