aboutsummaryrefslogtreecommitdiff
path: root/src/http/modules/ngx_http_fastcgi_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/modules/ngx_http_fastcgi_module.c')
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c1636
1 files changed, 610 insertions, 1026 deletions
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 4b92cd46f..cf9d008a5 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -15,37 +15,14 @@ typedef struct {
ngx_peers_t *peers;
- ngx_uint_t params;
-
- ngx_str_t root;
ngx_str_t index;
- ngx_array_t *vars;
-
- ngx_str_t *location;
+ ngx_array_t *params_len;
+ ngx_array_t *params;
+ ngx_array_t *params_source;
} 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,
@@ -69,28 +46,9 @@ typedef struct {
size_t padding;
ngx_uint_t header;
-
- ngx_http_fastcgi_upstream_t *upstream;
} ngx_http_fastcgi_ctx_t;
-#define NGX_HTTP_FASTCGI_REMOTE_ADDR 0x00000002
-#define NGX_HTTP_FASTCGI_REMOTE_USER 0x00000004
-#define NGX_HTTP_FASTCGI_SERVER_NAME 0x00000008
-#define NGX_HTTP_FASTCGI_SERVER_ADDR 0x00000010
-#define NGX_HTTP_FASTCGI_SERVER_PORT 0x00000020
-#define NGX_HTTP_FASTCGI_SCRIPT_NAME 0x00000040
-#define NGX_HTTP_FASTCGI_AUTH_TYPE 0x00000080
-#define NGX_HTTP_FASTCGI_SERVER_PROTOCOL 0x00000100
-#define NGX_HTTP_FASTCGI_SERVER_SOFTWARE 0x00000200
-#define NGX_HTTP_FASTCGI_GATEWAY_INTERFACE 0x00000400
-#define NGX_HTTP_FASTCGI_REQUEST_URI 0x00000800
-#define NGX_HTTP_FASTCGI_REDIRECT_STATUS 0x00001000
-#define NGX_HTTP_FASTCGI_DOCUMENT_ROOT 0x00002000
-#define NGX_HTTP_FASTCGI_SCRIPT_FILENAME 0x00004000
-#define NGX_HTTP_FASTCGI_REMOTE_PORT 0x00008000
-
-
#define NGX_HTTP_FASTCGI_RESPONDER 1
#define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1
@@ -123,10 +81,24 @@ typedef struct {
} ngx_http_fastcgi_begin_request_t;
+typedef struct {
+ u_char version;
+ u_char type;
+ u_char request_id_hi;
+ u_char request_id_lo;
+} ngx_http_fastcgi_header_small_t;
+
+
+typedef struct {
+ ngx_http_fastcgi_header_t h0;
+ ngx_http_fastcgi_begin_request_t br;
+ ngx_http_fastcgi_header_small_t h1;
+} ngx_http_fastcgi_request_start_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,
@@ -135,53 +107,69 @@ 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 ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf);
+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_http_variable_value_t *
+ ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
+ uintptr_t data);
+
static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static char *ngx_http_fastcgi_set_var(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_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
+ { 1, /* version */
+ NGX_HTTP_FASTCGI_BEGIN_REQUEST, /* type */
+ 0, /* request_id_hi */
+ 1, /* request_id_lo */
+ 0, /* content_length_hi */
+ sizeof(ngx_http_fastcgi_begin_request_t), /* content_length_lo */
+ 0, /* padding_length */
+ 0 }, /* reserved */
+
+ { 0, /* role_hi */
+ NGX_HTTP_FASTCGI_RESPONDER, /* role_lo */
+ 0, /* NGX_HTTP_FASTCGI_KEEP_CONN */ /* flags */
+ { 0, 0, 0, 0, 0 } }, /* reserved[5] */
+
+ { 1, /* version */
+ NGX_HTTP_FASTCGI_PARAMS, /* type */
+ 0, /* request_id_hi */
+ 1 }, /* request_id_lo */
+
+};
+
+
+#if 0
static ngx_str_t ngx_http_fastcgi_methods[] = {
ngx_string("GET"),
ngx_string("HEAD"),
ngx_string("POST")
};
-
-
-#if (NGX_PCRE)
-static ngx_str_t ngx_http_fastcgi_uri = ngx_string("/");
#endif
-static ngx_http_header_t ngx_http_fastcgi_headers_in[] = {
- { ngx_string("Status"), offsetof(ngx_http_fastcgi_headers_in_t, status) },
+static ngx_str_t ngx_http_fastcgi_script_name =
+ ngx_string("fastcgi_script_name");
- { 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) },
+#if (NGX_PCRE)
+static ngx_str_t ngx_http_fastcgi_uri = ngx_string("/");
+#endif
- { 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
+static ngx_conf_post_t ngx_http_fastcgi_lowat_post =
+ { ngx_http_fastcgi_lowat_check };
+static ngx_conf_enum_t ngx_http_fastcgi_set_methods[] = {
+ { ngx_string("get"), NGX_HTTP_GET },
{ 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 },
@@ -192,28 +180,6 @@ static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = {
};
-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_string("document_root"), NGX_HTTP_FASTCGI_DOCUMENT_ROOT },
- { ngx_string("script_filename"), NGX_HTTP_FASTCGI_SCRIPT_FILENAME },
- { ngx_string("remote_port"), NGX_HTTP_FASTCGI_REMOTE_PORT },
-
- { ngx_null_string, 0 }
-};
-
-
static ngx_command_t ngx_http_fastcgi_commands[] = {
{ ngx_string("fastcgi_pass"),
@@ -223,13 +189,6 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
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,
@@ -265,6 +224,27 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.header_buffer_size),
NULL },
+ { ngx_string("fastcgi_method"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.method),
+ ngx_http_fastcgi_set_methods },
+
+ { ngx_string("fastcgi_pass_request_headers"),
+ 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.pass_request_headers),
+ NULL },
+
+ { ngx_string("fastcgi_pass_request_body"),
+ 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.pass_request_body),
+ NULL },
+
{ ngx_string("fastcgi_redirect_errors"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -276,7 +256,7 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
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),
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_x_powered_by),
NULL },
{ ngx_string("fastcgi_read_timeout"),
@@ -328,26 +308,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream),
&ngx_http_fastcgi_next_upstream_masks },
- { ngx_string("fastcgi_set_var"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_fastcgi_set_var,
+ { ngx_string("fastcgi_param"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_conf_set_table_elt_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- 0,
+ offsetof(ngx_http_fastcgi_loc_conf_t, params_source),
NULL },
- { 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 */
+ ngx_http_fastcgi_add_variables, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -361,7 +335,7 @@ ngx_http_module_t ngx_http_fastcgi_module_ctx = {
ngx_module_t ngx_http_fastcgi_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_fastcgi_module_ctx, /* module context */
ngx_http_fastcgi_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -396,26 +370,15 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
u->conf = &flcf->upstream;
- u->location0 = 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->schema0.len = sizeof("fastcgi://") - 1;
- u->schema0.data = (u_char *) "fastcgi://";
- u->uri0.len = sizeof("/") - 1;
- u->uri0.data = (u_char *) "/";
-
r->upstream = u;
rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
@@ -431,206 +394,67 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
static ngx_int_t
ngx_http_fastcgi_create_request(ngx_http_request_t *r)
{
- u_char ch, *pos, addr_text[INET_ADDRSTRLEN],
- port_text[sizeof("65535") - 1];
- size_t size, len, index, padding,
- addr_len, port_len;
- off_t file_pos;
- ngx_buf_t *b;
- socklen_t slen;
- ngx_chain_t *cl, *body;
- ngx_uint_t i, n, next, *vindex, port;
- ngx_list_part_t *part;
- ngx_table_elt_t *header;
- struct sockaddr_in sin, *sinp;
- ngx_http_variable_t *var;
- ngx_http_variable_value_t *value;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_main_conf_t *cmcf;
- ngx_http_fastcgi_header_t *h;
- ngx_http_fastcgi_loc_conf_t *flcf;
- ngx_http_fastcgi_begin_request_t *br;
+ off_t file_pos;
+ u_char ch, *pos;
+ size_t size, len, key_len, val_len, padding;
+ ngx_uint_t i, n, next;
+ ngx_buf_t *b;
+ ngx_chain_t *cl, *body;
+ ngx_list_part_t *part;
+ ngx_table_elt_t *header;
+ ngx_http_script_code_pt code;
+ ngx_http_script_engine_t e, le;
+ ngx_http_fastcgi_header_t *h;
+ ngx_http_fastcgi_loc_conf_t *flcf;
+ ngx_http_script_len_code_pt lcode;
+ len = 0;
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 (NGX_SUPPRESS_WARN)
- clcf = NULL;
- var = NULL;
- vindex = NULL;
-#endif
-
-
- 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->unparsed_uri.len > 127) ? 4 : 1)
- + sizeof("REQUEST_URI") - 1 + r->unparsed_uri.len;
- }
-
- if (flcf->params & NGX_HTTP_FASTCGI_DOCUMENT_ROOT) {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- len += 1 + ((clcf->root.len > 127) ? 4 : 1)
- + sizeof("DOCUMENT_ROOT") - 1 + clcf->root.len;
- }
-
- if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_FILENAME) {
- len += 1 + ((flcf->root.len + r->uri.len + index > 127) ? 4 : 1)
- + sizeof("SCRIPT_FILENAME") - 1
- + flcf->root.len + r->uri.len + index;
- }
+ if (flcf->params_len) {
+ ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
- 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;
- }
+ le.ip = flcf->params_len->elts;
+ le.request = r;
- port_len = 0;
+ while (*(uintptr_t *) le.ip) {
- if (flcf->params & NGX_HTTP_FASTCGI_REMOTE_PORT) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ key_len = lcode(&le);
- /* AF_INET only */
-
- if (r->connection->sockaddr->sa_family == AF_INET) {
- sinp = (struct sockaddr_in *) r->connection->sockaddr;
-
- port = ntohs(sinp->sin_port);
-
- if (port > 0 && port < 65536) {
- port_len = ngx_sprintf(port_text, "%ui", port) - port_text;
+ for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
}
+ le.ip += sizeof(uintptr_t);
- len += 1 + 1 + sizeof("REMOTE_PORT") - 1 + port_len;
- }
- }
-
- if (flcf->params & NGX_HTTP_FASTCGI_SERVER_NAME) {
- len += 1 + 1 + sizeof("SERVER_NAME") - 1 + r->server_name.len;
- }
-
- 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;
- }
-
-
- if (flcf->vars) {
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- var = cmcf->variables.elts;
- vindex = flcf->vars->elts;
-
- for (i = 0; i < flcf->vars->nelts; i++) {
-
- value = ngx_http_get_indexed_variable(r, vindex[i]);
- if (value == NULL) {
- continue;
- }
-
- if (value->text.len) {
- len += 1 + 1 + var[vindex[i]].name.len + value->text.len;
+ if (val_len) {
+ len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
}
}
}
+ if (flcf->upstream.pass_request_headers) {
- part = &r->headers_in.headers.part;
- header = part->elts;
+ part = &r->headers_in.headers.part;
+ header = part->elts;
- for (i = 0; /* void */; i++) {
+ for (i = 0; /* void */; i++) {
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ header = part->elts;
+ i = 0;
}
- part = part->next;
- header = part->elts;
- i = 0;
+ len += ((sizeof("HTTP_") - 1 + header[i].key.len > 127) ? 4 : 1)
+ + ((header[i].value.len > 127) ? 4 : 1)
+ + sizeof("HTTP_") - 1 + header[i].key.len + header[i].value.len;
}
-
- len += ((header[i].key.len > 127) ? 4 : 1)
- + ((header[i].value.len > 127) ? 4 : 1)
- + 5 + header[i].key.len + header[i].value.len;
}
@@ -667,36 +491,13 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
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;
+ ngx_memcpy(b->pos, &ngx_http_fastcgi_request_start,
+ sizeof(ngx_http_fastcgi_request_start_t));
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;
@@ -707,376 +508,109 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
+ sizeof(ngx_http_fastcgi_header_t);
- *b->last++ = sizeof("PATH_TRANSLATED") - 1;
+ if (flcf->params_len) {
+ ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
- 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);
+ e.ip = flcf->params->elts;
+ e.pos = b->last;
+ e.request = r;
- } 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);
- }
+ le.ip = flcf->params_len->elts;
+ while (*(uintptr_t *) le.ip) {
- *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->unparsed_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->unparsed_uri.data, len);
- }
-
-
- if (flcf->params & NGX_HTTP_FASTCGI_DOCUMENT_ROOT) {
- *b->last++ = sizeof("DOCUMENT_ROOT") - 1;
-
- len = clcf->root.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, "DOCUMENT_ROOT",
- sizeof("DOCUMENT_ROOT") - 1);
- b->last = ngx_cpymem(b->last, clcf->root.data, len);
- }
-
-
- if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_FILENAME) {
- *b->last++ = sizeof("SCRIPT_FILENAME") - 1;
-
- len = flcf->root.len + r->uri.len + index;
- if (len > 127) {
- *b->last++ = (u_char) (((len >> 24) & 0x7f) | 0x80);
- *b->last++ = (u_char) ((len >> 16) & 0xff);
- *b->last++ = (u_char) ((len >> 8) & 0xff);
- *b->last++ = (u_char) (len & 0xff);
-
- } else {
- *b->last++ = (u_char) len;
- }
-
- b->last = ngx_cpymem(b->last, "SCRIPT_FILENAME",
- sizeof("SCRIPT_FILENAME") - 1);
- b->last = ngx_cpymem(b->last, flcf->root.data, flcf->root.len);
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
-
- if (index) {
- b->last = ngx_cpymem(b->last, flcf->index.data, index);
- }
- }
-
-
- if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_NAME) {
- *b->last++ = sizeof("SCRIPT_NAME") - 1;
-
- 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 (port_len) {
- *b->last++ = sizeof("REMOTE_PORT") - 1;
- *b->last++ = (u_char) port_len;
- b->last = ngx_cpymem(b->last, "REMOTE_PORT", sizeof("REMOTE_PORT") - 1);
- b->last = ngx_cpymem(b->last, port_text, port_len);
- }
-
-
- if (flcf->params & NGX_HTTP_FASTCGI_SERVER_NAME) {
- *b->last++ = sizeof("SERVER_NAME") - 1;
- *b->last++ = (u_char) r->server_name.len;
- 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);
- }
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ key_len = (u_char) lcode(&le);
+ for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ }
+ le.ip += sizeof(uintptr_t);
- 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 (val_len) {
+ *e.pos++ = (u_char) key_len;
+ if (val_len > 127) {
+ *e.pos++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
+ *e.pos++ = (u_char) ((val_len >> 16) & 0xff);
+ *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
+ *e.pos++ = (u_char) (val_len & 0xff);
- if (flcf->params & NGX_HTTP_FASTCGI_SERVER_PROTOCOL
- && r->http_protocol.len)
- {
- *b->last++ = sizeof("SERVER_PROTOCOL") - 1;
+ } else {
+ *e.pos++ = (u_char) val_len;
+ }
+ }
- 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);
+ e.skip = val_len ? 0 : 1;
- } else {
- *b->last++ = (u_char) len;
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+ }
+ e.ip += sizeof(uintptr_t);
}
- b->last = ngx_cpymem(b->last, "SERVER_PROTOCOL",
- sizeof("SERVER_PROTOCOL") - 1);
- b->last = ngx_cpymem(b->last, r->http_protocol.data, len);
+ b->last = e.pos;
}
- 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->upstream.pass_request_headers) {
- 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 (flcf->vars) {
- for (i = 0; i < flcf->vars->nelts; i++) {
-
- value = ngx_http_get_indexed_variable(r, vindex[i]);
- if (value == NULL) {
- continue;
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ header = part->elts;
+ i = 0;
}
- if (value->text.len == 0) {
- continue;
+ len = sizeof("HTTP_") - 1 + 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;
}
- *b->last++ = (u_char) var[vindex[i]].name.len;
- *b->last++ = (u_char) value->text.len;
-
- b->last = ngx_cpymem(b->last, var[vindex[i]].name.data,
- var[vindex[i]].name.len);
-
- b->last = ngx_cpymem(b->last, value->text.data, value->text.len);
- }
- }
-
-
- part = &r->headers_in.headers.part;
- header = part->elts;
+ 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);
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
+ } else {
+ *b->last++ = (u_char) len;
}
- 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);
- 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];
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
+ if (ch >= 'a' && ch <= 'z') {
+ ch &= ~0x20;
- if (ch >= 'a' && ch <= 'z') {
- ch &= ~0x20;
+ } else if (ch == '-') {
+ ch = '_';
+ }
- } else if (ch == '-') {
- ch = '_';
+ *b->last++ = ch;
}
- *b->last++ = ch;
+ b->last = ngx_cpymem(b->last, header[i].value.data,
+ header[i].value.len);
}
-
- b->last = ngx_cpymem(b->last, header[i].value.data,
- header[i].value.len);
}
@@ -1101,103 +635,109 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
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 (flcf->upstream.pass_request_body) {
+ body = r->upstream->request_bufs;
+ r->upstream->request_bufs = cl;
#if (NGX_SUPPRESS_WARN)
- file_pos = 0;
- pos = NULL;
+ file_pos = 0;
+ pos = NULL;
#endif
- while (body) {
+ while (body) {
- if (body->buf->in_file) {
- file_pos = body->buf->file_pos;
-
- } else {
- pos = body->buf->pos;
- }
-
- next = 0;
+ if (body->buf->in_file) {
+ file_pos = body->buf->file_pos;
- do {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
+ } else {
+ pos = body->buf->pos;
}
- ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
+ next = 0;
- 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;
+ do {
+ b = ngx_alloc_buf(r->pool);
+ if (b == NULL) {
+ return NGX_ERROR;
}
- b->file_last = file_pos;
- len = (ngx_uint_t) (file_pos - b->file_pos);
+ ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
- } else {
- b->pos = pos;
- pos += 32 * 1024;
+ if (body->buf->in_file) {
+ b->file_pos = file_pos;
+ file_pos += 32 * 1024;
- if (pos > body->buf->last) {
- pos = body->buf->last;
- next = 1;
- }
+ if (file_pos > body->buf->file_last) {
+ file_pos = body->buf->file_last;
+ next = 1;
+ }
- b->last = pos;
- len = (ngx_uint_t) (pos - b->pos);
- }
+ b->file_last = file_pos;
+ len = (ngx_uint_t) (file_pos - b->file_pos);
- padding = 8 - len % 8;
- padding = (padding == 8) ? 0 : padding;
+ } else {
+ b->pos = pos;
+ pos += 32 * 1024;
- 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 (pos > body->buf->last) {
+ pos = body->buf->last;
+ next = 1;
+ }
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
+ b->last = pos;
+ len = (ngx_uint_t) (pos - b->pos);
+ }
- cl = cl->next;
- cl->buf = b;
+ 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;
+
+ cl->next = ngx_alloc_chain_link(r->pool);
+ if (cl->next == NULL) {
+ return NGX_ERROR;
+ }
- b = ngx_create_temp_buf(r->pool, sizeof(ngx_http_fastcgi_header_t)
- + padding);
- if (b == NULL) {
- return NGX_ERROR;
- }
+ cl = cl->next;
+ cl->buf = b;
- if (padding) {
- ngx_memzero(b->last, padding);
- b->last += padding;
- }
+ b = ngx_create_temp_buf(r->pool,
+ sizeof(ngx_http_fastcgi_header_t)
+ + padding);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
- h = (ngx_http_fastcgi_header_t *) b->last;
- b->last += sizeof(ngx_http_fastcgi_header_t);
+ if (padding) {
+ ngx_memzero(b->last, padding);
+ b->last += padding;
+ }
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
+ h = (ngx_http_fastcgi_header_t *) b->last;
+ b->last += sizeof(ngx_http_fastcgi_header_t);
+
+ cl->next = ngx_alloc_chain_link(r->pool);
+ if (cl->next == NULL) {
+ return NGX_ERROR;
+ }
- cl = cl->next;
- cl->buf = b;
+ cl = cl->next;
+ cl->buf = b;
- } while (!next);
+ } while (!next);
- body = body->next;
+ body = body->next;
+ }
+
+ } else {
+ r->upstream->request_bufs = cl;
}
h->version = 1;
@@ -1229,17 +769,6 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
f->state = ngx_http_fastcgi_st_version;
f->header = 0;
- ngx_memzero(&f->upstream->headers_in,
- sizeof(ngx_http_fastcgi_headers_in_t));
-
- if (f->upstream->headers_in.headers.part.elts) {
- if (ngx_list_init(&f->upstream->headers_in.headers, r->pool, 8,
- sizeof(ngx_table_elt_t)) == NGX_ERROR)
- {
- return NGX_ERROR;
- }
- }
-
return NGX_OK;
}
@@ -1247,16 +776,21 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
static ngx_int_t
ngx_http_fastcgi_process_header(ngx_http_request_t *r)
{
- u_char *start, *last;
- ngx_str_t *status_line, 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;
+ u_char *start, *last;
+ ngx_str_t *status_line, line;
+ ngx_int_t rc, status;
+ ngx_uint_t key;
+ ngx_table_elt_t *h;
+ ngx_http_upstream_t *u;
+ ngx_http_fastcgi_ctx_t *f;
+ ngx_http_upstream_header_t *hh;
+ ngx_http_upstream_main_conf_t *umcf;
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
+ umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
+ hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
+
if (f == NULL) {
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
if (f == NULL) {
@@ -1264,17 +798,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
}
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, 8,
- sizeof(ngx_table_elt_t)) == NGX_ERROR)
- {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
}
u = r->upstream;
@@ -1424,11 +947,13 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
/* a header line has been parsed successfully */
- h = ngx_list_push(&f->upstream->headers_in.headers);
+ h = ngx_list_push(&u->headers_in.headers);
if (h == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ h->hash = r->header_hash;
+
h->key.len = r->header_name_end - r->header_name_start;
h->value.len = r->header_end - r->header_start;
@@ -1443,18 +968,13 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
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;
- }
+ key = h->hash % umcf->headers_in_hash.hash_size;
- 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;
+ if (hh[key].name.len == h->key.len
+ && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0)
+ {
+ if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
@@ -1472,8 +992,8 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
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;
+ if (u->headers_in.status) {
+ status_line = &u->headers_in.status->value;
status = ngx_atoi(status_line->data, 3);
@@ -1541,84 +1061,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
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 */
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- 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;
@@ -1937,7 +1379,6 @@ ngx_http_fastcgi_process_record(ngx_http_request_t *r,
}
}
- f->pos = p + 1;
f->state = state;
return NGX_AGAIN;
@@ -1964,140 +1405,19 @@ 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)
-{
- 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];
-
- lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
- if (lcf->peers == NULL) {
- 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];
-
- lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
- if (lcf->peers == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
-
- clcf->handler = ngx_http_fastcgi_handler;
-
-#if (NGX_PCRE)
- lcf->location = clcf->regex ? &ngx_http_fastcgi_uri : &clcf->name;
-#else
- lcf->location = &clcf->name;
-#endif
-
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_fastcgi_set_var(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_fastcgi_loc_conf_t *lcf = conf;
-
- ngx_uint_t i, *index;
- ngx_str_t *value;
- ngx_http_variable_t *var;
- ngx_http_core_main_conf_t *cmcf;
-
- if (lcf->vars == NULL) {
- lcf->vars = ngx_array_create(cf->pool, 4,
- sizeof(ngx_http_variable_t *));
- if (lcf->vars == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- value = cf->args->elts;
-
- var = cmcf->variables.elts;
- for (i = 0; i < cmcf->variables.nelts; i++) {
- if (ngx_strcasecmp(var[i].name.data, value[1].data) == 0) {
-
- index = ngx_array_push(lcf->vars);
- if (index == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *index = var[i].index;
- return NGX_CONF_OK;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown variable name \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
+static ngx_int_t
+ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
{
-#if (NGX_FREEBSD)
- ssize_t *np = data;
+ ngx_http_variable_t *var;
- 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;
+ var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name, 0);
+ if (var == NULL) {
+ return NGX_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");
+ var->handler = ngx_http_fastcgi_script_name_variable;
- *np = 0;
-
-#endif
-
- return NGX_CONF_OK;
+ return NGX_OK;
}
@@ -2118,12 +1438,12 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
* 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->upstream.schema = { 0, NULL };
+ * conf->upstream.uri = { 0, NULL };
+ * conf->upstream.location = NULL;
+ *
* conf->index.len = 0;
* conf->index.data = NULL;
- * conf->location = NULL;
*/
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
@@ -2135,14 +1455,23 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
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.redirect_errors = NGX_CONF_UNSET;
+
conf->upstream.pass_unparsed_uri = NGX_CONF_UNSET;
- conf->upstream.x_powered_by = NGX_CONF_UNSET;
+ conf->upstream.method = NGX_CONF_UNSET_UINT;
+ conf->upstream.pass_request_headers = NGX_CONF_UNSET;
+ conf->upstream.pass_request_body = NGX_CONF_UNSET;
+
+ conf->upstream.redirect_errors = NGX_CONF_UNSET;
/* "fastcgi_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
+ conf->upstream.pass_x_powered_by = NGX_CONF_UNSET;
+
+ /* the hardcoded values */
+ conf->upstream.pass_server = 1;
+ conf->upstream.pass_date = 1;
+
return conf;
}
@@ -2153,7 +1482,13 @@ 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;
+ u_char *p;
+ size_t size;
+ uintptr_t *code;
+ ngx_uint_t i;
+ ngx_table_elt_t *src;
+ ngx_http_script_compile_t sc;
+ ngx_http_script_copy_code_t *copy;
ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
prev->upstream.connect_timeout, 60000);
@@ -2263,51 +1598,300 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
NGX_HTTP_FASTCGI_TEMP_PATH, 1, 2, 0,
ngx_garbage_collector_temp_handler, cf);
-
- ngx_conf_merge_msec_value(conf->upstream.redirect_errors,
- prev->upstream.redirect_errors, 0);
-
ngx_conf_merge_msec_value(conf->upstream.pass_unparsed_uri,
prev->upstream.pass_unparsed_uri, 0);
- if (conf->upstream.pass_unparsed_uri && conf->location->len > 1) {
+ if (conf->upstream.pass_unparsed_uri && conf->upstream.location->len > 1) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"\"fastcgi_pass_unparsed_uri\" can be set for "
"location \"/\" or given by regular expression.");
return NGX_CONF_ERROR;
}
- ngx_conf_merge_msec_value(conf->upstream.x_powered_by,
- prev->upstream.x_powered_by, 1);
+ if (conf->upstream.method == NGX_CONF_UNSET_UINT) {
+ conf->upstream.method = prev->upstream.method;
+ }
+ ngx_conf_merge_value(conf->upstream.pass_request_headers,
+ prev->upstream.pass_request_headers, 1);
+ ngx_conf_merge_value(conf->upstream.pass_request_body,
+ prev->upstream.pass_request_body, 1);
- 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_msec_value(conf->upstream.redirect_errors,
+ prev->upstream.redirect_errors, 0);
- ngx_conf_merge_str_value(conf->index, prev->index, "");
+ ngx_conf_merge_msec_value(conf->upstream.pass_x_powered_by,
+ prev->upstream.pass_x_powered_by, 1);
- if (conf->vars == NULL) {
- conf->vars = prev->vars;
- }
+
+ ngx_conf_merge_str_value(conf->index, prev->index, "");
if (conf->peers == NULL) {
conf->peers = prev->peers;
conf->upstream = prev->upstream;
}
+ if (conf->params_source == NULL) {
+ conf->params_source = prev->params_source;
+ conf->params_len = prev->params_len;
+ conf->params = prev->params;
+
+ if (conf->params_source == NULL) {
+ return NGX_CONF_OK;
+ }
+ }
+
+ conf->params_len = ngx_array_create(cf->pool, 64, 1);
+ if (conf->params_len == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->params = ngx_array_create(cf->pool, 512, 1);
+ if (conf->params == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ src = conf->params_source->elts;
+ for (i = 0; i < conf->params_source->nelts; i++) {
+
+ if (ngx_http_script_variables_count(&src[i].value) == 0) {
+ copy = ngx_array_push_n(conf->params_len,
+ sizeof(ngx_http_script_copy_code_t));
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ copy->code = (ngx_http_script_code_pt)
+ ngx_http_script_copy_len_code;
+ copy->len = src[i].key.len;
+
+
+ copy = ngx_array_push_n(conf->params_len,
+ sizeof(ngx_http_script_copy_code_t));
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ copy->code = (ngx_http_script_code_pt)
+ ngx_http_script_copy_len_code;
+ copy->len = src[i].value.len;
+
+
+ size = (sizeof(ngx_http_script_copy_code_t)
+ + src[i].key.len + src[i].value.len
+ + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
+
+ copy = ngx_array_push_n(conf->params, size);
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ copy->code = ngx_http_script_copy_code;
+ copy->len = src[i].key.len + src[i].value.len;
+
+ p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
+
+ p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
+ ngx_memcpy(p, src[i].value.data, src[i].value.len);
+
+ } else {
+ copy = ngx_array_push_n(conf->params_len,
+ sizeof(ngx_http_script_copy_code_t));
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ copy->code = (ngx_http_script_code_pt)
+ ngx_http_script_copy_len_code;
+ copy->len = src[i].key.len;
+
+
+ size = (sizeof(ngx_http_script_copy_code_t)
+ + src[i].key.len + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
+
+ copy = ngx_array_push_n(conf->params, size);
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ copy->code = ngx_http_script_copy_code;
+ copy->len = src[i].key.len;
+
+ p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
+ ngx_memcpy(p, src[i].key.data, src[i].key.len);
+
+
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ sc.cf = cf;
+ sc.source = &src[i].value;
+ sc.lengths = &conf->params_len;
+ sc.values = &conf->params;
+
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
+ if (code == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *code = (uintptr_t) NULL;
+
+
+ code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
+ if (code == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *code = (uintptr_t) NULL;
+ }
+
+ code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
+ if (code == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *code = (uintptr_t) NULL;
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_http_variable_value_t *
+ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, uintptr_t data)
+{
+ u_char *p;
+ ngx_http_variable_value_t *vv;
+ ngx_http_fastcgi_loc_conf_t *flcf;
+
+ vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+ if (vv == NULL) {
+ return NULL;
+ }
+
+ vv->value = 0;
+
+ flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
+
+ if (r->uri.data[r->uri.len - 1] != '/') {
+ vv->text = r->uri;
+ return vv;
+ }
+
+ vv->text.len = r->uri.len + flcf->index.len;
+
+ vv->text.data = ngx_palloc(r->pool, vv->text.len);
+ if (vv->text.data == NULL) {
+ return NULL;
+ }
+
+ p = ngx_cpymem(vv->text.data, r->uri.data, r->uri.len);
+ ngx_memcpy(p, flcf->index.data, flcf->index.len);
+
+ return vv;
+}
+
+
+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];
+
+ lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
+ if (lcf->peers == NULL) {
+ 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];
+
+ lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
+ if (lcf->peers == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ lcf->upstream.schema.len = sizeof("fastcgi://") - 1;
+ lcf->upstream.schema.data = (u_char *) "fastcgi://";
+ lcf->upstream.uri.len = sizeof("/") - 1;
+ lcf->upstream.uri.data = (u_char *) "/";
+
+ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+
+ clcf->handler = ngx_http_fastcgi_handler;
+
+#if (NGX_PCRE)
+ lcf->upstream.location = clcf->regex ? &ngx_http_fastcgi_uri : &clcf->name;
+#else
+ lcf->upstream.location = &clcf->name;
+#endif
+
+ 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;
}