diff options
| author | Igor Sysoev <igor@sysoev.ru> | 2005-01-18 13:03:58 +0000 |
|---|---|---|
| committer | Igor Sysoev <igor@sysoev.ru> | 2005-01-18 13:03:58 +0000 |
| commit | 02025fd6bdfa997f521c3b26a08aeba366308e84 (patch) | |
| tree | 44db6ebb4e310f97f4550b7d7d69932636764304 /src/http/modules | |
| parent | 543d02a4427e1833f8f9bdb60e3ff5e9fe2eb21b (diff) | |
| download | nginx-release-0.1.14.tar.gz nginx-release-0.1.14.tar.bz2 | |
nginx-0.1.14-RELEASE importrelease-0.1.14
*) Feature: the autoconfiguration directives:
--http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and
--http-fastcgi-temp-path=PATH
*) Change: the directory name for the temporary files with the client
request body is specified by directive client_body_temp_path, by
default it is <prefix>/client_body_temp.
*) Feature: the ngx_http_fastcgi_module and the directives:
fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params,
fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout,
fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers,
fastcgi_busy_buffers_size, fastcgi_temp_path,
fastcgi_max_temp_file_size, fastcgi_temp_file_write_size,
fastcgi_next_upstream, and fastcgi_x_powered_by.
*) Bugfix: the "[alert] zero size buf" error; the bug had appeared in
0.1.3.
*) Change: the URI must be specified after the host name in the
proxy_pass directive.
*) Change: the %3F symbol in the URI was considered as the argument
string start.
*) Feature: the unix domain sockets support in the
ngx_http_proxy_module.
*) Feature: the ssl_engine and ssl_ciphers directives.
Thanks to Sergey Skvortsov for SSL-accelerator.
Diffstat (limited to 'src/http/modules')
| -rw-r--r-- | src/http/modules/ngx_http_access_handler.c | 8 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_fastcgi_handler.c | 1968 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_gzip_filter.c | 116 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_ssl_module.c | 96 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_ssl_module.h | 7 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_userid_filter.c | 159 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 354 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.h | 6 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_header.c | 12 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_upstream.c | 49 |
10 files changed, 2360 insertions, 415 deletions
diff --git a/src/http/modules/ngx_http_access_handler.c b/src/http/modules/ngx_http_access_handler.c index 9e5c43c4d..01796897f 100644 --- a/src/http/modules/ngx_http_access_handler.c +++ b/src/http/modules/ngx_http_access_handler.c @@ -80,7 +80,7 @@ ngx_module_t ngx_http_access_module = { static ngx_int_t ngx_http_access_handler(ngx_http_request_t *r) { ngx_uint_t i; - struct sockaddr_in *addr_in; + struct sockaddr_in *sin; ngx_http_access_rule_t *rule; ngx_http_access_loc_conf_t *alcf; @@ -92,16 +92,16 @@ static ngx_int_t ngx_http_access_handler(ngx_http_request_t *r) /* AF_INET only */ - addr_in = (struct sockaddr_in *) r->connection->sockaddr; + sin = (struct sockaddr_in *) r->connection->sockaddr; rule = alcf->rules->elts; for (i = 0; i < alcf->rules->nelts; i++) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "%08XD %08XD %08XD", - addr_in->sin_addr.s_addr, rule[i].mask, rule[i].addr); + sin->sin_addr.s_addr, rule[i].mask, rule[i].addr); - if ((addr_in->sin_addr.s_addr & rule[i].mask) == rule[i].addr) { + if ((sin->sin_addr.s_addr & rule[i].mask) == rule[i].addr) { if (rule[i].deny) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "access forbidden by rule"); diff --git a/src/http/modules/ngx_http_fastcgi_handler.c b/src/http/modules/ngx_http_fastcgi_handler.c new file mode 100644 index 000000000..f38646a9b --- /dev/null +++ b/src/http/modules/ngx_http_fastcgi_handler.c @@ -0,0 +1,1968 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_http.h> +#include <nginx.h> + + +typedef struct { + ngx_http_upstream_conf_t upstream; + + ngx_peers_t *peers; + + ngx_uint_t params; + + ngx_str_t root; + ngx_str_t index; + + ngx_str_t *location; +} ngx_http_fastcgi_loc_conf_t; + + +typedef struct { + ngx_list_t headers; + + ngx_table_elt_t *status; + + ngx_table_elt_t *content_type; + ngx_table_elt_t *content_length; + ngx_table_elt_t *x_powered_by; + +#if (NGX_HTTP_GZIP) + ngx_table_elt_t *content_encoding; +#endif +} ngx_http_fastcgi_headers_in_t; + + +typedef struct { + ngx_http_fastcgi_headers_in_t headers_in; +} ngx_http_fastcgi_upstream_t; + + +typedef enum { + ngx_http_fastcgi_st_version = 0, + ngx_http_fastcgi_st_type, + ngx_http_fastcgi_st_request_id_hi, + ngx_http_fastcgi_st_request_id_lo, + ngx_http_fastcgi_st_content_length_hi, + ngx_http_fastcgi_st_content_length_lo, + ngx_http_fastcgi_st_padding_length, + ngx_http_fastcgi_st_reserved, + ngx_http_fastcgi_st_data, + ngx_http_fastcgi_st_padding, +} ngx_http_fastcgi_state_e; + + +typedef struct { + ngx_http_fastcgi_state_e state; + u_char *pos; + u_char *last; + ngx_uint_t type; + size_t length; + size_t padding; + + 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_RESPONDER 1 + +#define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1 +#define NGX_HTTP_FASTCGI_ABORT_REQUEST 2 +#define NGX_HTTP_FASTCGI_END_REQUEST 3 +#define NGX_HTTP_FASTCGI_PARAMS 4 +#define NGX_HTTP_FASTCGI_STDIN 5 +#define NGX_HTTP_FASTCGI_STDOUT 6 +#define NGX_HTTP_FASTCGI_STDERR 7 +#define NGX_HTTP_FASTCGI_DATA 8 + + +typedef struct { + u_char version; + u_char type; + u_char request_id_hi; + u_char request_id_lo; + u_char content_length_hi; + u_char content_length_lo; + u_char padding_length; + u_char reserved; +} ngx_http_fastcgi_header_t; + + +typedef struct { + u_char role_hi; + u_char role_lo; + u_char flags; + u_char reserved[5]; +} ngx_http_fastcgi_begin_request_t; + + +static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r); +static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); +static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); +static ngx_int_t ngx_http_fastcgi_send_header(ngx_http_request_t *r); +static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, + ngx_buf_t *buf); +static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r, + ngx_http_fastcgi_ctx_t *f); +static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r); +static void ngx_http_fastcgi_finalize_request(ngx_http_request_t *r, + ngx_int_t rc); + +static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, + void *data); +static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf); +static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child); + + +static ngx_str_t ngx_http_fastcgi_methods[] = { + ngx_string("GET"), + ngx_string("HEAD"), + ngx_string("POST") +}; + + +static ngx_http_header_t ngx_http_fastcgi_headers_in[] = { + { ngx_string("Status"), offsetof(ngx_http_fastcgi_headers_in_t, status) }, + + { ngx_string("Content-Type"), + offsetof(ngx_http_fastcgi_headers_in_t, content_type) }, + + { ngx_string("Content-Length"), + offsetof(ngx_http_fastcgi_headers_in_t, content_length) }, + + { ngx_string("X-Powered-By"), + offsetof(ngx_http_fastcgi_headers_in_t, x_powered_by) }, + +#if (NGX_HTTP_GZIP) + { ngx_string("Content-Encoding"), + offsetof(ngx_http_fastcgi_headers_in_t, content_encoding) }, +#endif + + { ngx_null_string, 0 } +}; + + +static ngx_conf_post_t ngx_http_fastcgi_lowat_post = + { ngx_http_fastcgi_lowat_check } ; + +static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = { + { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, + { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, + { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, + { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, + { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_null_string, 0 } +}; + + +static ngx_conf_bitmask_t ngx_http_fastcgi_params_masks[] = { + { ngx_string("remote_addr"), NGX_HTTP_FASTCGI_REMOTE_ADDR }, + { ngx_string("server_port"), NGX_HTTP_FASTCGI_SERVER_PORT }, + { ngx_string("server_addr"), NGX_HTTP_FASTCGI_SERVER_ADDR }, + { ngx_string("server_name"), NGX_HTTP_FASTCGI_SERVER_NAME }, + { ngx_string("script_name"), NGX_HTTP_FASTCGI_SCRIPT_NAME }, + + { ngx_string("server_protocol"), NGX_HTTP_FASTCGI_SERVER_PROTOCOL }, + { ngx_string("server_software"), NGX_HTTP_FASTCGI_SERVER_SOFTWARE }, + { ngx_string("gateway_interface"), NGX_HTTP_FASTCGI_GATEWAY_INTERFACE }, + + { ngx_string("redirect_status"), NGX_HTTP_FASTCGI_REDIRECT_STATUS }, + { ngx_string("request_uri"), NGX_HTTP_FASTCGI_REQUEST_URI }, + + { ngx_null_string, 0 } +}; + + +static ngx_command_t ngx_http_fastcgi_commands[] = { + + { ngx_string("fastcgi_pass"), + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_fastcgi_pass, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("fastcgi_root"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, root), + NULL }, + + { ngx_string("fastcgi_index"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, index), + NULL }, + + { ngx_string("fastcgi_connect_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.connect_timeout), + NULL }, + + { ngx_string("fastcgi_send_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.send_timeout), + NULL }, + + { ngx_string("fastcgi_send_lowat"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.send_lowat), + &ngx_http_fastcgi_lowat_post }, + + { ngx_string("fastcgi_header_buffer_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.header_buffer_size), + NULL }, + + { ngx_string("fastcgi_x_powered_by"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.x_powered_by), + NULL }, + + { ngx_string("fastcgi_read_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.read_timeout), + NULL }, + + { ngx_string("fastcgi_buffers"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, + ngx_conf_set_bufs_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.bufs), + NULL }, + + { ngx_string("fastcgi_busy_buffers_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.busy_buffers_size), + NULL }, + + { ngx_string("fastcgi_temp_path"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, + ngx_conf_set_path_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.temp_path), + (void *) ngx_garbage_collector_temp_handler }, + + { ngx_string("fastcgi_max_temp_file_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.max_temp_file_size), + NULL }, + + { ngx_string("fastcgi_temp_file_write_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.temp_file_write_size), + NULL }, + + { ngx_string("fastcgi_next_upstream"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, + ngx_conf_set_bitmask_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream), + &ngx_http_fastcgi_next_upstream_masks }, + + { ngx_string("fastcgi_params"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, + ngx_conf_set_bitmask_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, params), + &ngx_http_fastcgi_params_masks }, + + ngx_null_command +}; + + +ngx_http_module_t ngx_http_fastcgi_module_ctx = { + NULL, /* pre conf */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_fastcgi_create_loc_conf, /* create location configuration */ + ngx_http_fastcgi_merge_loc_conf /* merge location configuration */ +}; + + +ngx_module_t ngx_http_fastcgi_module = { + NGX_MODULE, + &ngx_http_fastcgi_module_ctx, /* module context */ + ngx_http_fastcgi_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init module */ + NULL /* init process */ +}; + + +static ngx_int_t ngx_http_fastcgi_handler(ngx_http_request_t *r) +{ + ngx_int_t rc; + ngx_http_upstream_t *u; + ngx_http_fastcgi_loc_conf_t *flcf; + + flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); + + if (!(u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + u->peer.log = r->connection->log; + u->peer.log_error = NGX_ERROR_ERR; + u->peer.peers = flcf->peers; + u->peer.tries = flcf->peers->number; +#if (NGX_THREADS) + u->peer.lock = &r->connection->lock; +#endif + + u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module; + + u->conf = &flcf->upstream; + + u->location = flcf->location; + + u->create_request = ngx_http_fastcgi_create_request; + u->reinit_request = ngx_http_fastcgi_reinit_request; + u->process_header = ngx_http_fastcgi_process_header; + u->send_header = ngx_http_fastcgi_send_header; + u->abort_request = ngx_http_fastcgi_abort_request; + u->finalize_request = ngx_http_fastcgi_finalize_request; + + u->pipe.input_filter = ngx_http_fastcgi_input_filter; + u->pipe.input_ctx = r; + + u->log_ctx = r->connection->log->data; + u->log_handler = ngx_http_upstream_log_error; + + u->schema.len = sizeof("fastcgi://") - 1; + u->schema.data = (u_char *) "fastcgi://"; + u->uri.len = sizeof("/") - 1; + u->uri.data = (u_char *) "/"; + + r->upstream = u; + + rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + return rc; + } + + return NGX_DONE; +} + + +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; + off_t file_pos; + ngx_buf_t *b; + socklen_t slen; + ngx_chain_t *cl, *body; + ngx_uint_t i, n, next; + ngx_list_part_t *part; + ngx_table_elt_t *header; + struct sockaddr_in sin; + ngx_http_fastcgi_header_t *h; + ngx_http_fastcgi_loc_conf_t *flcf; + ngx_http_fastcgi_begin_request_t *br; + + flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); + + if ((flcf->params & NGX_HTTP_FASTCGI_SERVER_ADDR) && r->in_addr == 0) { + + slen = sizeof(struct sockaddr_in); + if (getsockname(r->connection->fd, + (struct sockaddr *) &sin, &slen) == -1) + { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, + ngx_socket_errno, "getsockname() failed"); + return NGX_ERROR; + } + + r->in_addr = sin.sin_addr.s_addr; + } + + addr_len = ngx_inet_ntop(r->connection->listening->family, &r->in_addr, + addr_text, INET_ADDRSTRLEN); + if (addr_len == 0) { + return NGX_ERROR; + } + + + if (r->upstream->method) { + len = 1 + 1 + sizeof("REQUEST_METHOD") - 1 + + ngx_http_fastcgi_methods[r->upstream->method - 1].len; + + } else { + len = 1 + ((r->method_name.len - 1 > 127) ? 4 : 1) + + sizeof("REQUEST_METHOD") - 1 + + r->method_name.len - 1; + } + + + index = (r->uri.data[r->uri.len - 1] == '/') ? flcf->index.len : 0; + + len += 1 + ((flcf->root.len + r->uri.len + index > 127) ? 4 : 1) + + sizeof("PATH_TRANSLATED") - 1 + + flcf->root.len + r->uri.len + index; + + if (r->args.len) { + len += 1 + ((r->args.len > 127) ? 4 : 1) + sizeof("QUERY_STRING") - 1 + + r->args.len; + } + + if (r->headers_in.content_length_n > 0) { + len += 1 + ((r->headers_in.content_length->value.len > 127) ? 4 : 1) + + sizeof("CONTENT_LENGTH") - 1 + + r->headers_in.content_length->value.len; + } + + + if (r->headers_in.content_type) { + len += 1 + ((r->headers_in.content_type->value.len > 127) ? 4 : 1) + + sizeof("CONTENT_TYPE") - 1 + + r->headers_in.content_type->value.len; + } + + + if (flcf->params & NGX_HTTP_FASTCGI_REDIRECT_STATUS) { + len += 1 + 1 + sizeof("REDIRECT_STATUS200") - 1; + } + + if (flcf->params & NGX_HTTP_FASTCGI_REQUEST_URI) { + len += 1 + ((r->uri.len > 127) ? 4 : 1) + + sizeof("REQUEST_URI") - 1 + r->uri.len; + } + + 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 ; + } + + if (flcf->params & NGX_HTTP_FASTCGI_REMOTE_ADDR) { + len += 1 + 1 + sizeof("REMOTE_ADDR") - 1 + r->connection->addr_text.len; + } + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_NAME) { + len += 1 + 1 + sizeof("SERVER_NAME") - 1 + r->server_name.len; + } + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_PORT) { + len += 1 + 1 + sizeof("SERVER_PORT") - 1 + r->port_text->len - 1; + } + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_ADDR) { + len += 1 + 1 + sizeof("SERVER_ADDR") - 1 + addr_len; + } + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_PROTOCOL + && r->http_protocol.len) + { + len += 1 + ((r->http_protocol.len > 127) ? 4 : 1) + + sizeof("SERVER_PROTOCOL") - 1 + r->http_protocol.len; + } + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_SOFTWARE) { + len += 1 + 1 + sizeof("SERVER_SOFTWARE") - 1 + sizeof(NGINX_VER) - 1; + } + + if (flcf->params & NGX_HTTP_FASTCGI_GATEWAY_INTERFACE) { + len += 1 + 1 + sizeof("GATEWAY_INTERFACE") - 1 + sizeof("CGI/1.1") - 1; + } + + + part = &r->headers_in.headers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + len += ((header[i].key.len > 127) ? 4 : 1) + + ((header[i].value.len > 127) ? 4 : 1) + + 5 + header[i].key.len + header[i].value.len; + } + + + if (len > 65535) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "fastcgi: the request record is too big"); + return NGX_ERROR; + } + + + padding = 8 - len % 8; + padding = (padding == 8) ? 0 : padding; + + + size = sizeof(ngx_http_fastcgi_header_t) + + sizeof(ngx_http_fastcgi_begin_request_t) + + + sizeof(ngx_http_fastcgi_header_t) /* NGX_HTTP_FASTCGI_PARAMS */ + + len + padding + + sizeof(ngx_http_fastcgi_header_t) /* NGX_HTTP_FASTCGI_PARAMS */ + + + sizeof(ngx_http_fastcgi_header_t); /* NGX_HTTP_FASTCGI_STDIN */ + + + if (!(b = ngx_create_temp_buf(r->pool, size))) { + return NGX_ERROR; + } + + if (!(cl = ngx_alloc_chain_link(r->pool))) { + return NGX_ERROR; + } + + cl->buf = b; + + h = (ngx_http_fastcgi_header_t *) b->pos; + + h->version = 1; + h->type = NGX_HTTP_FASTCGI_BEGIN_REQUEST; + h->request_id_hi = 0; + h->request_id_lo = 1; + h->content_length_hi = 0; + h->content_length_lo = sizeof(ngx_http_fastcgi_begin_request_t); + h->padding_length = 0; + h->reserved = 0; + + br = (ngx_http_fastcgi_begin_request_t *) + (b->pos + sizeof(ngx_http_fastcgi_header_t)); + br->role_hi = 0; + br->role_lo = NGX_HTTP_FASTCGI_RESPONDER; + br->flags = 0; /* NGX_HTTP_FASTCGI_KEEP_CONN */ + br->reserved[0] = 0; + br->reserved[1] = 0; + br->reserved[2] = 0; + br->reserved[3] = 0; + br->reserved[4] = 0; + + h = (ngx_http_fastcgi_header_t *) + (b->pos + sizeof(ngx_http_fastcgi_header_t) + + sizeof(ngx_http_fastcgi_begin_request_t)); + + h->version = 1; + h->type = NGX_HTTP_FASTCGI_PARAMS; + h->request_id_hi = 0; + h->request_id_lo = 1; + h->content_length_hi = (u_char) ((len >> 8) & 0xff); + h->content_length_lo = (u_char) (len & 0xff); + h->padding_length = (u_char) padding; + h->reserved = 0; + + b->last = b->pos + sizeof(ngx_http_fastcgi_header_t) + + sizeof(ngx_http_fastcgi_begin_request_t) + + sizeof(ngx_http_fastcgi_header_t); + + + *b->last++ = sizeof("PATH_TRANSLATED") - 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, "PATH_TRANSLATED", + sizeof("PATH_TRANSLATED") - 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); + } + + + *b->last++ = sizeof("REQUEST_METHOD") - 1; + + if (r->upstream->method) { + *b->last++ = (u_char) + ngx_http_fastcgi_methods[r->upstream->method - 1].len; + + b->last = ngx_cpymem(b->last, "REQUEST_METHOD", + sizeof("REQUEST_METHOD") - 1); + + b->last = ngx_cpymem(b->last, + ngx_http_fastcgi_methods[r->upstream->method - 1].data, + ngx_http_fastcgi_methods[r->upstream->method - 1].len); + + } else { + len = r->method_name.len - 1; + 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, "REQUEST_METHOD", + sizeof("REQUEST_METHOD") - 1); + b->last = ngx_cpymem(b->last, r->method_name.data, len); + } + + + if (r->args.len) { + *b->last++ = sizeof("QUERY_STRING") - 1; + + len = r->args.len; + 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, "QUERY_STRING", + sizeof("QUERY_STRING") - 1); + b->last = ngx_cpymem(b->last, r->args.data, len); + } + + + if (r->headers_in.content_length_n > 0) { + *b->last++ = sizeof("CONTENT_LENGTH") - 1; + + len = r->headers_in.content_length->value.len; + 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, "CONTENT_LENGTH", + sizeof("CONTENT_LENGTH") - 1); + b->last = ngx_cpymem(b->last, r->headers_in.content_length->value.data, + len); + } + + + if (r->headers_in.content_type) { + *b->last++ = sizeof("CONTENT_TYPE") - 1; + + len = r->headers_in.content_type->value.len; + 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, "CONTENT_TYPE", + sizeof("CONTENT_TYPE") - 1); + b->last = ngx_cpymem(b->last, r->headers_in.content_type->value.data, + len); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_REDIRECT_STATUS) { + *b->last++ = sizeof("REDIRECT_STATUS") - 1; + *b->last++ = sizeof("200") - 1; + b->last = ngx_cpymem(b->last, "REDIRECT_STATUS200", + sizeof("REDIRECT_STATUS200") - 1); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_REQUEST_URI) { + *b->last++ = sizeof("REQUEST_URI") - 1; + + len = r->uri.len; + 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, "REQUEST_URI", sizeof("REQUEST_URI") - 1); + b->last = ngx_cpymem(b->last, r->uri.data, len); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_NAME) { + *b->last++ = sizeof("SCRIPT_NAME") - 1; + + 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_NAME", sizeof("SCRIPT_NAME") - 1); + 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_REMOTE_ADDR) { + *b->last++ = sizeof("REMOTE_ADDR") - 1; + *b->last++ = (u_char) (r->connection->addr_text.len); + b->last = ngx_cpymem(b->last, "REMOTE_ADDR", sizeof("REMOTE_ADDR") - 1); + b->last = ngx_cpymem(b->last, r->connection->addr_text.data, + r->connection->addr_text.len); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_NAME) { + *b->last++ = sizeof("SERVER_NAME") - 1; + *b->last++ = (u_char) r->server_name.len; + b->last = ngx_cpymem(b->last, "SERVER_NAME", sizeof("SERVER_NAME") - 1); + b->last = ngx_cpymem(b->last, r->server_name.data, r->server_name.len); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_PORT) { + *b->last++ = sizeof("SERVER_PORT") - 1; + *b->last++ = (u_char) (r->port_text->len - 1); + b->last = ngx_cpymem(b->last, "SERVER_PORT", sizeof("SERVER_PORT") - 1); + b->last = ngx_cpymem(b->last, r->port_text->data + 1, + r->port_text->len - 1); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_ADDR) { + *b->last++ = sizeof("SERVER_ADDR") - 1; + *b->last++ = (u_char) addr_len; + b->last = ngx_cpymem(b->last, "SERVER_ADDR", sizeof("SERVER_ADDR") - 1); + b->last = ngx_cpymem(b->last, addr_text, addr_len); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_PROTOCOL + && r->http_protocol.len) + { + *b->last++ = sizeof("SERVER_PROTOCOL") - 1; + + len = r->http_protocol.len; + 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, "SERVER_PROTOCOL", + sizeof("SERVER_PROTOCOL") - 1); + b->last = ngx_cpymem(b->last, r->http_protocol.data, len); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_SERVER_SOFTWARE) { + *b->last++ = sizeof("SERVER_SOFTWARE") - 1; + *b->last++ = (u_char) (sizeof(NGINX_VER) - 1); + b->last = ngx_cpymem(b->last, "SERVER_SOFTWARE", + sizeof("SERVER_SOFTWARE") - 1); + b->last = ngx_cpymem(b->last, NGINX_VER, sizeof(NGINX_VER) - 1); + } + + + if (flcf->params & NGX_HTTP_FASTCGI_GATEWAY_INTERFACE) { + *b->last++ = sizeof("GATEWAY_INTERFACE") - 1; + *b->last++ = (u_char) (sizeof("CGI/1.1") - 1); + b->last = ngx_cpymem(b->last, "GATEWAY_INTERFACE", + sizeof("GATEWAY_INTERFACE") - 1); + b->last = ngx_cpymem(b->last, "CGI/1.1", sizeof("CGI/1.1") - 1); + } + + + part = &r->headers_in.headers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + len = 5 + header[i].key.len; + 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; + } + + len = header[i].value.len; + 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, "HTTP_", sizeof("HTTP_") - 1); + + for (n = 0; n < header[i].key.len; n++) { + ch = header[i].key.data[n]; + + if (ch >= 'a' && ch <= 'z') { + ch &= ~0x20; + + } else if (ch == '-') { + ch = '_'; + } + + *b->last++ = ch; + } + + b->last = ngx_cpymem(b->last, header[i].value.data, + header[i].value.len); + } + + + if (padding) { + ngx_memzero(b->last, padding); + b->last += padding; + } + + + h = (ngx_http_fastcgi_header_t *) b->last; + b->last += sizeof(ngx_http_fastcgi_header_t); + + h->version = 1; + h->type = NGX_HTTP_FASTCGI_PARAMS; + h->request_id_hi = 0; + h->request_id_lo = 1; + h->content_length_hi = 0; + h->content_length_lo = 0; + h->padding_length = 0; + h->reserved = 0; + + h = (ngx_http_fastcgi_header_t *) b->last; + b->last += sizeof(ngx_http_fastcgi_header_t); + + body = r->request_body->bufs; + r->request_body->bufs = cl; + +#if (NGX_SUPPRESS_WARN) + file_pos = 0; + pos = NULL; +#endif + + while (body) { + + if (body->buf->in_file) { + file_pos = body->buf->file_pos; + + } else { + pos = body->buf->pos; + } + + next = 0; + + do { + if (!(b = ngx_alloc_buf(r->pool))) { + return NGX_ERROR; + } + + ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); + + if (body->buf->in_file) { + b->file_pos = file_pos; + file_pos += 32 * 1024; + + if (file_pos > body->buf->file_last) { + file_pos = body->buf->file_last; + next = 1; + } + + b->file_last = file_pos; + len = (ngx_uint_t) (file_pos - b->file_pos); + + } else { + b->pos = pos; + pos += 32 * 1024; + + if (pos > body->buf->last) { + pos = body->buf->last; + next = 1; + } + + b->last = pos; + len = (ngx_uint_t) (pos - b->pos); + } + + padding = 8 - len % 8; + padding = (padding == 8) ? 0 : padding; + + h->version = 1; + h->type = NGX_HTTP_FASTCGI_STDIN; + h->request_id_hi = 0; + h->request_id_lo = 1; + h->content_length_hi = (u_char) ((len >> 8) & 0xff); + h->content_length_lo = (u_char) (len & 0xff); + h->padding_length = (u_char) padding; + h->reserved = 0; + + if (!(cl->next = ngx_alloc_chain_link(r->pool))) { + return NGX_ERROR; + } + + cl = cl->next; + cl->buf = b; + + b = ngx_create_temp_buf(r->pool, sizeof(ngx_http_fastcgi_header_t) + + padding); + if (b == NULL) { + return NGX_ERROR; + } + + if (padding) { + ngx_memzero(b->last, padding); + b->last += padding; + } + + h = (ngx_http_fastcgi_header_t *) b->last; + b->last += sizeof(ngx_http_fastcgi_header_t); + + if (!(cl->next = ngx_alloc_chain_link(r->pool))) { + return NGX_ERROR; + } + + cl = cl->next; + cl->buf = b; + + } while (!next); + + body = body->next; + } + + h->version = 1; + h->type = NGX_HTTP_FASTCGI_STDIN; + h->request_id_hi = 0; + h->request_id_lo = 1; + h->content_length_hi = 0; + h->content_length_lo = 0; + h->padding_length = 0; + h->reserved = 0; + + cl->next = NULL; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r) +{ + ngx_http_fastcgi_ctx_t *f; + + f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); + + if (f == NULL) { + return NGX_OK; + } + + f->state = ngx_http_fastcgi_st_version; + + 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, + sizeof(ngx_table_elt_t)) == NGX_ERROR) + { + return NGX_ERROR; + } + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r) +{ + u_char *start, *last; + ngx_str_t *status_line; + ngx_int_t rc, status; + ngx_uint_t i; + ngx_table_elt_t *h; + ngx_http_upstream_t *u; + ngx_http_fastcgi_ctx_t *f; + + f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); + + if (f == NULL) { + if (!(f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ngx_http_set_ctx(r, f, ngx_http_fastcgi_module); + + f->upstream = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_upstream_t)); + if (f->upstream == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (ngx_list_init(&f->upstream->headers_in.headers, r->pool, 5, + sizeof(ngx_table_elt_t)) == NGX_ERROR) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } + + u = r->upstream; + + for ( ;; ) { + + if (f->state < ngx_http_fastcgi_st_data) { + + f->pos = u->header_in.pos; + f->last = u->header_in.last; + + rc = ngx_http_fastcgi_process_record(r, f); + + u->header_in.pos = f->pos; + u->header_in.last = f->last; + + if (rc == NGX_AGAIN) { + return NGX_AGAIN; + } + + if (rc == NGX_ERROR) { + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + if (f->type != NGX_HTTP_FASTCGI_STDOUT) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent unexpected FastCGI record: %d", + f->type); + + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + if (f->length == 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream closed prematurely FastCGI stdout"); + + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + } + + if (f->state == ngx_http_fastcgi_st_padding) { + + if (u->header_in.pos + f->padding < u->header_in.last) { + f->state = ngx_http_fastcgi_st_version; + u->header_in.pos += f->padding; + + continue; + } + + if (u->header_in.pos + f->padding == u->header_in.last) { + f->state = ngx_http_fastcgi_st_version; + u->header_in.pos = u->header_in.last; + + return NGX_AGAIN; + } + + f->padding -= u->header_in.last - u->header_in.pos; + u->header_in.pos = u->header_in.last; + + return NGX_AGAIN; + } + + /* f->state == ngx_http_fastcgi_st_data */ + + start = u->header_in.pos; + + if (u->header_in.pos + f->length < u->header_in.last) { + + /* + * set u->header_in.last to the end of the FastCGI record data + * for ngx_http_parse_header_line() + */ + + last = u->header_in.last; + u->header_in.last = u->header_in.pos + f->length; + + } else { + last = NULL; + } + + for ( ;; ) { + + rc = ngx_http_parse_header_line(r, &u->header_in); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http fastcgi parser: %d", rc); + + if (rc == NGX_AGAIN) { + break; + } + + if (rc == NGX_OK) { + + /* a header line has been parsed successfully */ + + if (!(h = ngx_list_push(&f->upstream->headers_in.headers))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + h->key.len = r->header_name_end - r->header_name_start; + h->value.len = r->header_end - r->header_start; + + h->key.data = ngx_palloc(r->pool, + h->key.len + 1 + h->value.len + 1); + if (h->key.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + h->value.data = h->key.data + h->key.len + 1; + + ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); + ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); + + for (i = 0; ngx_http_fastcgi_headers_in[i].name.len != 0; i++) { + if (ngx_http_fastcgi_headers_in[i].name.len != h->key.len) { + continue; + } + + if (ngx_strcasecmp(ngx_http_fastcgi_headers_in[i].name.data, + h->key.data) == 0) + { + *((ngx_table_elt_t **) + ((char *) &f->upstream->headers_in + + ngx_http_fastcgi_headers_in[i].offset)) = h; + break; + } + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http fastcgi header: \"%V: %V\"", + &h->key, &h->value); + + continue; + } + + if (rc == NGX_HTTP_PARSE_HEADER_DONE) { + + /* a whole header has been parsed successfully */ + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http fastcgi header done"); + + if (f->upstream->headers_in.status) { + status_line = &f->upstream->headers_in.status->value; + + status = ngx_atoi(status_line->data, 3); + + if (status == NGX_ERROR) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + r->headers_out.status = status; + r->headers_out.status_line = *status_line; + + } else { + r->headers_out.status = 200; + r->headers_out.status_line.len = sizeof("200 OK") - 1; + r->headers_out.status_line.data = (u_char *) "200 OK"; + } + + u->state->status = r->headers_out.status; +#if 0 + if (u->cachable) { + u->cachable = ngx_http_upstream_is_cachable(r); + } +#endif + + break; + } + + /* there was error while a header line parsing */ + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + ngx_http_upstream_header_errors[rc + - NGX_HTTP_PARSE_HEADER_ERROR]); + + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + + } + + if (last) { + u->header_in.last = last; + } + + f->length -= u->header_in.pos - start; + + if (rc == NGX_AGAIN) { + if (u->header_in.pos == u->header_in.last) { + return NGX_AGAIN; + } + + 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 == 0) { + if (f->padding) { + f->state = ngx_http_fastcgi_st_padding; + } else { + f->state = ngx_http_fastcgi_st_version; + } + } + + return NGX_OK; + } +} + + +static ngx_int_t ngx_http_fastcgi_send_header(ngx_http_request_t *r) +{ + ngx_uint_t i; + ngx_list_part_t *part; + ngx_table_elt_t *ho, *h; + ngx_http_fastcgi_ctx_t *f; + ngx_http_fastcgi_headers_in_t *headers_in; + + f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); + + headers_in = &f->upstream->headers_in; + part = &headers_in->headers.part; + h = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + h = part->elts; + i = 0; + } + + /* ignore some headers */ + + if (&h[i] == headers_in->status) { + continue; + } + + + if (&h[i] == headers_in->x_powered_by + && !r->upstream->conf->x_powered_by) + { + continue; + } + + + /* "Content-Type" is handled specially */ + + if (&h[i] == headers_in->content_type) { + r->headers_out.content_type = &h[i]; + r->headers_out.content_type->key.len = 0; + continue; + } + + + /* copy some header pointers and set up r->headers_out */ + + if (!(ho = ngx_list_push(&r->headers_out.headers))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + *ho = h[i]; + +#if (NGX_HTTP_GZIP) + if (&h[i] == headers_in->content_encoding) { + r->headers_out.content_encoding = ho; + continue; + } +#endif + + if (&h[i] == headers_in->content_length) { + r->headers_out.content_length = ho; + r->headers_out.content_length_n = ngx_atoi(ho->value.data, + ho->value.len); + continue; + } + } + + return ngx_http_send_header(r); +} + + +static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, + ngx_buf_t *buf) +{ + ngx_int_t rc; + ngx_buf_t *b; + ngx_str_t line; + ngx_chain_t *cl; + ngx_http_request_t *r; + ngx_http_fastcgi_ctx_t *f; + + if (buf->pos == buf->last) { + return NGX_OK; + } + + r = p->input_ctx; + f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); + + b = NULL; + + f->pos = buf->pos; + f->last = buf->last; + + for ( ;; ) { + if (f->state < ngx_http_fastcgi_st_data) { + + rc = ngx_http_fastcgi_process_record(r, f); + + if (rc == NGX_AGAIN) { + break; + } + + if (rc == NGX_ERROR) { + return NGX_ERROR; + } + + if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { + f->state = ngx_http_fastcgi_st_version; + p->upstream_done = 1; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, + "http fastcgi closed stdout"); + + continue; + } + + if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + f->state = ngx_http_fastcgi_st_version; + p->upstream_done = 1; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, + "http fastcgi sent end request"); + + break; + } + } + + + if (f->state == ngx_http_fastcgi_st_padding) { + + if (f->pos + f->padding < f->last) { + f->state = ngx_http_fastcgi_st_version; + f->pos += f->padding; + + continue; + } + + if (f->pos + f->padding == f->last) { + f->state = ngx_http_fastcgi_st_version; + + break; + } + + f->padding -= f->last - f->pos; + + break; + } + + + /* f->state == ngx_http_fastcgi_st_data */ + + if (f->type == NGX_HTTP_FASTCGI_STDERR) { + + if (f->length) { + line.data = f->pos; + + if (f->pos + f->length <= f->last) { + line.len = f->length; + f->pos += f->length; + + } else { + line.len = f->last - f->pos; + f->length -= f->last - f->pos; + f->pos = f->last; + } + + /* + * TODO: copy split stderr output into buffer, + * clean it up + */ + + ngx_log_error(NGX_LOG_ERR, p->log, 0, + "FastCGI stderr: %V", &line); + + if (f->pos == f->last) { + break; + } + } + + f->state = ngx_http_fastcgi_st_version; + + continue; + } + + + /* f->type == NGX_HTTP_FASTCGI_STDOUT */ + + if (p->free) { + b = p->free->buf; + p->free = p->free->next; + + } else { + if (!(b = ngx_alloc_buf(p->pool))) { + return NGX_ERROR; + } + } + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->pos = f->pos; + b->shadow = buf; + b->tag = p->tag; + b->temporary = 1; + b->recycled = 1; + buf->shadow = b; + + if (!(cl = ngx_alloc_chain_link(p->pool))) { + return NGX_ERROR; + } + + cl->buf = b; + cl->next = NULL; + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); + + ngx_chain_add_link(p->in, p->last_in, cl); + + if (f->pos + f->length < f->last) { + + if (f->padding) { + f->state = ngx_http_fastcgi_st_padding; + } else { + f->state = ngx_http_fastcgi_st_version; + } + + f->pos += f->length; + b->last = f->pos; + + continue; + } + + if (f->pos + f->length == f->last) { + + if (f->padding) { + f->state = ngx_http_fastcgi_st_padding; + } else { + f->state = ngx_http_fastcgi_st_version; + } + + b->last = f->last; + + break; + } + + f->length -= f->last - f->pos; + + b->last = f->last; + + break; + + } + + if (b) { + b->last_shadow = 1; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r, + ngx_http_fastcgi_ctx_t *f) +{ + u_char ch, *p; + ngx_http_upstream_t *u; + ngx_http_fastcgi_state_e state; + + u = r->upstream; + + state = f->state; + + for (p = f->pos; p < f->last; p++) { + + ch = *p; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http fastcgi record byte: %02Xd", ch); + + switch (state) { + + case ngx_http_fastcgi_st_version: + if (ch != 1) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent unsupported FastCGI " + "protocol version: %d", ch); + return NGX_ERROR; + } + state = ngx_http_fastcgi_st_type; + break; + + case ngx_http_fastcgi_st_type: + switch (ch) { + case NGX_HTTP_FASTCGI_STDOUT: + case NGX_HTTP_FASTCGI_STDERR: + case NGX_HTTP_FASTCGI_END_REQUEST: + f->type = (ngx_uint_t) ch; + break; + default: + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent invalid FastCGI " + "record type: %d", ch); + return NGX_ERROR; + + } + state = ngx_http_fastcgi_st_request_id_hi; + break; + + /* we support the single request per connection */ + + case ngx_http_fastcgi_st_request_id_hi: + if (ch != 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent unexpected FastCGI " + "request id high byte: %d", ch); + return NGX_ERROR; + } + state = ngx_http_fastcgi_st_request_id_lo; + break; + + case ngx_http_fastcgi_st_request_id_lo: + if (ch != 1) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent unexpected FastCGI " + "request id low byte: %d", ch); + return NGX_ERROR; + } + state = ngx_http_fastcgi_st_content_length_hi; + break; + + case ngx_http_fastcgi_st_content_length_hi: + f->length = ch << 8; + state = ngx_http_fastcgi_st_content_length_lo; + break; + + case ngx_http_fastcgi_st_content_length_lo: + f->length |= (size_t) ch; + state = ngx_http_fastcgi_st_padding_length; + break; + + case ngx_http_fastcgi_st_padding_length: + f->padding = (size_t) ch; + state = ngx_http_fastcgi_st_reserved; + break; + + case ngx_http_fastcgi_st_reserved: + state = ngx_http_fastcgi_st_data; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http fastcgi record length: %z", f->length); + + f->pos = p + 1; + f->state = state; + + return NGX_OK; + + /* suppress warning */ + case ngx_http_fastcgi_st_data: + case ngx_http_fastcgi_st_padding: + break; + } + } + + f->pos = p + 1; + f->state = state; + + return NGX_AGAIN; +} + + +static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r) +{ + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "abort http fastcgi request"); + + return; +} + + +static void ngx_http_fastcgi_finalize_request(ngx_http_request_t *r, + ngx_int_t rc) +{ + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "finalize http fastcgi request"); + + return; +} + + +static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + ngx_http_fastcgi_loc_conf_t *lcf = conf; + + ngx_str_t *value; + ngx_inet_upstream_t inet_upstream; + ngx_http_core_loc_conf_t *clcf; +#if (NGX_HAVE_UNIX_DOMAIN) + ngx_unix_domain_upstream_t unix_upstream; +#endif + + value = cf->args->elts; + + if (ngx_strncasecmp(value[1].data, "unix:", 5) == 0) { + +#if (NGX_HAVE_UNIX_DOMAIN) + + ngx_memzero(&unix_upstream, sizeof(ngx_unix_domain_upstream_t)); + + unix_upstream.name = value[1]; + unix_upstream.url = value[1]; + + + if (!(lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream))) { + return NGX_CONF_ERROR; + } + +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the unix domain sockets are not supported " + "on this platform"); + return NGX_CONF_ERROR; + +#endif + + } else { + ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t)); + + inet_upstream.name = value[1]; + inet_upstream.url = value[1]; + + if (!(lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream))) { + return NGX_CONF_ERROR; + } + } + + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + + lcf->location = &clcf->name; + clcf->handler = ngx_http_fastcgi_handler; + + if (clcf->name.data[clcf->name.len - 1] == '/') { + clcf->auto_redirect = 1; + } + + return NGX_CONF_OK; +} + + +static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, + void *data) +{ +#if (NGX_FREEBSD) + ssize_t *np = data; + + if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"fastcgi_send_lowat\" must be less than %d " + "(sysctl net.inet.tcp.sendspace)", + ngx_freebsd_net_inet_tcp_sendspace); + + return NGX_CONF_ERROR; + } + +#elif !(NGX_HAVE_SO_SNDLOWAT) + ssize_t *np = data; + + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "\"fastcgi_send_lowat\" is not supported, ignored"); + + *np = 0; + +#endif + + return NGX_CONF_OK; +} + + +static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf) +{ + ngx_http_fastcgi_loc_conf_t *conf; + + if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_fastcgi_loc_conf_t)))) { + return NGX_CONF_ERROR; + } + + /* + * set by ngx_pcalloc(): + * + * conf->upstream.bufs.num = 0; + * conf->upstream.path = NULL; + * conf->upstream.next_upstream = 0; + * conf->upstream.temp_path = NULL; + * conf->params = 0; + * conf->root.len = 0; + * conf->root.data = NULL; + * conf->index.len = 0; + * conf->index.data = NULL; + * conf->location = NULL; + */ + + conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; + conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; + conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; + + conf->upstream.header_buffer_size = NGX_CONF_UNSET_SIZE; + conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; + conf->upstream.busy_buffers_size = NGX_CONF_UNSET_SIZE; + + conf->upstream.max_temp_file_size = NGX_CONF_UNSET_SIZE; + conf->upstream.temp_file_write_size = NGX_CONF_UNSET_SIZE; + + conf->upstream.x_powered_by = NGX_CONF_UNSET; + + /* "fastcgi_cyclic_temp_file" is disabled */ + conf->upstream.cyclic_temp_file = 0; + + return conf; +} + + +static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child) +{ + ngx_http_fastcgi_loc_conf_t *prev = parent; + ngx_http_fastcgi_loc_conf_t *conf = child; + + size_t size; + + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, + prev->upstream.connect_timeout, 60000); + ngx_conf_merge_msec_value(conf->upstream.send_timeout, + prev->upstream.send_timeout, 60000); + ngx_conf_merge_size_value(conf->upstream.send_lowat, + prev->upstream.send_lowat, 0); + + ngx_conf_merge_msec_value(conf->upstream.read_timeout, + prev->upstream.read_timeout, 60000); + + ngx_conf_merge_msec_value(conf->upstream.x_powered_by, + prev->upstream.x_powered_by, 1); + + + ngx_conf_merge_size_value(conf->upstream.header_buffer_size, + prev->upstream.header_buffer_size, + (size_t) ngx_pagesize); + + ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, + 8, ngx_pagesize); + + if (conf->upstream.bufs.num < 2) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "there must be at least 2 \"fastcgi_buffers\""); + return NGX_CONF_ERROR; + } + + + size = conf->upstream.header_buffer_size; + if (size < conf->upstream.bufs.size) { + size = conf->upstream.bufs.size; + } + + + ngx_conf_merge_size_value(conf->upstream.busy_buffers_size, + prev->upstream.busy_buffers_size, + NGX_CONF_UNSET_SIZE); + + if (conf->upstream.busy_buffers_size == NGX_CONF_UNSET_SIZE) { + conf->upstream.busy_buffers_size = 2 * size; + + } else if (conf->upstream.busy_buffers_size < size) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"fastcgi_busy_buffers_size\" must be equal or bigger than " + "maximum of the value of \"fastcgi_header_buffer_size\" and " + "one of the \"fastcgi_buffers\""); + + return NGX_CONF_ERROR; + + } else if (conf->upstream.busy_buffers_size + > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"fastcgi_busy_buffers_size\" must be less than " + "the size of all \"fastcgi_buffers\" minus one buffer"); + + return NGX_CONF_ERROR; + } + + + ngx_conf_merge_size_value(conf->upstream.temp_file_write_size, + prev->upstream.temp_file_write_size, + NGX_CONF_UNSET_SIZE); + + if (conf->upstream.temp_file_write_size == NGX_CONF_UNSET_SIZE) { + conf->upstream.temp_file_write_size = 2 * size; + + } else if (conf->upstream.temp_file_write_size < size) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"fastcgi_temp_file_write_size\" must be equal or bigger than " + "maximum of the value of \"fastcgi_header_buffer_size\" and " + "one of the \"fastcgi_buffers\""); + + return NGX_CONF_ERROR; + } + + + ngx_conf_merge_size_value(conf->upstream.max_temp_file_size, + prev->upstream.max_temp_file_size, + NGX_CONF_UNSET_SIZE); + + if (conf->upstream.max_temp_file_size == NGX_CONF_UNSET_SIZE) { + + conf->upstream.max_temp_file_size = 1024 * 1024 * 1024; + + } else if (conf->upstream.max_temp_file_size != 0 + && conf->upstream.max_temp_file_size < size) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"fastcgi_max_temp_file_size\" must be equal to zero to disable " + "the temporary files usage or must be equal or bigger than " + "maximum of the value of \"fastcgi_header_buffer_size\" and " + "one of the \"fastcgi_buffers\""); + + return NGX_CONF_ERROR; + } + + + ngx_conf_merge_bitmask_value(conf->upstream.next_upstream, + prev->upstream.next_upstream, + (NGX_CONF_BITMASK_SET + |NGX_HTTP_UPSTREAM_FT_ERROR + |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); + + ngx_conf_merge_path_value(conf->upstream.temp_path, + prev->upstream.temp_path, + NGX_HTTP_FASTCGI_TEMP_PATH, 1, 2, 0, + ngx_garbage_collector_temp_handler, cf); + + + ngx_conf_merge_bitmask_value(conf->params, prev->params, + (NGX_CONF_BITMASK_SET + |NGX_HTTP_FASTCGI_REMOTE_ADDR + |NGX_HTTP_FASTCGI_REMOTE_USER + |NGX_HTTP_FASTCGI_SERVER_NAME + |NGX_HTTP_FASTCGI_SERVER_PORT + |NGX_HTTP_FASTCGI_SCRIPT_NAME + |NGX_HTTP_FASTCGI_AUTH_TYPE + |NGX_HTTP_FASTCGI_REQUEST_URI + |NGX_HTTP_FASTCGI_REDIRECT_STATUS)); + + ngx_conf_merge_str_value(conf->root, prev->root, ""); + + if (conf->root.len && conf->root.data[conf->root.len - 1] == '/') { + conf->root.len--; + } + + ngx_conf_merge_str_value(conf->index, prev->index, ""); + + return NGX_CONF_OK; +} diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c index b093d582f..0cd1d91df 100644 --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -80,12 +80,13 @@ static ngx_int_t ngx_http_gzip_proxied(ngx_http_request_t *r, static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items, u_int size); static void ngx_http_gzip_filter_free(void *opaque, void *address); -static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx); +static void ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx); static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, - uintptr_t data); + ngx_http_log_op_t *op); + +static ngx_int_t ngx_http_gzip_add_log_formats(ngx_conf_t *cf); -static ngx_int_t ngx_http_gzip_pre_conf(ngx_conf_t *cf); static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle); static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, @@ -205,7 +206,7 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = { static ngx_http_module_t ngx_http_gzip_filter_module_ctx = { - ngx_http_gzip_pre_conf, /* pre conf */ + ngx_http_gzip_add_log_formats, /* pre conf */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -229,22 +230,23 @@ ngx_module_t ngx_http_gzip_filter_module = { static ngx_http_log_op_name_t ngx_http_gzip_log_fmt_ops[] = { - { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3, ngx_http_gzip_log_ratio }, - { ngx_null_string, 0, NULL } + { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3, + NULL, NULL, ngx_http_gzip_log_ratio }, + { ngx_null_string, 0, NULL, NULL, NULL } }; static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; -#if (NGX_HAVE_LITTLE_ENDIAN) +#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) struct gztrailer { uint32_t crc32; uint32_t zlen; }; -#else /* NGX_HAVE_BIG_ENDIAN */ +#else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */ struct gztrailer { u_char crc32[4]; @@ -497,11 +499,13 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, if (rc != Z_OK) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "deflateInit2() failed: %d", rc); - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } if (!(b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } b->memory = 1; @@ -509,7 +513,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, b->last = b->pos + 10; if (!(cl = ngx_alloc_chain_link(r->pool))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } cl->buf = b; cl->next = NULL; @@ -522,7 +527,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, */ if (ngx_http_next_body_filter(r, cl) == NGX_ERROR) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } ctx->last_out = &ctx->out; @@ -533,7 +539,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, if (in) { if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } } @@ -607,7 +614,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, ctx->out_buf = ngx_create_temp_buf(r->pool, conf->bufs.size); if (ctx->out_buf == NULL) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } ctx->out_buf->tag = (ngx_buf_tag_t) @@ -634,7 +642,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, if (rc != Z_OK && rc != Z_STREAM_END) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "deflate() failed: %d, %d", ctx->flush, rc); - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -663,7 +672,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, /* zlib wants to output some more gzipped data */ if (!(cl = ngx_alloc_chain_link(r->pool))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; @@ -683,7 +693,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, ctx->flush = Z_NO_FLUSH; if (!(cl = ngx_alloc_chain_link(r->pool))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; @@ -703,13 +714,15 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, if (rc != Z_OK) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "deflateEnd() failed: %d", rc); - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } ngx_pfree(r->pool, ctx->preallocated); if (!(cl = ngx_alloc_chain_link(r->pool))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; @@ -723,13 +736,15 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, } else { if (!(b = ngx_create_temp_buf(r->pool, 8))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } b->last_buf = 1; if (!(cl = ngx_alloc_chain_link(r->pool))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } cl->buf = b; cl->next = NULL; @@ -739,19 +754,21 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, b->last += 8; } -#if (NGX_HAVE_LITTLE_ENDIAN) +#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) + trailer->crc32 = ctx->crc32; trailer->zlen = ctx->zin; + #else - trailer->crc32[0] = ctx->crc32 & 0xff; - trailer->crc32[1] = (ctx->crc32 >> 8) & 0xff; - trailer->crc32[2] = (ctx->crc32 >> 16) & 0xff; - trailer->crc32[3] = (ctx->crc32 >> 24) & 0xff; - - trailer->zlen[0] = ctx->zin & 0xff; - trailer->zlen[1] = (ctx->zin >> 8) & 0xff; - trailer->zlen[2] = (ctx->zin >> 16) & 0xff; - trailer->zlen[3] = (ctx->zin >> 24) & 0xff; + trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff); + trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff); + trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff); + trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff); + + trailer->zlen[0] = (u_char) (ctx->zin & 0xff); + trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff); + trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff); + trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff); #endif ctx->zstream.avail_in = 0; @@ -764,7 +781,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, if (conf->no_buffer && ctx->in == NULL) { if (!(cl = ngx_alloc_chain_link(r->pool))) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; @@ -791,7 +809,8 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, */ if (last == NGX_ERROR) { - return ngx_http_gzip_error(ctx); + ngx_http_gzip_error(ctx); + return NGX_ERROR; } ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out, @@ -858,7 +877,7 @@ static void ngx_http_gzip_filter_free(void *opaque, void *address) static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, - uintptr_t data) + ngx_http_log_op_t *op) { ngx_uint_t zint, zfrac; ngx_http_gzip_ctx_t *ctx; @@ -889,7 +908,7 @@ static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, } -static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) +static void ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) { deflateEnd(&ctx->zstream); @@ -902,26 +921,24 @@ static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) ctx->done = 1; - return NGX_ERROR; + return; } -static ngx_int_t ngx_http_gzip_pre_conf(ngx_conf_t *cf) +static ngx_int_t ngx_http_gzip_add_log_formats(ngx_conf_t *cf) { ngx_http_log_op_name_t *op; for (op = ngx_http_gzip_log_fmt_ops; op->name.len; op++) { /* void */ } - op->op = NULL; - - op = ngx_http_log_fmt_ops; + op->run = NULL; - for (op = ngx_http_log_fmt_ops; op->op; op++) { + for (op = ngx_http_log_fmt_ops; op->run; op++) { if (op->name.len == 0) { - op = (ngx_http_log_op_name_t *) op->op; + op = (ngx_http_log_op_name_t *) op->run; } } - op->op = (ngx_http_log_op_pt) ngx_http_gzip_log_fmt_ops; + op->run = (ngx_http_log_op_run_pt) ngx_http_gzip_log_fmt_ops; return NGX_OK; } @@ -948,14 +965,11 @@ static void *ngx_http_gzip_create_conf(ngx_conf_t *cf) } /* - - set by ngx_pcalloc(): - - conf->bufs.num = 0; - conf->proxied = 0; - - conf->types = NULL; - + * set by ngx_pcalloc(): + * + * conf->bufs.num = 0; + * conf->proxied = 0; + * conf->types = NULL; */ conf->enable = NGX_CONF_UNSET; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 35ab2c46c..9cb6e171d 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -8,11 +8,15 @@ #include <ngx_core.h> #include <ngx_http.h> +#include <openssl/engine.h> + #define NGX_DEFLAUT_CERTIFICATE "cert.pem" #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem" +static void *ngx_http_ssl_create_main_conf(ngx_conf_t *cf); +static char *ngx_http_ssl_init_main_conf(ngx_conf_t *cf, void *conf); static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child); @@ -20,6 +24,13 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, static ngx_command_t ngx_http_ssl_commands[] = { + { ngx_string("ssl_engine"), + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_ssl_main_conf_t, engine), + NULL }, + { ngx_string("ssl"), NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -41,6 +52,13 @@ static ngx_command_t ngx_http_ssl_commands[] = { offsetof(ngx_http_ssl_srv_conf_t, certificate_key), NULL }, + { ngx_string("ssl_ciphers"), + NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, ciphers), + NULL }, + ngx_null_command }; @@ -48,8 +66,8 @@ static ngx_command_t ngx_http_ssl_commands[] = { static ngx_http_module_t ngx_http_ssl_module_ctx = { NULL, /* pre conf */ - NULL, /* create main configuration */ - NULL, /* init main configuration */ + ngx_http_ssl_create_main_conf, /* create main configuration */ + ngx_http_ssl_init_main_conf, /* init main configuration */ ngx_http_ssl_create_srv_conf, /* create server configuration */ ngx_http_ssl_merge_srv_conf, /* merge server configuration */ @@ -69,6 +87,56 @@ ngx_module_t ngx_http_ssl_module = { }; +static void *ngx_http_ssl_create_main_conf(ngx_conf_t *cf) +{ + ngx_http_ssl_main_conf_t *mcf; + + if (!(mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_main_conf_t)))) { + return NGX_CONF_ERROR; + } + + /* + * set by ngx_pcalloc(): + * + * mcf->engine.len = 0; + * mcf->engine.data = NULL; + */ + + return mcf; +} + + +static char *ngx_http_ssl_init_main_conf(ngx_conf_t *cf, void *conf) +{ + ngx_http_ssl_main_conf_t *mcf = conf; + + ENGINE *engine; + + if (mcf->engine.len == 0) { + return NGX_CONF_OK; + } + + engine = ENGINE_by_id((const char *) mcf->engine.data); + + if (engine == NULL) { + ngx_ssl_error(NGX_LOG_WARN, cf->log, 0, + "ENGINE_by_id(\"%V\") failed", &mcf->engine); + return NGX_CONF_ERROR; + } + + if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) { + ngx_ssl_error(NGX_LOG_WARN, cf->log, 0, + "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed", + &mcf->engine); + return NGX_CONF_ERROR; + } + + ENGINE_free(engine); + + return NGX_CONF_OK; +} + + static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) { ngx_http_ssl_srv_conf_t *scf; @@ -77,6 +145,17 @@ static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) return NGX_CONF_ERROR; } + /* + * set by ngx_pcalloc(): + * + * scf->certificate.len = 0; + * scf->certificate.data = NULL; + * scf->certificate_key.len = 0; + * scf->certificate_key.data = NULL; + * scf->ciphers.len = 0; + * scf->ciphers.data = NULL; + */ + scf->enable = NGX_CONF_UNSET; return scf; @@ -101,6 +180,9 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, NGX_DEFLAUT_CERTIFICATE_KEY); + ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, ""); + + /* TODO: configure methods */ conf->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); @@ -110,6 +192,16 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } + if (conf->ciphers.len) { + if (SSL_CTX_set_cipher_list(conf->ssl_ctx, + (const char *) conf->ciphers.data) == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + &conf->ciphers); + } + } + if (SSL_CTX_use_certificate_file(conf->ssl_ctx, (char *) conf->certificate.data, SSL_FILETYPE_PEM) == 0) { diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h index eaca2a6c5..87166877f 100644 --- a/src/http/modules/ngx_http_ssl_module.h +++ b/src/http/modules/ngx_http_ssl_module.h @@ -14,10 +14,17 @@ typedef struct { + ngx_str_t engine; +} ngx_http_ssl_main_conf_t; + + +typedef struct { ngx_flag_t enable; ngx_str_t certificate; ngx_str_t certificate_key; + ngx_str_t ciphers; + ngx_ssl_ctx_t *ssl_ctx; } ngx_http_ssl_srv_conf_t; diff --git a/src/http/modules/ngx_http_userid_filter.c b/src/http/modules/ngx_http_userid_filter.c index 2385ceed2..aee161b53 100644 --- a/src/http/modules/ngx_http_userid_filter.c +++ b/src/http/modules/ngx_http_userid_filter.c @@ -44,13 +44,17 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf); +static size_t ngx_http_userid_log_uid_got_getlen(ngx_http_request_t *r, + uintptr_t data); static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, - uintptr_t data); + ngx_http_log_op_t *op); +static size_t ngx_http_userid_log_uid_set_getlen(ngx_http_request_t *r, + uintptr_t data); static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, - uintptr_t data); + ngx_http_log_op_t *op); +static ngx_int_t ngx_http_userid_add_log_formats(ngx_conf_t *cf); static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle); -static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf); static void *ngx_http_userid_create_conf(ngx_conf_t *cf); static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child); @@ -142,7 +146,7 @@ static ngx_command_t ngx_http_userid_commands[] = { ngx_http_module_t ngx_http_userid_filter_module_ctx = { - ngx_http_userid_pre_conf, /* pre conf */ + ngx_http_userid_add_log_formats, /* pre conf */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -166,9 +170,13 @@ ngx_module_t ngx_http_userid_filter_module = { static ngx_http_log_op_name_t ngx_http_userid_log_fmt_ops[] = { - { ngx_string("uid_got"), 0, ngx_http_userid_log_uid_got }, - { ngx_string("uid_set"), 0, ngx_http_userid_log_uid_set }, - { ngx_null_string, 0, NULL } + { ngx_string("uid_got"), 0, NULL, + ngx_http_userid_log_uid_got_getlen, + ngx_http_userid_log_uid_got }, + { ngx_string("uid_set"), 0, NULL, + ngx_http_userid_log_uid_set_getlen, + ngx_http_userid_log_uid_set }, + { ngx_null_string, 0, NULL, NULL, NULL } }; @@ -298,7 +306,7 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, u_char *cookie, *p; size_t len; socklen_t slen; - struct sockaddr_in addr_in; + struct sockaddr_in sin; ngx_str_t src, dst; ngx_table_elt_t *set_cookie, *p3p; @@ -321,14 +329,13 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, if (r->in_addr == 0) { slen = sizeof(struct sockaddr_in); if (getsockname(r->connection->fd, - (struct sockaddr *) &addr_in, &slen) == -1) + (struct sockaddr *) &sin, &slen) == -1) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, - ngx_socket_errno, - "getsockname() failed"); + ngx_socket_errno, "getsockname() failed"); } - r->in_addr = addr_in.sin_addr.s_addr; + r->in_addr = sin.sin_addr.s_addr; } ctx->uid_set[0] = htonl(r->in_addr); @@ -352,7 +359,7 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, len += sizeof(expires) - 1 + 2; } - if (conf->domain.len > 1) { + if (conf->domain.len) { len += conf->domain.len; } @@ -379,7 +386,7 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, p = ngx_http_cookie_time(p, ngx_time() + conf->expires); } - if (conf->domain.len > 1) { + if (conf->domain.len) { p = ngx_cpymem(p, conf->domain.data, conf->domain.len); } @@ -397,7 +404,7 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "uid cookie: \"%V\"", &set_cookie->value); - if (conf->p3p.len == 1) { + if (conf->p3p.len == 0) { return NGX_OK; } @@ -413,8 +420,8 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, } -static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, - uintptr_t data) +static size_t ngx_http_userid_log_uid_got_getlen(ngx_http_request_t *r, + uintptr_t data) { ngx_http_userid_ctx_t *ctx; ngx_http_userid_conf_t *conf; @@ -422,20 +429,30 @@ static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); if (ctx == NULL || ctx->uid_got[3] == 0) { - if (buf == NULL) { - return (u_char *) 1; - } + return 1; + } + + conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); + + return conf->name.len + 1 + 32; +} + + +static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, + ngx_http_log_op_t *op) +{ + ngx_http_userid_ctx_t *ctx; + ngx_http_userid_conf_t *conf; + + ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); + if (ctx == NULL || ctx->uid_got[3] == 0) { *buf = '-'; return buf + 1; } conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); - if (buf == NULL) { - return (u_char *) (conf->name.len + 1 + 32); - } - buf = ngx_cpymem(buf, conf->name.data, conf->name.len); *buf++ = '='; @@ -446,8 +463,8 @@ static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, } -static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, - uintptr_t data) +static size_t ngx_http_userid_log_uid_set_getlen(ngx_http_request_t *r, + uintptr_t data) { ngx_http_userid_ctx_t *ctx; ngx_http_userid_conf_t *conf; @@ -455,20 +472,30 @@ static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); if (ctx == NULL || ctx->uid_set[3] == 0) { - if (buf == NULL) { - return (u_char *) 1; - } + return 1; + } + + conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); + + return conf->name.len + 1 + 32; +} + +static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, + ngx_http_log_op_t *op) +{ + ngx_http_userid_ctx_t *ctx; + ngx_http_userid_conf_t *conf; + + ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); + + if (ctx == NULL || ctx->uid_set[3] == 0) { *buf = '-'; return buf + 1; } conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); - if (buf == NULL) { - return (u_char *) (conf->name.len + 1 + 32); - } - buf = ngx_cpymem(buf, conf->name.data, conf->name.len); *buf++ = '='; @@ -479,31 +506,29 @@ static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, } -static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle) -{ - ngx_http_next_header_filter = ngx_http_top_header_filter; - ngx_http_top_header_filter = ngx_http_userid_filter; - - return NGX_OK; -} - - -static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf) +static ngx_int_t ngx_http_userid_add_log_formats(ngx_conf_t *cf) { ngx_http_log_op_name_t *op; for (op = ngx_http_userid_log_fmt_ops; op->name.len; op++) { /* void */ } - op->op = NULL; + op->run = NULL; - op = ngx_http_log_fmt_ops; - - for (op = ngx_http_log_fmt_ops; op->op; op++) { + for (op = ngx_http_log_fmt_ops; op->run; op++) { if (op->name.len == 0) { - op = (ngx_http_log_op_name_t *) op->op; + op = (ngx_http_log_op_name_t *) op->run; } } - op->op = (ngx_http_log_op_pt) ngx_http_userid_log_fmt_ops; + op->run = (ngx_http_log_op_run_pt) ngx_http_userid_log_fmt_ops; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle) +{ + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_userid_filter; return NGX_OK; } @@ -517,18 +542,18 @@ static void *ngx_http_userid_create_conf(ngx_conf_t *cf) return NGX_CONF_ERROR; } - /* set by ngx_pcalloc(): - - conf->name.len = 0; - conf->name.date = NULL; - conf->domain.len = 0; - conf->domain.date = NULL; - conf->path.len = 0; - conf->path.date = NULL; - conf->p3p.len = 0; - conf->p3p.date = NULL; - - */ + /* + * set by ngx_pcalloc(): + * + * conf->name.len = 0; + * conf->name.date = NULL; + * conf->domain.len = 0; + * conf->domain.date = NULL; + * conf->path.len = 0; + * conf->path.date = NULL; + * conf->p3p.len = 0; + * conf->p3p.date = NULL; + */ conf->enable = NGX_CONF_UNSET; conf->service = NGX_CONF_UNSET; @@ -547,9 +572,9 @@ static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, ngx_conf_merge_value(conf->enable, prev->enable, NGX_HTTP_USERID_OFF); ngx_conf_merge_str_value(conf->name, prev->name, "uid"); - ngx_conf_merge_str_value(conf->domain, prev->domain, "."); + ngx_conf_merge_str_value(conf->domain, prev->domain, ""); ngx_conf_merge_str_value(conf->path, prev->path, "; path=/"); - ngx_conf_merge_str_value(conf->p3p, prev->p3p, "."); + ngx_conf_merge_str_value(conf->p3p, prev->p3p, ""); ngx_conf_merge_value(conf->service, prev->service, NGX_CONF_UNSET); ngx_conf_merge_sec_value(conf->expires, prev->expires, 0); @@ -565,8 +590,8 @@ char *ngx_http_userid_domain(ngx_conf_t *cf, void *post, void *data) u_char *p, *new; if (domain->len == 4 && ngx_strcmp(domain->data, "none") == 0) { - domain->len = 1; - domain->data = (u_char *) "."; + domain->len = 0; + domain->data = (u_char *) ""; return NGX_CONF_OK; } @@ -645,8 +670,8 @@ char *ngx_http_userid_p3p(ngx_conf_t *cf, void *post, void *data) ngx_str_t *p3p = data; if (p3p->len == 4 && ngx_strcmp(p3p->data, "none") == 0) { - p3p->len = 1; - p3p->data = (u_char *) "."; + p3p->len = 0; + p3p->data = (u_char *) ""; } return NGX_CONF_OK; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 62e348e0a..7a1c03ce3 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -13,14 +13,20 @@ static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p); +static size_t ngx_http_proxy_log_proxy_state_getlen(ngx_http_request_t *r, + uintptr_t data); static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, - u_char *buf, uintptr_t data); + u_char *buf, + ngx_http_log_op_t *op); + +#if 0 static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r, u_char *buf, uintptr_t data); static u_char *ngx_http_proxy_log_reason(ngx_http_request_t *r, u_char *buf, uintptr_t data); +#endif -static ngx_int_t ngx_http_proxy_pre_conf(ngx_conf_t *cf); +static ngx_int_t ngx_http_proxy_add_log_formats(ngx_conf_t *cf); static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -231,7 +237,6 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, default_expires), NULL }, - { ngx_string("proxy_next_upstream"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, ngx_conf_set_bitmask_slot, @@ -251,7 +256,7 @@ static ngx_command_t ngx_http_proxy_commands[] = { ngx_http_module_t ngx_http_proxy_module_ctx = { - ngx_http_proxy_pre_conf, /* pre conf */ + ngx_http_proxy_add_log_formats, /* pre conf */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -270,16 +275,22 @@ ngx_module_t ngx_http_proxy_module = { ngx_http_proxy_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init module */ - NULL /* init child */ + NULL /* init process */ }; static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = { - { ngx_string("proxy"), 0, ngx_http_proxy_log_proxy_state }, + { ngx_string("proxy"), 0, NULL, + ngx_http_proxy_log_proxy_state_getlen, + ngx_http_proxy_log_proxy_state }, + +#if 0 { ngx_string("proxy_cache_state"), 0, ngx_http_proxy_log_cache_state }, { ngx_string("proxy_reason"), 0, ngx_http_proxy_log_reason }, - { ngx_null_string, 0, NULL } +#endif + + { ngx_null_string, 0, NULL, NULL, NULL } }; @@ -301,8 +312,12 @@ ngx_http_header_t ngx_http_proxy_headers_in[] = { offsetof(ngx_http_proxy_headers_in_t, content_type) }, { ngx_string("Content-Length"), offsetof(ngx_http_proxy_headers_in_t, content_length) }, + +#if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), offsetof(ngx_http_proxy_headers_in_t, content_encoding) }, +#endif + { ngx_string("Last-Modified"), offsetof(ngx_http_proxy_headers_in_t, last_modified) }, { ngx_string("Location"), @@ -779,11 +794,12 @@ u_char *ngx_http_proxy_log_error(void *data, u_char *buf, size_t len) peer = &ctx->proxy->upstream->peer; p = ngx_snprintf(buf, len, - " while %s, client: %V, URL: %V, upstream: %V%V", + " while %s, client: %V, URL: %V, upstream: http://%V%s%V", ctx->proxy->action, &r->connection->addr_text, &r->unparsed_uri, - &peer->peers->peers[peer->cur_peer].addr_port_text, + &peer->peers->peer[peer->cur_peer].name, + ctx->proxy->lcf->upstream->uri_separator, &ctx->proxy->lcf->upstream->uri); len -= p - buf; buf = p; @@ -835,8 +851,24 @@ u_char *ngx_http_proxy_log_error(void *data, u_char *buf, size_t len) } +static size_t ngx_http_proxy_log_proxy_state_getlen(ngx_http_request_t *r, + uintptr_t data) +{ + ngx_http_proxy_ctx_t *p; + + p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module); + + if (p == NULL) { + return 1; + } + + return p->states.nelts * /* STUB */ 100; +} + + static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, - u_char *buf, uintptr_t data) + u_char *buf, + ngx_http_log_op_t *op) { ngx_uint_t i; ngx_http_proxy_ctx_t *p; @@ -845,21 +877,10 @@ static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module); if (p == NULL) { - if (buf == NULL) { - return (u_char *) 1; - } - *buf = '-'; return buf + 1; } - - if (buf == NULL) { - /* find the request line length */ - return (u_char *) (uintptr_t) (p->states.nelts * /* STUB */ 100); - } - - i = 0; state = p->states.elts; @@ -935,6 +956,8 @@ static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, } +#if 0 + static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r, u_char *buf, uintptr_t data) { @@ -1014,23 +1037,23 @@ static u_char *ngx_http_proxy_log_reason(ngx_http_request_t *r, u_char *buf, } } +#endif + -static ngx_int_t ngx_http_proxy_pre_conf(ngx_conf_t *cf) +static ngx_int_t ngx_http_proxy_add_log_formats(ngx_conf_t *cf) { ngx_http_log_op_name_t *op; for (op = ngx_http_proxy_log_fmt_ops; op->name.len; op++) { /* void */ } - op->op = NULL; - - op = ngx_http_log_fmt_ops; + op->run = NULL; - for (op = ngx_http_log_fmt_ops; op->op; op++) { + for (op = ngx_http_log_fmt_ops; op->run; op++) { if (op->name.len == 0) { - op = (ngx_http_log_op_name_t *) op->op; + op = (ngx_http_log_op_name_t *) op->run; } } - op->op = (ngx_http_log_op_pt) ngx_http_proxy_log_fmt_ops; + op->run = (ngx_http_log_op_run_pt) ngx_http_proxy_log_fmt_ops; return NGX_OK; } @@ -1044,24 +1067,19 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)), NGX_CONF_ERROR); - /* set by ngx_pcalloc(): - - conf->bufs.num = 0; - - conf->path = NULL; - - conf->next_upstream = 0; - conf->use_stale = 0; - - conf->upstreams = NULL; - conf->peers = NULL; - - conf->cache_path = NULL; - conf->temp_path = NULL; - - conf->busy_lock = NULL; - - */ + /* + * set by ngx_pcalloc(): + * + * conf->bufs.num = 0; + * conf->path = NULL; + * conf->next_upstream = 0; + * conf->use_stale = 0; + * conf->upstreams = NULL; + * conf->peers = NULL; + * conf->cache_path = NULL; + * conf->temp_path = NULL; + * conf->busy_lock = NULL; + */ conf->connect_timeout = NGX_CONF_UNSET_MSEC; conf->send_timeout = NGX_CONF_UNSET_MSEC; @@ -1210,11 +1228,15 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, ngx_conf_merge_bitmask_value(conf->use_stale, prev->use_stale, NGX_CONF_BITMASK_SET); +#if 0 ngx_conf_merge_path_value(conf->cache_path, prev->cache_path, - "cache", 1, 2, 0, cf->pool); + NGX_HTTP_PROXY_CACHE_PATH, 1, 2, 0, + ngx_garbage_collector_temp_handler, cf); +#endif ngx_conf_merge_path_value(conf->temp_path, prev->temp_path, - "temp", 1, 2, 0, cf->pool); + NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0, + ngx_garbage_collector_temp_handler, cf); ngx_conf_merge_value(conf->cache, prev->cache, 0); @@ -1256,24 +1278,23 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, } - static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_proxy_loc_conf_t *lcf = conf; - ngx_uint_t i, len; - char *err; - u_char *host; - in_addr_t addr; - ngx_str_t *value; - struct hostent *h; - ngx_http_core_loc_conf_t *clcf; - + ngx_str_t *value, *url; + ngx_inet_upstream_t inet_upstream; + ngx_http_core_loc_conf_t *clcf; +#if (NGX_HAVE_UNIX_DOMAIN) + ngx_unix_domain_upstream_t unix_upstream; +#endif value = cf->args->elts; - if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) { + url = &value[1]; + + if (ngx_strncasecmp(url->data, "http://", 7) != 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix"); return NGX_CONF_ERROR; } @@ -1284,121 +1305,52 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } - lcf->upstream->url.len = value[1].len; - if (!(lcf->upstream->url.data = ngx_palloc(cf->pool, value[1].len + 1))) { - return NGX_CONF_ERROR; - } - - ngx_cpystrn(lcf->upstream->url.data, value[1].data, value[1].len + 1); - - value[1].data += 7; - value[1].len -= 7; - - err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream); - - if (err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, err); - return NGX_CONF_ERROR; - } - - if (!(host = ngx_palloc(cf->pool, lcf->upstream->host.len + 1))) { - return NGX_CONF_ERROR; - } - - ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1); + if (ngx_strncasecmp(url->data + 7, "unix:", 5) == 0) { - /* AF_INET only */ +#if (NGX_HAVE_UNIX_DOMAIN) - addr = inet_addr((char *) host); + ngx_memzero(&unix_upstream, sizeof(ngx_unix_domain_upstream_t)); - if (addr == INADDR_NONE) { - h = gethostbyname((char *) host); + unix_upstream.name = *url; + unix_upstream.url.len = url->len - 7; + unix_upstream.url.data = url->data + 7; + unix_upstream.uri_part = 1; - if (h == NULL || h->h_addr_list[0] == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "host %s not found", host); + if (!(lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream))) { return NGX_CONF_ERROR; } - for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } - - /* MP: ngx_shared_palloc() */ - - lcf->peers = ngx_pcalloc(cf->pool, - sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1)); - - if (lcf->peers == NULL) { - return NGX_CONF_ERROR; - } - - lcf->peers->number = i; - - /* STUB */ - lcf->peers->max_fails = 1; - lcf->peers->fail_timeout = 60; - - for (i = 0; h->h_addr_list[i] != NULL; i++) { - lcf->peers->peers[i].host.data = host; - lcf->peers->peers[i].host.len = lcf->upstream->host.len; - lcf->peers->peers[i].addr = *(in_addr_t *)(h->h_addr_list[i]); - lcf->peers->peers[i].port = lcf->upstream->port; + lcf->upstream->host_header.len = sizeof("localhost") - 1; + lcf->upstream->host_header.data = (u_char *) "localhost"; + lcf->upstream->uri = unix_upstream.uri; + lcf->upstream->uri_separator = ":"; + lcf->upstream->default_port = 1; - len = INET_ADDRSTRLEN - 1 + 1 + lcf->upstream->port_text.len; - - lcf->peers->peers[i].addr_port_text.data = - ngx_palloc(cf->pool, len); - if (lcf->peers->peers[i].addr_port_text.data == NULL) { - return NGX_CONF_ERROR; - } - - len = ngx_inet_ntop(AF_INET, - &lcf->peers->peers[i].addr, - lcf->peers->peers[i].addr_port_text.data, - len); - - lcf->peers->peers[i].addr_port_text.data[len++] = ':'; - - ngx_memcpy(lcf->peers->peers[i].addr_port_text.data + len, - lcf->upstream->port_text.data, - lcf->upstream->port_text.len); +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the unix domain sockets are not supported " + "on this platform"); + return NGX_CONF_ERROR; - lcf->peers->peers[i].addr_port_text.len = - len + lcf->upstream->port_text.len; - } +#endif } else { + ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t)); - /* MP: ngx_shared_palloc() */ - - if (!(lcf->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)))) { - return NGX_CONF_ERROR; - } - - lcf->peers->number = 1; - - lcf->peers->peers[0].host.data = host; - lcf->peers->peers[0].host.len = lcf->upstream->host.len; - lcf->peers->peers[0].addr = addr; - lcf->peers->peers[0].port = lcf->upstream->port; - - len = lcf->upstream->host.len + 1 + lcf->upstream->port_text.len; + inet_upstream.name = *url; + inet_upstream.url.len = url->len - 7; + inet_upstream.url.data = url->data + 7; + inet_upstream.default_port_value = 80; + inet_upstream.uri_part = 1; - lcf->peers->peers[0].addr_port_text.len = len; - - lcf->peers->peers[0].addr_port_text.data = ngx_palloc(cf->pool, len); - if (lcf->peers->peers[0].addr_port_text.data == NULL) { + if (!(lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream))) { return NGX_CONF_ERROR; } - len = lcf->upstream->host.len; - - ngx_memcpy(lcf->peers->peers[0].addr_port_text.data, - lcf->upstream->host.data, len); - - lcf->peers->peers[0].addr_port_text.data[len++] = ':'; - - ngx_memcpy(lcf->peers->peers[0].addr_port_text.data + len, - lcf->upstream->port_text.data, - lcf->upstream->port_text.len); + lcf->upstream->host_header = inet_upstream.host_header; + lcf->upstream->port_text = inet_upstream.port_text; + lcf->upstream->uri = inet_upstream.uri; + lcf->upstream->uri_separator = ""; } clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); @@ -1410,93 +1362,7 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, clcf->auto_redirect = 1; } - return NULL; -} - - -static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, - ngx_http_proxy_upstream_conf_t *u) -{ - size_t i; - - if (url->data[0] == ':' || url->data[0] == '/') { - return "invalid upstream URL"; - } - - u->host.data = url->data; - u->host_header.data = url->data; - - for (i = 1; i < url->len; i++) { - if (url->data[i] == ':') { - u->port_text.data = &url->data[i] + 1; - u->host.len = i; - } - - if (url->data[i] == '/') { - u->uri.data = &url->data[i]; - u->uri.len = url->len - i; - u->host_header.len = i; - - if (u->host.len == 0) { - u->host.len = i; - } - - if (u->port_text.data == NULL) { - u->default_port = 1; - u->port = htons(80); - u->port_text.len = 2; - u->port_text.data = (u_char *) "80"; - return NULL; - } - - u->port_text.len = &url->data[i] - u->port_text.data; - - if (u->port_text.len > 0) { - u->port = (in_port_t) ngx_atoi(u->port_text.data, - u->port_text.len); - if (u->port > 0) { - - if (u->port == 80) { - u->default_port = 1; - } - - u->port = htons(u->port); - return NULL; - } - } - - return "invalid port in upstream URL"; - } - } - - if (u->host.len == 0) { - u->host.len = i; - } - - u->host_header.len = i; - - u->uri.data = (u_char *) "/"; - u->uri.len = 1; - - if (u->port_text.data == NULL) { - u->default_port = 1; - u->port = htons(80); - u->port_text.len = 2; - u->port_text.data = (u_char *) "80"; - return NULL; - } - - u->port_text.len = &url->data[i] - u->port_text.data; - - if (u->port_text.len > 0) { - u->port = (in_port_t) ngx_atoi(u->port_text.data, u->port_text.len); - if (u->port > 0) { - u->port = htons(u->port); - return NULL; - } - } - - return "invalid port in upstream URL"; + return NGX_CONF_OK; } diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 8ab88ad54..915ca6219 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -47,6 +47,8 @@ typedef struct { ngx_str_t port_text; ngx_str_t *location; + char *uri_separator; + in_port_t port; unsigned default_port:1; @@ -131,7 +133,11 @@ typedef struct { ngx_table_elt_t *connection; ngx_table_elt_t *content_type; ngx_table_elt_t *content_length; + +#if (NGX_HTTP_GZIP) ngx_table_elt_t *content_encoding; +#endif + ngx_table_elt_t *last_modified; ngx_table_elt_t *location; ngx_table_elt_t *accept_ranges; diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c index cd5deeb9e..78ae6530f 100644 --- a/src/http/modules/proxy/ngx_http_proxy_header.c +++ b/src/http/modules/proxy/ngx_http_proxy_header.c @@ -26,12 +26,7 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, part = &headers_in->headers.part; h = part->elts; -#if 0 - h = headers_in->headers.elts; - for (i = 0; i < headers_in->headers.nelts; i++) { -#endif - - for (i = 0 ; /* void */; i++) { + for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { @@ -113,10 +108,12 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, continue; } +#if (NGX_HTTP_GZIP) if (&h[i] == headers_in->content_encoding) { r->headers_out.content_encoding = ho; continue; } +#endif if (&h[i] == headers_in->last_modified) { r->headers_out.last_modified = ho; @@ -169,7 +166,8 @@ static int ngx_http_proxy_rewrite_location_header(ngx_http_proxy_ctx_t *p, return NGX_ERROR; } - if (uc->url.len > loc->value.len + if (p->lcf->preserve_host + || uc->url.len > loc->value.len || ngx_rstrncmp(loc->value.data, uc->url.data, uc->url.len) != 0) { diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index 47d2b17df..4dfd4e6d1 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -14,7 +14,7 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p); -static void ngx_http_proxy_init_upstream(void *data); +static void ngx_http_proxy_init_upstream(ngx_http_request_t *r); static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); @@ -53,9 +53,7 @@ static char connection_close_header[] = "Connection: close" CRLF; int ngx_http_proxy_request_upstream(ngx_http_proxy_ctx_t *p) { int rc; - ngx_temp_file_t *tf; ngx_http_request_t *r; - ngx_http_request_body_t *rb; ngx_http_proxy_upstream_t *u; r = p->request; @@ -75,36 +73,7 @@ int ngx_http_proxy_request_upstream(ngx_http_proxy_ctx_t *p) u->method = r->method; - if (!(rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)))) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - r->request_body = rb; - - if (r->headers_in.content_length_n <= 0) { - ngx_http_proxy_init_upstream(p); - return NGX_DONE; - } - - if (!(tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)))) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - tf->file.fd = NGX_INVALID_FILE; - tf->file.log = r->connection->log; - tf->path = p->lcf->temp_path; - tf->pool = r->pool; - tf->warn = "a client request body is buffered to a temporary file"; - /* tf->persistent = 0; */ - - rb->handler = ngx_http_proxy_init_upstream; - rb->data = p; - /* rb->bufs = NULL; */ - /* rb->buf = NULL; */ - /* rb->rest = 0; */ - - rb->temp_file = tf; - - rc = ngx_http_read_client_request_body(r); + rc = ngx_http_read_client_request_body(r, ngx_http_proxy_init_upstream); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; @@ -428,17 +397,16 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) } -static void ngx_http_proxy_init_upstream(void *data) +static void ngx_http_proxy_init_upstream(ngx_http_request_t *r) { - ngx_http_proxy_ctx_t *p = data; ngx_chain_t *cl; - ngx_http_request_t *r; + ngx_http_proxy_ctx_t *p; ngx_output_chain_ctx_t *output; ngx_chain_writer_ctx_t *writer; ngx_http_proxy_log_ctx_t *ctx; - r = p->request; + p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http proxy init upstream, client timer: %d", @@ -502,7 +470,7 @@ static void ngx_http_proxy_init_upstream(void *data) output->pool = r->pool; output->bufs.num = 1; output->tag = (ngx_buf_tag_t) &ngx_http_proxy_module; - output->output_filter = (ngx_output_chain_filter_pt) ngx_chain_writer; + output->output_filter = ngx_chain_writer; if (!(writer = ngx_palloc(r->pool, sizeof(ngx_chain_writer_ctx_t)))) { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -700,7 +668,7 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) } p->state->peer = - &p->upstream->peer.peers->peers[p->upstream->peer.cur_peer].addr_port_text; + &p->upstream->peer.peers->peer[p->upstream->peer.cur_peer].name; if (rc == NGX_CONNECT_ERROR) { ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR); @@ -733,7 +701,7 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) } if (r->request_body->buf) { - if (r->request_body->temp_file->file.fd != NGX_INVALID_FILE) { + if (r->request_body->temp_file) { if (!(output->free = ngx_alloc_chain_link(r->pool))) { ngx_http_proxy_finalize_request(p, @@ -1347,6 +1315,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p) } ep->preread_bufs->buf = p->header_in; ep->preread_bufs->next = NULL; + p->header_in->recycled = 1; ep->preread_size = p->header_in->last - p->header_in->pos; |
