aboutsummaryrefslogtreecommitdiff
path: root/src/http/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_access_module.c5
-rw-r--r--src/http/modules/ngx_http_auth_basic_module.c6
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c21
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c16
-rw-r--r--src/http/modules/ngx_http_chunked_filter_module.c7
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c1636
-rw-r--r--src/http/modules/ngx_http_geo_module.c7
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c40
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c51
-rw-r--r--src/http/modules/ngx_http_index_module.c507
-rw-r--r--src/http/modules/ngx_http_not_modified_filter_module.c11
-rw-r--r--src/http/modules/ngx_http_proxy_module.c1567
-rw-r--r--src/http/modules/ngx_http_range_filter_module.c36
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c972
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c604
-rw-r--r--src/http/modules/ngx_http_ssl_module.c12
-rw-r--r--src/http/modules/ngx_http_static_module.c290
-rw-r--r--src/http/modules/ngx_http_stub_status_module.c22
-rw-r--r--src/http/modules/ngx_http_userid_filter_module.c117
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c31
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.h7
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_upstream.c38
22 files changed, 2947 insertions, 3056 deletions
diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c
index 685d15d57..47f9944b0 100644
--- a/src/http/modules/ngx_http_access_module.c
+++ b/src/http/modules/ngx_http_access_module.c
@@ -54,7 +54,8 @@ static ngx_command_t ngx_http_access_commands[] = {
ngx_http_module_t ngx_http_access_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -68,7 +69,7 @@ ngx_http_module_t ngx_http_access_module_ctx = {
ngx_module_t ngx_http_access_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_access_module_ctx, /* module context */
ngx_http_access_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index 03314b5cf..98c47bd64 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -60,7 +60,8 @@ static ngx_command_t ngx_http_auth_basic_commands[] = {
ngx_http_module_t ngx_http_auth_basic_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -74,7 +75,7 @@ ngx_http_module_t ngx_http_auth_basic_module_ctx = {
ngx_module_t ngx_http_auth_basic_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_auth_basic_module_ctx, /* module context */
ngx_http_auth_basic_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -327,6 +328,7 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ r->headers_out.www_authenticate->hash = 1;
r->headers_out.www_authenticate->key.len = sizeof("WWW-Authenticate") - 1;
r->headers_out.www_authenticate->key.data = (u_char *) "WWW-Authenticate";
r->headers_out.www_authenticate->value = *realm;
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index ff163ed3c..76c5b0314 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -63,7 +63,8 @@ static ngx_command_t ngx_http_autoindex_commands[] = {
ngx_http_module_t ngx_http_autoindex_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -77,7 +78,7 @@ ngx_http_module_t ngx_http_autoindex_module_ctx = {
ngx_module_t ngx_http_autoindex_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_autoindex_module_ctx, /* module context */
ngx_http_autoindex_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -419,16 +420,8 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = b->last - b->pos;
-
- r->headers_out.content_type = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.content_type == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->headers_out.content_type->key.len = 0;
- r->headers_out.content_type->key.data = NULL;
- r->headers_out.content_type->value.len = sizeof("text/html") - 1;
- r->headers_out.content_type->value.data = (u_char *) "text/html";
+ r->headers_out.content_type.len = sizeof("text/html") - 1;
+ r->headers_out.content_type.data = (u_char *) "text/html";
rc = ngx_http_send_header(r);
@@ -436,10 +429,12 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
return rc;
}
- if (!r->main) {
+ if (r->main == NULL) {
b->last_buf = 1;
}
+ b->last_in_chain = 1;
+
out.buf = b;
out.next = NULL;
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index dad26ba91..0c76a5f43 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -106,7 +106,8 @@ static ngx_command_t ngx_http_charset_filter_commands[] = {
static ngx_http_module_t ngx_http_charset_filter_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
ngx_http_charset_create_main_conf, /* create main configuration */
ngx_http_charset_init_main_conf, /* init main configuration */
@@ -120,7 +121,7 @@ static ngx_http_module_t ngx_http_charset_filter_module_ctx = {
ngx_module_t ngx_http_charset_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_charset_filter_module_ctx, /* module context */
ngx_http_charset_filter_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -148,19 +149,18 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
return ngx_http_next_header_filter(r);
}
- if (r->headers_out.content_type == NULL) {
+ if (r->headers_out.content_type.len == 0) {
return ngx_http_next_header_filter(r);
}
- if (ngx_strncasecmp(r->headers_out.content_type->value.data,
- "text/", 5) != 0
- && ngx_strncasecmp(r->headers_out.content_type->value.data,
- "application/x-javascript", 24) != 0)
+ if (ngx_strncasecmp(r->headers_out.content_type.data, "text/", 5) != 0
+ && ngx_strncasecmp(r->headers_out.content_type.data,
+ "application/x-javascript", 24) != 0)
{
return ngx_http_next_header_filter(r);
}
- if (ngx_strstr(r->headers_out.content_type->value.data, "charset") != NULL)
+ if (ngx_strstr(r->headers_out.content_type.data, "charset") != NULL)
{
return ngx_http_next_header_filter(r);
}
diff --git a/src/http/modules/ngx_http_chunked_filter_module.c b/src/http/modules/ngx_http_chunked_filter_module.c
index b742dbb7c..4136613e0 100644
--- a/src/http/modules/ngx_http_chunked_filter_module.c
+++ b/src/http/modules/ngx_http_chunked_filter_module.c
@@ -13,7 +13,8 @@ static ngx_int_t ngx_http_chunked_filter_init(ngx_cycle_t *cycle);
static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -27,7 +28,7 @@ static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
ngx_module_t ngx_http_chunked_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_chunked_filter_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -43,7 +44,7 @@ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
ngx_http_chunked_header_filter(ngx_http_request_t *r)
{
- if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
+ if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED || r->main) {
return ngx_http_next_header_filter(r);
}
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;
}
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index 865f82551..723eff90f 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -34,7 +34,8 @@ static ngx_command_t ngx_http_geo_commands[] = {
static ngx_http_module_t ngx_http_geo_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -48,7 +49,7 @@ static ngx_http_module_t ngx_http_geo_module_ctx = {
ngx_module_t ngx_http_geo_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_geo_module_ctx, /* module context */
ngx_http_geo_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -110,7 +111,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
name.data++;
}
- var = ngx_http_add_variable(cf, &name, 1);
+ var = ngx_http_add_variable(cf, &name, 0);
if (var == NULL) {
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 4a4da7f58..1f7c2328c 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -207,7 +207,8 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
static ngx_http_module_t ngx_http_gzip_filter_module_ctx = {
- ngx_http_gzip_add_log_formats, /* pre conf */
+ ngx_http_gzip_add_log_formats, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -221,7 +222,7 @@ static ngx_http_module_t ngx_http_gzip_filter_module_ctx = {
ngx_module_t ngx_http_gzip_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_gzip_filter_module_ctx, /* module context */
ngx_http_gzip_filter_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -257,6 +258,11 @@ struct gztrailer {
#endif
+static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
+static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
+static ngx_str_t ngx_http_gzip_private = ngx_string("private");
+
+
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
@@ -276,8 +282,9 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|| r->header_only
+ || r->main
|| r->http_version < conf->http_version
- || r->headers_out.content_type == NULL
+ || r->headers_out.content_type.len == 0
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| r->headers_in.accept_encoding == NULL
@@ -294,8 +301,8 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
type = conf->types->elts;
for (i = 0; i < conf->types->nelts; i++) {
- if (r->headers_out.content_type->value.len >= type[i].name.len
- && ngx_strncasecmp(r->headers_out.content_type->value.data,
+ if (r->headers_out.content_type.len >= type[i].name.len
+ && ngx_strncasecmp(r->headers_out.content_type.data,
type[i].name.data, type[i].name.len) == 0)
{
found = 1;
@@ -346,6 +353,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
+ r->headers_out.content_encoding->hash = 1;
r->headers_out.content_encoding->key.len = sizeof("Content-Encoding") - 1;
r->headers_out.content_encoding->key.data = (u_char *) "Content-Encoding";
r->headers_out.content_encoding->value.len = sizeof("gzip") - 1;
@@ -353,10 +361,12 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
ctx->length = r->headers_out.content_length_n;
r->headers_out.content_length_n = -1;
+
if (r->headers_out.content_length) {
- r->headers_out.content_length->key.len = 0;
+ r->headers_out.content_length->hash = 0;
r->headers_out.content_length = NULL;
}
+
r->filter_need_in_memory = 1;
return ngx_http_next_header_filter(r);
@@ -404,22 +414,25 @@ ngx_http_gzip_proxied(ngx_http_request_t *r, ngx_http_gzip_conf_t *conf)
return NGX_DECLINED;
}
- if (r->headers_out.cache_control) {
+ if (r->headers_out.cache_control.elts) {
if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
- && ngx_strstr(r->headers_out.cache_control->value.data, "no-cache"))
+ && ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
+ &ngx_http_gzip_no_cache, NULL) >= 0)
{
return NGX_OK;
}
if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_STORE)
- && ngx_strstr(r->headers_out.cache_control->value.data, "no-store"))
+ && ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
+ &ngx_http_gzip_no_store, NULL) >= 0)
{
return NGX_OK;
}
if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_PRIVATE)
- && ngx_strstr(r->headers_out.cache_control->value.data, "private"))
+ && ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
+ &ngx_http_gzip_private, NULL) >= 0)
{
return NGX_OK;
}
@@ -484,8 +497,8 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
* and do not wait while a whole response will be sent to a client.
*
* 8K is for zlib deflate_state, it takes
- * * 5816 bytes on x86 and sparc64 (32-bit mode)
- * * 5920 bytes on amd64 and sparc64
+ * *) 5816 bytes on i386 and sparc64 (32-bit mode)
+ * *) 5920 bytes on amd64 and sparc64
*/
ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9));
@@ -696,7 +709,8 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (ctx->flush == Z_SYNC_FLUSH) {
- ctx->out_buf->flush = 0;
+ ctx->zstream.avail_out = 0;
+ ctx->out_buf->flush = 1;
ctx->flush = Z_NO_FLUSH;
cl = ngx_alloc_chain_link(r->pool);
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index 793cefd48..f27ab476d 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -41,7 +41,8 @@ static ngx_command_t ngx_http_headers_filter_commands[] = {
static ngx_http_module_t ngx_http_headers_filter_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -55,7 +56,7 @@ static ngx_http_module_t ngx_http_headers_filter_module_ctx = {
ngx_module_t ngx_http_headers_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_headers_filter_module_ctx, /* module context */
ngx_http_headers_filter_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -71,10 +72,11 @@ static ngx_int_t
ngx_http_headers_filter(ngx_http_request_t *r)
{
size_t len;
+ ngx_uint_t i;
ngx_table_elt_t *expires, *cc;
ngx_http_headers_conf_t *conf;
- if (r->headers_out.status != NGX_HTTP_OK) {
+ if (r->headers_out.status != NGX_HTTP_OK || r->main) {
return ngx_http_next_header_filter(r);
}
@@ -82,28 +84,43 @@ ngx_http_headers_filter(ngx_http_request_t *r)
if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
- expires = ngx_list_push(&r->headers_out.headers);
+ expires = r->headers_out.expires;
+
if (expires == NULL) {
- return NGX_ERROR;
- }
- r->headers_out.expires = expires;
+ expires = ngx_list_push(&r->headers_out.headers);
+ if (expires == NULL) {
+ return NGX_ERROR;
+ }
- cc = ngx_list_push(&r->headers_out.headers);
- if (cc == NULL) {
- return NGX_ERROR;
- }
+ r->headers_out.expires = expires;
- r->headers_out.cache_control = cc;
+ expires->hash = 1;
+ expires->key.len = sizeof("Expires") - 1;
+ expires->key.data = (u_char *) "Expires";
+ }
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
-
- expires->key.len = sizeof("Expires") - 1;
- expires->key.data = (u_char *) "Expires";
expires->value.len = len - 1;
- cc->key.len = sizeof("Cache-Control") - 1;
- cc->key.data = (u_char *) "Cache-Control";
+ cc = r->headers_out.cache_control.elts;
+
+ if (cc == NULL) {
+
+ cc = ngx_list_push(&r->headers_out.headers);
+ if (cc == NULL) {
+ return NGX_ERROR;
+ }
+
+ cc->hash = 1;
+ cc->key.len = sizeof("Cache-Control") - 1;
+ cc->key.data = (u_char *) "Cache-Control";
+
+ } else {
+ for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
+ cc[i].hash = 0;
+ }
+ }
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 373c31552..5315704b4 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -10,42 +10,52 @@
typedef struct {
- ngx_array_t indices;
+ ngx_str_t name;
+ ngx_array_t *lengths;
+ ngx_array_t *values;
+} ngx_http_index_t;
+
+
+typedef struct {
+ ngx_array_t *indices; /* array of ngx_http_index_t */
size_t max_index_len;
- ngx_http_cache_hash_t *index_cache;
} ngx_http_index_loc_conf_t;
typedef struct {
- ngx_uint_t index;
- u_char *last;
- ngx_str_t path;
- ngx_str_t redirect;
- ngx_http_cache_entry_t *cache;
- ngx_uint_t tested; /* unsigned tested:1 */
+ ngx_uint_t current;
+ size_t allocated;
+
+ u_char *path;
+ ngx_str_t uri;
+ ngx_str_t index;
+
+ ngx_uint_t tested; /* unsigned tested:1 */
} ngx_http_index_ctx_t;
#define NGX_HTTP_DEFAULT_INDEX "index.html"
+static ngx_int_t ngx_http_index_alloc(ngx_http_request_t *r, size_t size,
+ ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf);
static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx);
+ ngx_http_index_ctx_t *ctx);
static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx, ngx_err_t err);
+ ngx_http_index_ctx_t *ctx, ngx_err_t err);
static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle);
static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
+ void *parent, void *child);
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
+ void *conf);
static ngx_command_t ngx_http_index_commands[] = {
{ ngx_string("index"),
- NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_index_set_index,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -67,7 +77,8 @@ static ngx_command_t ngx_http_index_commands[] = {
ngx_http_module_t ngx_http_index_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -81,7 +92,7 @@ ngx_http_module_t ngx_http_index_module_ctx = {
ngx_module_t ngx_http_index_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_index_module_ctx, /* module context */
ngx_http_index_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -100,21 +111,24 @@ ngx_module_t ngx_http_index_module = {
* that path contains the usual file in place of the directory.
*/
-static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
+static ngx_int_t
+ngx_http_index_handler(ngx_http_request_t *r)
{
- u_char *name;
- ngx_fd_t fd;
- ngx_int_t rc;
- ngx_str_t *index;
- ngx_err_t err;
- ngx_log_t *log;
- ngx_http_index_ctx_t *ctx;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_index_loc_conf_t *ilcf;
-#if (NGX_HTTP_CACHE0)
- /* crc must be in ctx !! */
- uint32_t crc;
-#endif
+ u_char *name;
+ size_t len;
+ ngx_fd_t fd;
+ ngx_int_t rc;
+ ngx_err_t err;
+ ngx_log_t *log;
+ ngx_uint_t i;
+ ngx_http_index_t *index;
+ ngx_http_index_ctx_t *ctx;
+ ngx_pool_cleanup_file_t *cln;
+ ngx_http_script_code_pt code;
+ ngx_http_script_engine_t e;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_index_loc_conf_t *ilcf;
+ ngx_http_script_len_code_pt lcode;
if (r->uri.data[r->uri.len - 1] != '/') {
return NGX_DECLINED;
@@ -128,8 +142,8 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
log = r->connection->log;
/*
- * we use context because the handler supports an async file opening
- * and thus can be called several times
+ * we use context because the handler supports an async file opening,
+ * and may be called several times
*/
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -144,108 +158,63 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
}
ngx_http_set_ctx(r, ctx, ngx_http_index_module);
+ }
-#if (NGX_HTTP_CACHE)
+ index = ilcf->indices->elts;
+ for (i = ctx->current; i < ilcf->indices->nelts; i++) {
- if (ilcf->index_cache) {
- ctx->cache = ngx_http_cache_get(ilcf->index_cache, NULL,
- &r->uri, &crc);
+ if (index[i].lengths == NULL) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http index cache get: %p", ctx->cache);
+ if (index[i].name.data[0] == '/') {
+ return ngx_http_internal_redirect(r, &index[i].name, &r->args);
+ }
- if (ctx->cache && !ctx->cache->expired) {
+ len = ilcf->max_index_len;
+ ctx->index.len = index[i].name.len;
- ctx->cache->accessed = ngx_cached_time;
+ } else {
+ ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
- ctx->redirect.len = ctx->cache->data.value.len;
- ctx->redirect.data = ngx_palloc(r->pool, ctx->redirect.len + 1);
- if (ctx->redirect.data == NULL) {
- ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ e.ip = index[i].lengths->elts;
+ e.request = r;
- ngx_memcpy(ctx->redirect.data, ctx->cache->data.value.data,
- ctx->redirect.len + 1);
- ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
+ len = 1;
- return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
+ while (*(uintptr_t *) e.ip) {
+ lcode = *(ngx_http_script_len_code_pt *) e.ip;
+ len += lcode(&e);
}
- }
-
-#endif
-#if 0
- ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
- + ilcf->max_index_len
- - clcf->alias * clcf->name.len);
- if (ctx->path.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ ctx->index.len = len;
}
- ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
- clcf->root.len);
-#endif
-
- if (clcf->alias) {
- ctx->path.data = ngx_palloc(r->pool, clcf->root.len
- + r->uri.len + 1 - clcf->name.len
- + ilcf->max_index_len);
- if (ctx->path.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ctx->redirect.data = ngx_palloc(r->pool, r->uri.len
- + ilcf->max_index_len);
- if (ctx->redirect.data == NULL) {
+ if (len > ctx->allocated) {
+ if (ngx_http_index_alloc(r, len, ctx, clcf) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ }
- ngx_memcpy(ctx->path.data, clcf->root.data, clcf->root.len);
-
- ctx->last = ngx_cpystrn(ctx->path.data + clcf->root.len,
- r->uri.data + clcf->name.len,
- r->uri.len + 1 - clcf->name.len);
+ if (index[i].values == NULL) {
+ ngx_memcpy(ctx->index.data, index[i].name.data, ctx->index.len);
-#if 0
- /*
- * aliases usually have trailling "/",
- * set it in the start of the possible redirect
- */
+ } else {
+ e.ip = index[i].values->elts;
+ e.pos = ctx->index.data;
- if (*ctx->redirect.data != '/') {
- ctx->redirect.data--;
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
}
-#endif
- } else {
- ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
- + ilcf->max_index_len);
- if (ctx->path.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ if (*ctx->index.data == '/') {
+ ctx->index.len--;
+ return ngx_http_internal_redirect(r, &ctx->index, &r->args);
}
- ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
- clcf->root.len);
-
- ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data,
- r->uri.len + 1);
+ *e.pos++ = '\0';
}
- }
-
- ctx->path.len = ctx->last - ctx->path.data;
- index = ilcf->indices.elts;
- for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {
-
- if (index[ctx->index].data[0] == '/') {
- name = index[ctx->index].data;
-
- } else {
- ngx_memcpy(ctx->last, index[ctx->index].data,
- index[ctx->index].len + 1);
- name = ctx->path.data;
- }
+ name = ctx->path;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
"open index \"%s\"", name);
@@ -253,6 +222,7 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
if (fd == (ngx_fd_t) NGX_AGAIN) {
+ ctx->current = i;
return NGX_AGAIN;
}
@@ -290,149 +260,132 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
}
- /* STUB: open file cache */
+ cln = ngx_palloc(r->pool, sizeof(ngx_pool_cleanup_file_t));
+ if (cln == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
- r->file.name.data = name;
- r->file.fd = fd;
+ cln->fd = fd;
+ cln->name = name;
+ cln->log = r->pool->log;
- if (index[ctx->index].data[0] == '/') {
- r->file.name.len = index[ctx->index].len;
- ctx->redirect.len = index[ctx->index].len;
- ctx->redirect.data = index[ctx->index].data;
+ if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
- } else {
- if (clcf->alias) {
- name = ngx_cpymem(ctx->redirect.data, r->uri.data, r->uri.len);
- ngx_memcpy(name, index[ctx->index].data,
- index[ctx->index].len + 1);
- }
- ctx->redirect.len = r->uri.len + index[ctx->index].len;
- r->file.name.len = clcf->root.len + r->uri.len
- - clcf->alias * clcf->name.len
- + index[ctx->index].len;
+ if (clcf->alias) {
+ name = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len);
+ ngx_memcpy(name, ctx->index.data, ctx->index.len - 1);
}
- /**/
+ ctx->uri.len = r->uri.len + ctx->index.len - 1;
+ return ngx_http_internal_redirect(r, &ctx->uri, &r->args);
+ }
+
+ return NGX_DECLINED;
+}
-#if (NGX_HTTP_CACHE)
- if (ilcf->index_cache) {
+static ngx_int_t
+ngx_http_index_alloc(ngx_http_request_t *r, size_t size,
+ ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf)
+{
+ ctx->allocated = size;
- if (ctx->cache) {
- if (ctx->redirect.len == ctx->cache->data.value.len
- && ngx_memcmp(ctx->cache->data.value.data,
- ctx->redirect.data, ctx->redirect.len) == 0)
- {
- ctx->cache->accessed = ngx_cached_time;
- ctx->cache->updated = ngx_cached_time;
- ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
+ if (!clcf->alias) {
+ ctx->path = ngx_palloc(r->pool, clcf->root.len + r->uri.len + size);
+ if (ctx->path == NULL) {
+ return NGX_ERROR;
+ }
- return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
- }
- }
+ ctx->uri.data = ngx_cpymem(ctx->path, clcf->root.data, clcf->root.len);
- ctx->redirect.len++;
- ctx->cache = ngx_http_cache_alloc(ilcf->index_cache, ctx->cache,
- NULL, &r->uri, crc,
- &ctx->redirect, log);
- ctx->redirect.len--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http index cache alloc: %p", ctx->cache);
-
- if (ctx->cache) {
- ctx->cache->fd = NGX_INVALID_FILE;
- ctx->cache->accessed = ngx_cached_time;
- ctx->cache->last_modified = 0;
- ctx->cache->updated = ngx_cached_time;
- ctx->cache->memory = 1;
- ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
- }
+ ctx->index.data = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len);
+
+ } else {
+ ctx->path = ngx_palloc(r->pool,
+ clcf->root.len + r->uri.len - clcf->name.len + size);
+ if (ctx->path == NULL) {
+ return NGX_ERROR;
}
-#endif
+ ctx->uri.data = ngx_palloc(r->pool, r->uri.len + size);
+ if (ctx->uri.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(ctx->path, clcf->root.data, clcf->root.len);
- return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
+ ctx->index.data = ngx_cpymem(ctx->path + clcf->root.len,
+ r->uri.data + clcf->name.len,
+ r->uri.len - clcf->name.len);
}
- return NGX_DECLINED;
+ return NGX_OK;
}
-static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx)
+static ngx_int_t
+ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx)
{
- ngx_err_t err;
+ ngx_err_t err;
+ ngx_file_info_t fi;
- ctx->path.data[ctx->path.len - 1] = '\0';
- ctx->path.data[ctx->path.len] = '\0';
+ *(ctx->index.data - 1) = '\0';
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http check dir: \"%s\"", ctx->path.data);
+ "http index check dir: \"%s\"", ctx->path);
- if (ngx_file_info(ctx->path.data, &r->file.info) == -1) {
+ if (ngx_file_info(ctx->path, &fi) == -1) {
err = ngx_errno;
if (err == NGX_ENOENT) {
- ctx->path.data[ctx->path.len - 1] = '/';
+ *(ctx->index.data - 1) = '/';
return ngx_http_index_error(r, ctx, err);
}
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_file_info_n " \"%s\" failed", ctx->path.data);
+ ngx_file_info_n " \"%s\" failed", ctx->path);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- ctx->path.data[ctx->path.len - 1] = '/';
+ *(ctx->index.data - 1) = '/';
- if (ngx_is_dir(&r->file.info)) {
+ if (ngx_is_dir(&fi)) {
return NGX_OK;
}
- /* THINK: not reached ??? */
- return ngx_http_index_error(r, ctx, 0);
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "\"%s\" is not a directory", ctx->path);
+
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
-static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx, ngx_err_t err)
+static ngx_int_t
+ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx,
+ ngx_err_t err)
{
if (err == NGX_EACCES) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- "\"%s\" is forbidden", ctx->path.data);
+ "\"%s\" is forbidden", ctx->path);
return NGX_HTTP_FORBIDDEN;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- "\"%s\" is not found", ctx->path.data);
- return NGX_HTTP_NOT_FOUND;
-}
+ "\"%s\" is not found", ctx->path);
-
-static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_index_handler;
-
- return NGX_OK;
+ return NGX_HTTP_NOT_FOUND;
}
-static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf)
+static void *
+ngx_http_index_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_index_loc_conf_t *conf;
@@ -441,118 +394,146 @@ static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf)
return NGX_CONF_ERROR;
}
- if (ngx_array_init(&conf->indices, cf->pool, 2, sizeof(ngx_str_t))
- == NGX_ERROR)
- {
- return NGX_CONF_ERROR;
- }
-
- conf->max_index_len = 0;
-
- conf->index_cache = NULL;
+ conf->indices = NULL;
+ conf->max_index_len = 1;
return conf;
}
-/* TODO: remove duplicate indices */
-
-static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child)
+static char *
+ngx_http_index_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_index_loc_conf_t *prev = parent;
ngx_http_index_loc_conf_t *conf = child;
- ngx_str_t *index;
+ ngx_http_index_t *index;
- if (conf->max_index_len == 0) {
- if (prev->max_index_len != 0) {
- ngx_memcpy(conf, prev, sizeof(ngx_http_index_loc_conf_t));
- return NGX_CONF_OK;
+ if (conf->indices == NULL) {
+ conf->indices = prev->indices;
+ conf->max_index_len = prev->max_index_len;
+ }
+
+ if (conf->indices == NULL) {
+ conf->indices = ngx_array_create(cf->pool, 1, sizeof(ngx_http_index_t));
+ if (conf->indices == NULL) {
+ return NGX_CONF_ERROR;
}
- index = ngx_array_push(&conf->indices);
+ index = ngx_array_push(conf->indices);
if (index == NULL) {
return NGX_CONF_ERROR;
}
- index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1;
- index->data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
+ index->name.len = sizeof(NGX_HTTP_DEFAULT_INDEX);
+ index->name.data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
+ index->lengths = NULL;
+ index->values = NULL;
+
conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);
return NGX_CONF_OK;
}
-#if 0
-
- if (prev->max_index_len != 0) {
-
- prev_index = prev->indices.elts;
- for (i = 0; i < prev->indices.nelts; i++) {
- index = ngx_array_push(&conf->indices);
- if (index == NULL) {
- return NGX_CONF_ERROR;
- }
-
- index->len = prev_index[i].len;
- index->data = prev_index[i].data;
- }
- }
-
- if (conf->max_index_len < prev->max_index_len) {
- conf->max_index_len = prev->max_index_len;
- }
-
-#endif
-
- if (conf->index_cache == NULL) {
- conf->index_cache = prev->index_cache;
- }
-
return NGX_CONF_OK;
}
/* TODO: warn about duplicate indices */
-static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
+static char *
+ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_index_loc_conf_t *ilcf = conf;
- ngx_uint_t i;
- ngx_str_t *index, *value;
-
- value = cf->args->elts;
+ ngx_uint_t i, n;
+ ngx_str_t *value;
+ ngx_http_index_t *index;
+ ngx_http_script_compile_t sc;
- if (value[1].data[0] == '/' && ilcf->indices.nelts == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "first index \"%V\" in \"%V\" directive "
- "must not be absolute",
- &value[1], &cmd->name);
- return NGX_CONF_ERROR;
+ if (ilcf->indices == NULL) {
+ ilcf->indices = ngx_array_create(cf->pool, 2, sizeof(ngx_http_index_t));
+ if (ilcf->indices == NULL) {
+ return NGX_CONF_ERROR;
+ }
}
+ value = cf->args->elts;
+
for (i = 1; i < cf->args->nelts; i++) {
+ if (value[i].data[0] == '/' && i != cf->args->nelts - 1) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "only the last index in \"index\" directive "
+ "may be absolute");
+ return NGX_CONF_ERROR;
+ }
+
if (value[i].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "index \"%V\" in \"%V\" directive is invalid",
- &value[1], &cmd->name);
+ "index \"%V\" in \"index\" directive is invalid",
+ &value[1]);
return NGX_CONF_ERROR;
}
- index = ngx_array_push(&ilcf->indices);
+ index = ngx_array_push(ilcf->indices);
if (index == NULL) {
return NGX_CONF_ERROR;
}
- index->len = value[i].len;
- index->data = value[i].data;
+ index->name.len = value[i].len;
+ index->name.data = value[i].data;
+ index->lengths = NULL;
+ index->values = NULL;
+
+ n = ngx_http_script_variables_count(&value[i]);
+
+ if (n == 0) {
+ index->name.len++;
+
+ if (ilcf->max_index_len != 0
+ && ilcf->max_index_len < index->name.len)
+ {
+ ilcf->max_index_len = index->name.len;
+ }
+
+ continue;
+ }
+
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ sc.cf = cf;
+ sc.source = &value[i];
+ sc.lengths = &index->lengths;
+ sc.values = &index->values;
+ sc.variables = n;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
- if (ilcf->max_index_len < index->len + 1) {
- ilcf->max_index_len = index->len + 1;
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
}
+
+ ilcf->max_index_len = 0;
}
return NGX_CONF_OK;
}
+
+
+static ngx_int_t
+ngx_http_index_init(ngx_cycle_t *cycle)
+{
+ ngx_http_handler_pt *h;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
+
+ h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ *h = ngx_http_index_handler;
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c
index 24ea58d90..23ea57215 100644
--- a/src/http/modules/ngx_http_not_modified_filter_module.c
+++ b/src/http/modules/ngx_http_not_modified_filter_module.c
@@ -14,7 +14,8 @@ static ngx_int_t ngx_http_not_modified_filter_init(ngx_cycle_t *cycle);
static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -28,7 +29,7 @@ static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = {
ngx_module_t ngx_http_not_modified_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_not_modified_filter_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -45,6 +46,7 @@ static ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
time_t ims;
if (r->headers_out.status != NGX_HTTP_OK
+ || r->main
|| r->headers_in.if_modified_since == NULL
|| r->headers_out.last_modified_time == -1)
{
@@ -63,12 +65,11 @@ static ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
- r->headers_out.content_type->key.len = 0;
- r->headers_out.content_type = NULL;
+ r->headers_out.content_type.len = 0;
r->headers_out.content_length_n = -1;
r->headers_out.content_length = NULL;
#if 0
- r->headers_out.accept_ranges->key.len = 0;
+ r->headers_out.accept_ranges->hash = 0;
#endif
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 8020856c3..5504610e6 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -10,89 +10,100 @@
#include <ngx_http.h>
+typedef struct ngx_http_proxy_redirect_s ngx_http_proxy_redirect_t;
+
+typedef ngx_int_t (*ngx_http_proxy_redirect_pt)(ngx_http_request_t *r,
+ ngx_table_elt_t *h, size_t prefix, ngx_http_proxy_redirect_t *pr);
+
+struct ngx_http_proxy_redirect_s {
+ ngx_http_proxy_redirect_pt handler;
+ ngx_str_t redirect;
+
+ union {
+ ngx_str_t text;
+
+ struct {
+ void *lengths;
+ void *values;
+ } vars;
+
+ void *regex;
+ } replacement;
+};
+
+
typedef struct {
- ngx_http_upstream_conf_t upstream;
+ ngx_http_upstream_conf_t upstream;
- ngx_peers_t *peers;
+ ngx_peers_t *peers;
- ngx_array_t *headers_set_len;
- ngx_array_t *headers_set;
- ngx_hash_t *headers_set_hash;
+ ngx_array_t *headers_set_len;
+ ngx_array_t *headers_set;
+ ngx_hash_t *headers_set_hash;
- ngx_flag_t preserve_host;
- ngx_flag_t set_x_url;
- ngx_flag_t set_x_real_ip;
- ngx_flag_t add_x_forwarded_for;
- ngx_flag_t pass_server;
- ngx_flag_t pass_x_accel_expires;
+ ngx_array_t *headers_source;
+ ngx_array_t *headers_names;
- ngx_str_t *location0;
+ ngx_array_t *redirects;
- ngx_str_t host_header;
- ngx_str_t uri0;
+ ngx_str_t host_header;
+ ngx_str_t port_text;
- ngx_array_t *headers_sources;
- ngx_array_t *headers_names;
+ ngx_flag_t redirect;
} ngx_http_proxy_loc_conf_t;
typedef struct {
- ngx_list_t headers;
-
- ngx_table_elt_t *date;
- ngx_table_elt_t *server;
+ ngx_uint_t status;
+ ngx_uint_t status_count;
+ u_char *status_start;
+ u_char *status_end;
+} ngx_http_proxy_ctx_t;
- ngx_table_elt_t *expires;
- ngx_table_elt_t *cache_control;
- ngx_table_elt_t *etag;
- ngx_table_elt_t *x_accel_expires;
- 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;
- ngx_table_elt_t *x_pad;
-
- off_t content_length_n;
-} ngx_http_proxy_headers_in_t;
+#define NGX_HTTP_PROXY_PARSE_NO_HEADER 20
static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r);
+static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r);
+static ngx_int_t ngx_http_proxy_parse_status_line(ngx_http_request_t *r,
+ ngx_http_proxy_ctx_t *p);
static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_proxy_send_header(ngx_http_request_t *r);
static void ngx_http_proxy_abort_request(ngx_http_request_t *r);
static void ngx_http_proxy_finalize_request(ngx_http_request_t *r,
ngx_int_t rc);
-static ngx_int_t ngx_http_proxy_compile_header_start(ngx_table_elt_t *h,
- ngx_array_t *lengths, ngx_array_t *values, ngx_uint_t value);
-static ngx_int_t ngx_http_proxy_compile_header_end(ngx_array_t *lengths,
- ngx_array_t *values);
+static ngx_http_variable_value_t *
+ ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data);
+static ngx_http_variable_value_t *
+ ngx_http_proxy_port_variable(ngx_http_request_t *r, uintptr_t data);
+static ngx_http_variable_value_t *
+ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
+ uintptr_t data);
+static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
+ ngx_table_elt_t *h, size_t prefix);
-static ngx_int_t ngx_http_proxy_init(ngx_cycle_t *cycle);
-static ngx_http_variable_value_t *ngx_http_proxy_host_variable
- (ngx_http_request_t *r, uintptr_t data);
+static ngx_int_t ngx_http_proxy_add_variables(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);
static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-
-static char *ngx_http_proxy_set_x_var(ngx_conf_t *cf, ngx_command_t *cmd,
+static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
+
static ngx_conf_post_t ngx_http_proxy_lowat_post =
- { ngx_http_proxy_lowat_check };
+ { ngx_http_proxy_lowat_check };
+
+static ngx_conf_enum_t ngx_http_proxy_set_methods[] = {
+ { ngx_string("get"), NGX_HTTP_GET },
+ { ngx_null_string, 0 }
+};
static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
@@ -113,6 +124,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
0,
NULL },
+ { ngx_string("proxy_redirect"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
+ ngx_http_proxy_redirect,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("proxy_connect_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -134,46 +152,46 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, upstream.send_lowat),
&ngx_http_proxy_lowat_post },
- { ngx_string("proxy_pass_unparsed_uri"),
+ { ngx_string("proxy_redirect_errors"),
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_proxy_loc_conf_t, upstream.pass_unparsed_uri),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.redirect_errors),
NULL },
- { ngx_string("proxy_preserve_host"),
+ { ngx_string("proxy_pass_unparsed_uri"),
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_proxy_loc_conf_t, preserve_host),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_unparsed_uri),
NULL },
- { ngx_string("proxy_set_x_url"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
+ { ngx_string("proxy_set_header"),
+ 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,
- offsetof(ngx_http_proxy_loc_conf_t, set_x_url),
+ offsetof(ngx_http_proxy_loc_conf_t, headers_source),
NULL },
- { ngx_string("proxy_set_x_real_ip"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
+ { ngx_string("proxy_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_proxy_loc_conf_t, set_x_real_ip),
- NULL },
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.method),
+ ngx_http_proxy_set_methods },
- { ngx_string("proxy_set_x_var"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_proxy_set_x_var,
+ { ngx_string("proxy_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,
- 0,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_headers),
NULL },
- { ngx_string("proxy_add_x_forwarded_for"),
+ { ngx_string("proxy_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_proxy_loc_conf_t, add_x_forwarded_for),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_body),
NULL },
{ ngx_string("proxy_header_buffer_size"),
@@ -232,18 +250,25 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream),
&ngx_http_proxy_next_upstream_masks },
+ { ngx_string("proxy_pass_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_proxy_loc_conf_t, upstream.pass_x_powered_by),
+ NULL },
+
{ ngx_string("proxy_pass_server"),
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_proxy_loc_conf_t, pass_server),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_server),
NULL },
{ ngx_string("proxy_pass_x_accel_expires"),
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_proxy_loc_conf_t, pass_x_accel_expires),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_x_accel_expires),
NULL },
ngx_null_command
@@ -251,7 +276,8 @@ static ngx_command_t ngx_http_proxy_commands[] = {
ngx_http_module_t ngx_http_proxy_module_ctx = {
- NULL, /* pre conf */
+ ngx_http_proxy_add_variables, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -265,68 +291,53 @@ ngx_http_module_t ngx_http_proxy_module_ctx = {
ngx_module_t ngx_http_proxy_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_proxy_module_ctx, /* module context */
ngx_http_proxy_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
- ngx_http_proxy_init, /* init module */
+ NULL, /* init module */
NULL /* init process */
};
static ngx_str_t ngx_http_proxy_methods[] = {
- ngx_string("GET"),
- ngx_string("HEAD"),
- ngx_string("POST")
+ ngx_string("GET "),
+ ngx_string("HEAD "),
+ ngx_string("POST ")
};
static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF;
-static ngx_str_t ngx_http_proxy_host = ngx_string("PROXY_HOST");
+static ngx_table_elt_t ngx_http_proxy_headers[] = {
+ { 0, ngx_string("Host"), ngx_string("$proxy_host"), },
+ { 0, ngx_string("Connection"), ngx_string("close"), },
+ { 0, ngx_null_string, ngx_null_string }
+};
-#if (NGX_PCRE)
-static ngx_str_t ngx_http_proxy_uri = ngx_string("/");
-#endif
+static ngx_http_variable_t ngx_http_proxy_vars[] = {
-#if 0
+ { ngx_string("proxy_host"), ngx_http_proxy_host_variable, 0,
+ NGX_HTTP_VAR_CHANGABLE },
-ngx_http_header_t ngx_http_proxy_headers_in[] = {
- { ngx_string("Date"), offsetof(ngx_http_proxy_headers_in_t, date) },
- { ngx_string("Server"), offsetof(ngx_http_proxy_headers_in_t, server) },
-
- { ngx_string("Expires"), offsetof(ngx_http_proxy_headers_in_t, expires) },
- { ngx_string("Cache-Control"),
- offsetof(ngx_http_proxy_headers_in_t, cache_control) },
- { ngx_string("ETag"), offsetof(ngx_http_proxy_headers_in_t, etag) },
- { ngx_string("X-Accel-Expires"),
- offsetof(ngx_http_proxy_headers_in_t, x_accel_expires) },
-
- { ngx_string("Connection"),
- offsetof(ngx_http_proxy_headers_in_t, connection) },
- { ngx_string("Content-Type"),
- 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("proxy_port"), ngx_http_proxy_port_variable, 0,
+ NGX_HTTP_VAR_CHANGABLE },
+
+ { ngx_string("proxy_add_x_forwarded_for"),
+ ngx_http_proxy_add_x_forwarded_for_variable, 0, 0 },
- { ngx_string("Last-Modified"),
- offsetof(ngx_http_proxy_headers_in_t, last_modified) },
- { ngx_string("Location"),
- offsetof(ngx_http_proxy_headers_in_t, location) },
- { ngx_string("Accept-Ranges"),
- offsetof(ngx_http_proxy_headers_in_t, accept_ranges) },
- { ngx_string("X-Pad"), offsetof(ngx_http_proxy_headers_in_t, x_pad) },
+#if 0
+ { ngx_string("proxy_add_via"), NULL, 0, 0 },
+#endif
- { ngx_null_string, 0 }
+ { ngx_null_string, NULL, 0, 0 }
};
+
+#if (NGX_PCRE)
+static ngx_str_t ngx_http_proxy_uri = ngx_string("/");
#endif
@@ -358,20 +369,17 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
u->create_request = ngx_http_proxy_create_request;
u->reinit_request = ngx_http_proxy_reinit_request;
- u->process_header = ngx_http_proxy_process_header;
- u->send_header = ngx_http_proxy_send_header;
+ u->process_header = ngx_http_proxy_process_status_line;
u->abort_request = ngx_http_proxy_abort_request;
u->finalize_request = ngx_http_proxy_finalize_request;
- u->pipe.input_filter = ngx_event_pipe_copy_input_filter;
+ if (plcf->redirects) {
+ u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
+ }
- u->log_ctx = r->connection->log->data;
- u->log_handler = ngx_http_upstream_log_error;
+ u->pipe.input_filter = ngx_event_pipe_copy_input_filter;
- u->schema0.len = sizeof("http://") - 1;
- u->schema0.data = (u_char *) "http://";
- u->uri0 = plcf->uri0;
- u->location0 = plcf->location0;
+ u->accel = 1;
r->upstream = u;
@@ -388,19 +396,19 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
static ngx_int_t
ngx_http_proxy_create_request(ngx_http_request_t *r)
{
- size_t len;
- ngx_uint_t i, key;
- uintptr_t escape;
- ngx_buf_t *b;
- ngx_str_t *hh;
- ngx_chain_t *cl;
- ngx_list_part_t *part;
- ngx_table_elt_t *header;
- ngx_http_upstream_t *u;
- ngx_http_proxy_loc_conf_t *plcf;
- ngx_http_script_code_pt code;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_lite_engine_t e;
+ size_t len, loc_len;
+ ngx_uint_t i, key;
+ uintptr_t escape;
+ ngx_buf_t *b;
+ ngx_str_t *hh;
+ ngx_chain_t *cl, *body;
+ ngx_list_part_t *part;
+ ngx_table_elt_t *header;
+ ngx_http_upstream_t *u;
+ ngx_http_script_code_pt code;
+ ngx_http_script_engine_t e, le;
+ ngx_http_proxy_loc_conf_t *plcf;
+ ngx_http_script_len_code_pt lcode;
u = r->upstream;
@@ -409,65 +417,73 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
len = sizeof(ngx_http_proxy_version) - 1 + sizeof(CRLF) - 1;
if (u->method) {
- len += ngx_http_proxy_methods[u->method - 1].len + u->uri0.len;
+ len += ngx_http_proxy_methods[u->method - 1].len + u->conf->uri.len;
} else {
- len += r->method_name.len + u->uri0.len;
+ len += r->method_name.len + 1 + u->conf->uri.len;
}
escape = 0;
-
+
+ loc_len = r->valid_location ? u->conf->location->len : 1;
+
if (plcf->upstream.pass_unparsed_uri && r->valid_unparsed_uri) {
len += r->unparsed_uri.len - 1;
} else {
if (r->quoted_uri) {
- escape = 2 * ngx_escape_uri(NULL, r->uri.data + u->location0->len,
- r->uri.len - u->location0->len,
- NGX_ESCAPE_URI);
+ escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
+ r->uri.len - loc_len, NGX_ESCAPE_URI);
}
- len += r->uri.len - u->location0->len + escape
- + sizeof("?") - 1 + r->args.len;
+ len += r->uri.len - loc_len + escape + sizeof("?") - 1 + r->args.len;
}
+ ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
- e.ip = plcf->headers_set_len->elts;
- e.request = r;
+ le.ip = plcf->headers_set_len->elts;
+ le.request = r;
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
+ while (*(uintptr_t *) le.ip) {
+ while (*(uintptr_t *) le.ip) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ len += lcode(&le);
+ }
+ le.ip += sizeof(uintptr_t);
}
- part = &r->headers_in.headers.part;
- header = part->elts;
hh = (ngx_str_t *) plcf->headers_set_hash->buckets;
- for (i = 0; /* void */; i++) {
+ if (plcf->upstream.pass_request_headers) {
+ part = &r->headers_in.headers.part;
+ header = part->elts;
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
+ for (i = 0; /* void */; i++) {
+
+ 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;
- }
+ key = header[i].hash % plcf->headers_set_hash->hash_size;
- key = header[i].hash % plcf->headers_set_hash->hash_size;
+ if (hh[key].len == header[i].key.len
+ && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
+ {
+ continue;
+ }
- if (hh[key].len == header[i].key.len
- && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
- {
- continue;
+ len += header[i].key.len + sizeof(": ") - 1
+ + header[i].value.len + sizeof(CRLF) - 1;
}
-
- len += header[i].key.len + sizeof(": ") - 1
- + header[i].value.len + sizeof(CRLF) - 1;
}
+
b = ngx_create_temp_buf(r->pool, len);
if (b == NULL) {
return NGX_ERROR;
@@ -479,9 +495,6 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
}
cl->buf = b;
- cl->next = NULL;
-
- r->request_body->bufs = cl;
/* the request line */
@@ -491,23 +504,24 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
ngx_http_proxy_methods[u->method - 1].data,
ngx_http_proxy_methods[u->method - 1].len);
} else {
- b->last = ngx_cpymem(b->last, r->method_name.data, r->method_name.len);
+ b->last = ngx_cpymem(b->last, r->method_name.data,
+ r->method_name.len + 1);
}
- b->last = ngx_cpymem(b->last, u->uri0.data, u->uri0.len);
+ b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len);
if (plcf->upstream.pass_unparsed_uri && r->valid_unparsed_uri) {
b->last = ngx_cpymem(b->last, r->unparsed_uri.data + 1,
r->unparsed_uri.len - 1);
} else {
if (escape) {
- ngx_escape_uri(b->last, r->uri.data + u->location0->len,
- r->uri.len - u->location0->len, NGX_ESCAPE_URI);
- b->last += r->uri.len - u->location0->len + escape;
+ ngx_escape_uri(b->last, r->uri.data + loc_len,
+ r->uri.len - loc_len, NGX_ESCAPE_URI);
+ b->last += r->uri.len - loc_len + escape;
} else {
- b->last = ngx_cpymem(b->last, r->uri.data + u->location0->len,
- r->uri.len - u->location0->len);
+ b->last = ngx_cpymem(b->last, r->uri.data + loc_len,
+ r->uri.len - loc_len);
}
if (r->args.len > 0) {
@@ -522,50 +536,76 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
e.ip = plcf->headers_set->elts;
e.pos = b->last;
+ e.request = r;
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
+ le.ip = plcf->headers_set_len->elts;
+
+ while (*(uintptr_t *) le.ip) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ lcode(&le);
+
+ if (*(ngx_http_script_len_code_pt *) le.ip) {
+
+ for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ }
+
+ e.skip = (len == sizeof(CRLF) - 1) ? 1 : 0;
+
+ } else {
+ e.skip = 0;
+ }
+
+ le.ip += sizeof(uintptr_t);
+
+ 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 = e.pos;
- part = &r->headers_in.headers.part;
- header = part->elts;
+ if (plcf->upstream.pass_request_headers) {
+ 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;
+ }
- key = header[i].hash % plcf->headers_set_hash->hash_size;
+ key = header[i].hash % plcf->headers_set_hash->hash_size;
- if (hh[key].len == header[i].key.len
- && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
- {
- continue;
- }
+ if (hh[key].len == header[i].key.len
+ && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
+ {
+ continue;
+ }
- b->last = ngx_cpymem(b->last, header[i].key.data, header[i].key.len);
+ b->last = ngx_cpymem(b->last, header[i].key.data,
+ header[i].key.len);
- *b->last++ = ':'; *b->last++ = ' ';
+ *b->last++ = ':'; *b->last++ = ' ';
- 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);
- *b->last++ = CR; *b->last++ = LF;
+ *b->last++ = CR; *b->last++ = LF;
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy header: \"%V: %V\"",
- &header[i].key, &header[i].value);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http proxy header: \"%V: %V\"",
+ &header[i].key, &header[i].value);
+ }
}
/* add "\r\n" at the header end */
@@ -582,6 +622,36 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
}
#endif
+ if (plcf->upstream.pass_request_body) {
+
+ body = u->request_bufs;
+ u->request_bufs = cl;
+
+ while (body) {
+ b = ngx_alloc_buf(r->pool);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
+
+ cl->next = ngx_alloc_chain_link(r->pool);
+ if (cl->next == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl = cl->next;
+ cl->buf = b;
+
+ body = body->next;
+ }
+
+ } else {
+ u->request_bufs = cl;
+ }
+
+ cl->next = NULL;
+
return NGX_OK;
}
@@ -589,24 +659,369 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
static ngx_int_t
ngx_http_proxy_reinit_request(ngx_http_request_t *r)
{
+ ngx_http_proxy_ctx_t *p;
+
+ p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
+
+ if (p == NULL) {
+ return NGX_OK;
+ }
+
+ p->status = 0;
+ p->status_count = 0;
+ p->status_start = NULL;
+ p->status_end = NULL;
+
+ r->upstream->process_header = ngx_http_proxy_process_status_line;
+
return NGX_OK;
}
static ngx_int_t
-ngx_http_proxy_process_header(ngx_http_request_t *r)
+ngx_http_proxy_process_status_line(ngx_http_request_t *r)
{
- return NGX_OK;
+ ngx_int_t rc;
+ ngx_http_upstream_t *u;
+ ngx_http_proxy_ctx_t *p;
+
+ p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
+
+ if (p == NULL) {
+ p = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t));
+ if (p == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ngx_http_set_ctx(r, p, ngx_http_proxy_module);
+ }
+
+ rc = ngx_http_proxy_parse_status_line(r, p);
+
+ if (rc == NGX_AGAIN) {
+ return rc;
+ }
+
+ u = r->upstream;
+
+ if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent no valid HTTP/1.0 header");
+
+ if (u->accel) {
+ return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ }
+
+ r->http_version = NGX_HTTP_VERSION_9;
+ p->status = NGX_HTTP_OK;
+
+ return NGX_OK;
+ }
+
+ r->headers_out.status = p->status;
+ u->state->status = p->status;
+
+ r->headers_out.status_line.len = p->status_end - p->status_start;
+ r->headers_out.status_line.data = ngx_palloc(r->pool,
+ r->headers_out.status_line.len);
+ if (r->headers_out.status_line.data == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+ ngx_memcpy(r->headers_out.status_line.data, p->status_start,
+ r->headers_out.status_line.len);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http proxy status %ui \"%V\"",
+ r->headers_out.status, &r->headers_out.status_line);
+
+ u->process_header = ngx_http_proxy_process_header;
+
+ return ngx_http_proxy_process_header(r);
}
static ngx_int_t
-ngx_http_proxy_send_header(ngx_http_request_t *r)
+ngx_http_proxy_parse_status_line(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p)
{
+ u_char ch;
+ u_char *pos;
+ ngx_http_upstream_t *u;
+ enum {
+ sw_start = 0,
+ sw_H,
+ sw_HT,
+ sw_HTT,
+ sw_HTTP,
+ sw_first_major_digit,
+ sw_major_digit,
+ sw_first_minor_digit,
+ sw_minor_digit,
+ sw_status,
+ sw_space_after_status,
+ sw_status_text,
+ sw_almost_done
+ } state;
+
+ u = r->upstream;
+
+ state = r->state;
+
+ for (pos = u->header_in.pos; pos < u->header_in.last; pos++) {
+ ch = *pos;
+
+ switch (state) {
+
+ /* "HTTP/" */
+ case sw_start:
+ switch (ch) {
+ case 'H':
+ state = sw_H;
+ break;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ break;
+
+ case sw_H:
+ switch (ch) {
+ case 'T':
+ state = sw_HT;
+ break;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ break;
+
+ case sw_HT:
+ switch (ch) {
+ case 'T':
+ state = sw_HTT;
+ break;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ break;
+
+ case sw_HTT:
+ switch (ch) {
+ case 'P':
+ state = sw_HTTP;
+ break;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ break;
+
+ case sw_HTTP:
+ switch (ch) {
+ case '/':
+ state = sw_first_major_digit;
+ break;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ break;
+
+ /* the first digit of major HTTP version */
+ case sw_first_major_digit:
+ if (ch < '1' || ch > '9') {
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+
+ state = sw_major_digit;
+ break;
+
+ /* the major HTTP version or dot */
+ case sw_major_digit:
+ if (ch == '.') {
+ state = sw_first_minor_digit;
+ break;
+ }
+
+ if (ch < '0' || ch > '9') {
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+
+ break;
+
+ /* the first digit of minor HTTP version */
+ case sw_first_minor_digit:
+ if (ch < '0' || ch > '9') {
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+
+ state = sw_minor_digit;
+ break;
+
+ /* the minor HTTP version or the end of the request line */
+ case sw_minor_digit:
+ if (ch == ' ') {
+ state = sw_status;
+ break;
+ }
+
+ if (ch < '0' || ch > '9') {
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+
+ break;
+
+ /* HTTP status code */
+ case sw_status:
+ if (ch < '0' || ch > '9') {
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+
+ p->status = p->status * 10 + ch - '0';
+
+ if (++p->status_count == 3) {
+ state = sw_space_after_status;
+ p->status_start = pos - 2;
+ }
+
+ break;
+
+ /* space or end of line */
+ case sw_space_after_status:
+ switch (ch) {
+ case ' ':
+ state = sw_status_text;
+ break;
+ case '.': /* IIS may send 403.1, 403.2, etc */
+ state = sw_status_text;
+ break;
+ case CR:
+ state = sw_almost_done;
+ break;
+ case LF:
+ goto done;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ break;
+
+ /* any text until end of line */
+ case sw_status_text:
+ switch (ch) {
+ case CR:
+ state = sw_almost_done;
+
+ break;
+ case LF:
+ goto done;
+ }
+ break;
+
+ /* end of request line */
+ case sw_almost_done:
+ p->status_end = pos - 1;
+ switch (ch) {
+ case LF:
+ goto done;
+ default:
+ return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+ }
+ }
+ }
+
+ u->header_in.pos = pos + 1;
+ r->state = state;
+
+ return NGX_AGAIN;
+
+done:
+
+ u->header_in.pos = pos + 1;
+
+ if (p->status_end == NULL) {
+ p->status_end = pos;
+ }
+
+ r->state = sw_start;
+
return NGX_OK;
}
+static ngx_int_t
+ngx_http_proxy_process_header(ngx_http_request_t *r)
+{
+ ngx_int_t rc;
+ ngx_uint_t key;
+ ngx_table_elt_t *h;
+ ngx_http_upstream_header_t *hh;
+ ngx_http_upstream_main_conf_t *umcf;
+
+ umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
+ hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
+
+ for ( ;; ) {
+
+ rc = ngx_http_parse_header_line(r, &r->upstream->header_in);
+
+ if (rc == NGX_OK) {
+
+ /* a header line has been parsed successfully */
+
+ h = ngx_list_push(&r->upstream->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;
+
+ 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);
+
+ key = h->hash % umcf->headers_in_hash.hash_size;
+
+ 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;
+ }
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http proxy 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 proxy header done");
+
+ return NGX_OK;
+ }
+
+ /* 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;
+ }
+}
+
+
static void
ngx_http_proxy_abort_request(ngx_http_request_t *r)
{
@@ -627,57 +1042,222 @@ ngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
}
-static ngx_int_t
-ngx_http_proxy_init(ngx_cycle_t *cycle)
+static ngx_http_variable_value_t *
+ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data)
{
-#if 0
- ngx_http_variable_t *var;
+ ngx_http_variable_value_t *vv;
+ ngx_http_proxy_loc_conf_t *plcf;
- var = ngx_http_add_variable(cf, &ngx_http_proxy_host, 1);
- if (var == NULL) {
- return NGX_ERROR;
+ vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+ if (vv == NULL) {
+ return NULL;
}
- var->handler = ngx_http_proxy_host_variable;
-#endif
+ plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
- return NGX_OK;
+ vv->value = 0;
+ vv->text = plcf->host_header;
-#if 0
- ngx_http_log_op_name_t *op;
+ return vv;
+}
- for (op = ngx_http_proxy_log_fmt_ops; op->name.len; op++) { /* void */ }
- op->run = NULL;
- for (op = ngx_http_log_fmt_ops; op->run; op++) {
- if (op->name.len == 0) {
- op = (ngx_http_log_op_name_t *) op->run;
- }
+static ngx_http_variable_value_t *
+ngx_http_proxy_port_variable(ngx_http_request_t *r, uintptr_t data)
+{
+ ngx_http_variable_value_t *vv;
+ ngx_http_proxy_loc_conf_t *plcf;
+
+ vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+ if (vv == NULL) {
+ return NULL;
}
- op->run = (ngx_http_log_op_run_pt) ngx_http_proxy_log_fmt_ops;
+ plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
+
+ vv->value = 0;
+ vv->text = plcf->port_text;
-#endif
+ return vv;
}
static ngx_http_variable_value_t *
-ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data)
+ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
+ uintptr_t data)
{
- ngx_http_variable_value_t *var;
- ngx_http_proxy_loc_conf_t *plcf;
+ u_char *p;
+ ngx_http_variable_value_t *vv;
- var = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
- if (var == NULL) {
+ vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+ if (vv == NULL) {
return NULL;
}
+ vv->value = 0;
+
+ if (r->headers_in.x_forwarded_for == NULL) {
+ vv->text = r->connection->addr_text;
+ return vv;
+ }
+
+ vv->text.len = r->headers_in.x_forwarded_for->value.len
+ + sizeof(", ") - 1 + r->connection->addr_text.len;
+
+ p = ngx_palloc(r->pool, vv->text.len);
+ if (p == NULL) {
+ return NULL;
+ }
+
+ vv->text.data = p;
+
+ p = ngx_cpymem(p, r->headers_in.x_forwarded_for->value.data,
+ r->headers_in.x_forwarded_for->value.len);
+
+ *p++ = ','; *p++ = ' ';
+
+ ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
+
+ return vv;
+}
+
+
+static ngx_int_t
+ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
+ size_t prefix)
+{
+ ngx_int_t rc;
+ ngx_uint_t i;
+ ngx_http_proxy_loc_conf_t *plcf;
+ ngx_http_proxy_redirect_t *pr;
+
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
- var->value = 0;
- var->text = plcf->host_header;
+ pr = plcf->redirects->elts;
+
+ if (pr == NULL) {
+ return NGX_DECLINED;
+ }
+
+ for (i = 0; i < plcf->redirects->nelts; i++) {
+ rc = pr->handler(r, h, prefix, pr);
- return var;
+ if (rc != NGX_DECLINED) {
+ return rc;
+ }
+ }
+
+ return NGX_DECLINED;
+}
+
+
+static ngx_int_t
+ngx_http_proxy_rewrite_redirect_text(ngx_http_request_t *r, ngx_table_elt_t *h,
+ size_t prefix, ngx_http_proxy_redirect_t *pr)
+{
+ size_t len;
+ u_char *data, *p;
+
+ if (pr->redirect.len > h->value.len - prefix
+ || ngx_rstrncmp(h->value.data + prefix, pr->redirect.data,
+ pr->redirect.len) != 0)
+ {
+ return NGX_DECLINED;
+ }
+
+ len = prefix + pr->replacement.text.len + h->value.len - pr->redirect.len;
+
+ data = ngx_palloc(r->pool, len);
+ if (data == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = data;
+
+ if (prefix) {
+ p = ngx_cpymem(p, h->value.data, prefix);
+ }
+
+ p = ngx_cpymem(p, pr->replacement.text.data, pr->replacement.text.len);
+
+ ngx_memcpy(p, h->value.data + prefix + pr->redirect.len,
+ h->value.len - pr->redirect.len - prefix);
+
+ h->value.len = len;
+ h->value.data = data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_proxy_rewrite_redirect_vars(ngx_http_request_t *r, ngx_table_elt_t *h,
+ size_t prefix, ngx_http_proxy_redirect_t *pr)
+{
+ size_t len;
+ u_char *data, *p;
+ ngx_http_script_code_pt code;
+ ngx_http_script_engine_t e;
+ ngx_http_script_len_code_pt lcode;
+
+ if (pr->redirect.len > h->value.len - prefix
+ || ngx_rstrncmp(h->value.data + prefix, pr->redirect.data,
+ pr->redirect.len) != 0)
+ {
+ return NGX_DECLINED;
+ }
+
+ ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
+
+ e.ip = pr->replacement.vars.lengths;
+ e.request = r;
+
+ for (len = prefix; *(uintptr_t *) e.ip; len += lcode(&e)) {
+ lcode = *(ngx_http_script_len_code_pt *) e.ip;
+ }
+
+ data = ngx_palloc(r->pool, len);
+ if (data == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = data;
+
+ if (prefix) {
+ p = ngx_cpymem(p, h->value.data, prefix);
+ }
+
+ e.ip = pr->replacement.vars.values;
+ e.pos = p;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code(&e);
+ }
+
+ h->value.len = len;
+ h->value.data = data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_proxy_add_variables(ngx_conf_t *cf)
+{
+ ngx_http_variable_t *var, *v;
+
+ for (v = ngx_http_proxy_vars; v->name.len; v++) {
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->handler = v->handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
}
@@ -698,6 +1278,15 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.path = NULL;
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
+ * conf->upstream.schema = { 0, NULL };
+ * conf->upstream.uri = { 0, NULL };
+ * conf->upstream.location = NULL;
+ *
+ * conf->headers_source = NULL;
+ * conf->headers_set_len = NULL;
+ * conf->headers_set = NULL;
+ * conf->headers_set_hash = NULL;
+ * conf->rewrite_locations = NULL;
*/
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
@@ -709,21 +1298,23 @@ ngx_http_proxy_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.pass_unparsed_uri = 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;
- conf->upstream.pass_unparsed_uri = NGX_CONF_UNSET;
- conf->upstream.x_powered_by = NGX_CONF_UNSET;
/* "proxy_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
- conf->preserve_host = NGX_CONF_UNSET;
- conf->set_x_url = NGX_CONF_UNSET;
- conf->set_x_real_ip = NGX_CONF_UNSET;
- conf->add_x_forwarded_for = NGX_CONF_UNSET;
+ conf->upstream.pass_x_powered_by = NGX_CONF_UNSET;
+ conf->upstream.pass_server = NGX_CONF_UNSET;
+ conf->upstream.pass_date = 0;
+ conf->upstream.pass_x_accel_expires = NGX_CONF_UNSET;
- conf->pass_server = NGX_CONF_UNSET;
- conf->pass_x_accel_expires = NGX_CONF_UNSET;
+ conf->redirect = NGX_CONF_UNSET;
return conf;
}
@@ -735,11 +1326,16 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_proxy_loc_conf_t *prev = parent;
ngx_http_proxy_loc_conf_t *conf = child;
- size_t size;
- ngx_str_t *name;
- ngx_table_elt_t *src;
- ngx_http_variable_t *var;
-
+ u_char *p;
+ size_t size;
+ uintptr_t *code;
+ ngx_str_t *name;
+ ngx_uint_t i;
+ ngx_table_elt_t *src, *s, *h;
+ ngx_http_proxy_redirect_t *pr;
+ 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);
@@ -841,241 +1437,297 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|NGX_HTTP_UPSTREAM_FT_ERROR
|NGX_HTTP_UPSTREAM_FT_TIMEOUT));
- ngx_conf_merge_msec_value(conf->upstream.redirect_errors,
- prev->upstream.redirect_errors, 0);
+ ngx_conf_merge_path_value(conf->upstream.temp_path,
+ prev->upstream.temp_path,
+ NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
+ ngx_garbage_collector_temp_handler, cf);
ngx_conf_merge_msec_value(conf->upstream.pass_unparsed_uri,
prev->upstream.pass_unparsed_uri, 0);
- if (conf->upstream.pass_unparsed_uri && conf->location0->len > 1) {
+ if (conf->upstream.pass_unparsed_uri && conf->upstream.location->len > 1) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"\"proxy_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_msec_value(conf->upstream.redirect_errors,
+ prev->upstream.redirect_errors, 0);
+
+ ngx_conf_merge_msec_value(conf->upstream.pass_x_powered_by,
+ prev->upstream.pass_x_powered_by, 1);
+ ngx_conf_merge_msec_value(conf->upstream.pass_server,
+ prev->upstream.pass_server, 0);
+ ngx_conf_merge_msec_value(conf->upstream.pass_x_accel_expires,
+ prev->upstream.pass_x_accel_expires, 0);
+
+
+ ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
+
+ if (conf->redirect) {
+
+ if (conf->redirects == NULL) {
+ conf->redirects = prev->redirects;
+ }
+
+ if (conf->redirects == NULL && conf->upstream.url.data) {
+
+ conf->redirects = ngx_array_create(cf->pool, 1,
+ sizeof(ngx_http_proxy_redirect_t));
+ if (conf->redirects == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ pr = ngx_array_push(conf->redirects);
+ if (pr == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ pr->handler = ngx_http_proxy_rewrite_redirect_text;
+ pr->redirect = conf->upstream.url;
+ pr->replacement.text = *conf->upstream.location;
+ }
+ }
- ngx_conf_merge_value(conf->preserve_host, prev->preserve_host, 0);
- ngx_conf_merge_value(conf->set_x_url, prev->set_x_url, 0);
- ngx_conf_merge_value(conf->set_x_real_ip, prev->set_x_real_ip, 0);
- ngx_conf_merge_value(conf->add_x_forwarded_for,
- prev->add_x_forwarded_for, 0);
if (conf->peers == NULL) {
conf->peers = prev->peers;
conf->upstream = prev->upstream;
}
- if (conf->headers_set_hash == NULL) {
+ if (conf->headers_source == NULL) {
+ conf->headers_source = prev->headers_source;
conf->headers_set_len = prev->headers_set_len;
conf->headers_set = prev->headers_set;
conf->headers_set_hash = prev->headers_set_hash;
}
- if (conf->headers_set_hash == NULL) {
+ if (conf->headers_set_hash) {
+ return NGX_CONF_OK;
+ }
- if (conf->headers_names == NULL) {
- conf->headers_names = ngx_array_create(cf->pool, 4,
- sizeof(ngx_str_t));
- if (conf->headers_names == NULL) {
- return NGX_CONF_ERROR;
- }
- }
- if (conf->headers_sources == NULL) {
- conf->headers_sources = ngx_array_create(cf->pool, 4,
- sizeof(ngx_table_elt_t));
- if (conf->headers_sources == NULL) {
- return NGX_CONF_ERROR;
- }
- }
+ conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
+ if (conf->headers_names == NULL) {
+ return NGX_CONF_ERROR;
+ }
- /* STUB */
- var = ngx_http_add_variable(cf, &ngx_http_proxy_host, 0);
- if (var == NULL) {
+ if (conf->headers_source == NULL) {
+ conf->headers_source = ngx_array_create(cf->pool, 4,
+ sizeof(ngx_table_elt_t));
+ if (conf->headers_source == NULL) {
return NGX_CONF_ERROR;
}
+ }
- var->handler = ngx_http_proxy_host_variable;
- /**/
+ conf->headers_set_len = ngx_array_create(cf->pool, 64, 1);
+ if (conf->headers_set_len == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ conf->headers_set = ngx_array_create(cf->pool, 512, 1);
+ if (conf->headers_set == NULL) {
+ return NGX_CONF_ERROR;
+ }
- name = ngx_array_push(conf->headers_names);
- if (name == NULL) {
- return NGX_CONF_ERROR;
- }
- name->len = sizeof("Host") - 1;
- name->data = (u_char *) "Host";
+ src = conf->headers_source->elts;
- src = ngx_array_push(conf->headers_sources);
- if (src == NULL) {
+ for (h = ngx_http_proxy_headers; h->key.len; h++) {
+
+ for (i = 0; i < conf->headers_source->nelts; i++) {
+ if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
+ goto next;
+ }
+ }
+
+ s = ngx_array_push(conf->headers_source);
+ if (s == NULL) {
return NGX_CONF_ERROR;
}
- src->hash = 0;
- src->key.len = sizeof("Host") - 1;
- src->key.data = (u_char *) "Host";
- src->value.len = sizeof("$PROXY_HOST") - 1;
- src->value.data = (u_char *) "$PROXY_HOST";
+ *s = *h;
+ next:
+
+ continue;
+ }
+
+ for (i = 0; i < conf->headers_source->nelts; i++) {
name = ngx_array_push(conf->headers_names);
if (name == NULL) {
return NGX_CONF_ERROR;
}
- name->len = sizeof("Connection") - 1;
- name->data = (u_char *) "Connection";
+ *name = src[i].key;
- src = ngx_array_push(conf->headers_sources);
- if (src == NULL) {
- return NGX_CONF_ERROR;
- }
+ if (ngx_http_script_variables_count(&src[i].value) == 0) {
+ copy = ngx_array_push_n(conf->headers_set_len,
+ sizeof(ngx_http_script_copy_code_t));
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
- src->hash = 0;
- src->key.len = sizeof("Connection") - 1;
- src->key.data = (u_char *) "Connection";
- src->value.len = sizeof("close") - 1;
- src->value.data = (u_char *) "close";
+ copy->code = (ngx_http_script_code_pt)
+ ngx_http_script_copy_len_code;
+ copy->len = src[i].key.len + sizeof(": ") - 1
+ + src[i].value.len + sizeof(CRLF) - 1;
- name = ngx_array_push(conf->headers_names);
- if (name == NULL) {
- return NGX_CONF_ERROR;
- }
+ size = (sizeof(ngx_http_script_copy_code_t)
+ + src[i].key.len + sizeof(": ") - 1
+ + src[i].value.len + sizeof(CRLF) - 1
+ + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
- name->len = 0;
- name->data = NULL;
+ copy = ngx_array_push_n(conf->headers_set, size);
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ copy->code = ngx_http_script_copy_code;
+ copy->len = src[i].key.len + sizeof(": ") - 1
+ + src[i].value.len + sizeof(CRLF) - 1;
- if (ngx_http_script_compile_lite(cf, conf->headers_sources,
- &conf->headers_set_len, &conf->headers_set,
- ngx_http_proxy_compile_header_start,
- ngx_http_proxy_compile_header_end) != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
+ p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
+ p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
+ *p++ = ':'; *p++ = ' ';
+ p = ngx_cpymem(p, src[i].value.data, src[i].value.len);
+ *p++ = CR; *p = LF;
- conf->headers_set_hash = ngx_pcalloc(cf->pool, sizeof(ngx_hash_t));
- if (conf->headers_set_hash == NULL) {
- return NGX_CONF_ERROR;
- }
+ } else {
+ copy = ngx_array_push_n(conf->headers_set_len,
+ sizeof(ngx_http_script_copy_code_t));
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
- conf->headers_set_hash->max_size = 100;
- conf->headers_set_hash->bucket_limit = 1;
- conf->headers_set_hash->bucket_size = sizeof(ngx_str_t);
- conf->headers_set_hash->name = "proxy_headers";
+ copy->code = (ngx_http_script_code_pt)
+ ngx_http_script_copy_len_code;
+ copy->len = src[i].key.len + sizeof(": ") - 1;
- if (ngx_hash_init(conf->headers_set_hash, cf->pool,
- conf->headers_names->elts) != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-#if 0
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
-#endif
- ngx_log_error(NGX_LOG_NOTICE, cf->log, 0,
- "proxy_headers hash size: %ui, "
- "max buckets per entry: %ui",
- conf->headers_set_hash->hash_size,
- conf->headers_set_hash->min_buckets);
- }
+ size = (sizeof(ngx_http_script_copy_code_t)
+ + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
- return NGX_CONF_OK;
-}
+ copy = ngx_array_push_n(conf->headers_set, size);
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ copy->code = ngx_http_script_copy_code;
+ copy->len = src[i].key.len + sizeof(": ") - 1;
-static ngx_int_t
-ngx_http_proxy_compile_header_start(ngx_table_elt_t *h,
- ngx_array_t *lengths, ngx_array_t *values, ngx_uint_t value)
-{
- u_char *p;
- size_t size;
- ngx_http_script_copy_code_t *copy;
+ p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
+ p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
+ *p++ = ':'; *p = ' ';
- copy = ngx_array_push_n(lengths, sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len;
- copy->len = h->key.len + sizeof(": ") - 1;
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
- if (value) {
- copy->len += h->value.len + sizeof(CRLF) - 1;
- }
+ sc.cf = cf;
+ sc.source = &src[i].value;
+ sc.lengths = &conf->headers_set_len;
+ sc.values = &conf->headers_set;
- size = (copy->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1);
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
- copy = ngx_array_push_n(values,
- sizeof(ngx_http_script_copy_code_t) + size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
- copy->code = ngx_http_script_copy;
- copy->len = h->key.len + sizeof(": ") - 1;
+ copy = ngx_array_push_n(conf->headers_set_len,
+ sizeof(ngx_http_script_copy_code_t));
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
- if (value) {
- copy->len += h->value.len + sizeof(CRLF) - 1;
- }
+ copy->code = (ngx_http_script_code_pt)
+ ngx_http_script_copy_len_code;
+ copy->len = sizeof(CRLF) - 1;
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
- p = ngx_cpymem(p, h->key.data, h->key.len);
- p = ngx_cpymem(p, ": ", sizeof(": ") - 1);
+ size = (sizeof(ngx_http_script_copy_code_t)
+ + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
- if (value) {
- p = ngx_cpymem(p, h->value.data, h->value.len);
- ngx_memcpy(p, CRLF, sizeof(CRLF) - 1);
- }
+ copy = ngx_array_push_n(conf->headers_set, size);
+ if (copy == NULL) {
+ return NGX_CONF_ERROR;
+ }
- return NGX_OK;
-}
+ copy->code = ngx_http_script_copy_code;
+ copy->len = sizeof(CRLF) - 1;
+ p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
+ *p++ = CR; *p = LF;
+ }
-static ngx_int_t
-ngx_http_proxy_compile_header_end(ngx_array_t *lengths, ngx_array_t *values)
-{
- size_t size;
- ngx_http_script_copy_code_t *copy;
+ code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t));
+ if (code == NULL) {
+ return NGX_CONF_ERROR;
+ }
- copy = ngx_array_push_n(lengths, sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
+ *code = (uintptr_t) NULL;
+
+ code = ngx_array_push_n(conf->headers_set, sizeof(uintptr_t));
+ if (code == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *code = (uintptr_t) NULL;
}
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len;
- copy->len = sizeof(CRLF) - 1;
+ code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t));
+ if (code == NULL) {
+ return NGX_CONF_ERROR;
+ }
- size = (sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
+ *code = (uintptr_t) NULL;
- copy = ngx_array_push_n(values,
- sizeof(ngx_http_script_copy_code_t) + size);
- if (copy == NULL) {
- return NGX_ERROR;
+
+ conf->headers_set_hash = ngx_pcalloc(cf->pool, sizeof(ngx_hash_t));
+ if (conf->headers_set_hash == NULL) {
+ return NGX_CONF_ERROR;
}
- copy->code = ngx_http_script_copy;
- copy->len = sizeof(CRLF) - 1;
+ conf->headers_set_hash->max_size = 100;
+ conf->headers_set_hash->bucket_limit = 1;
+ conf->headers_set_hash->bucket_size = sizeof(ngx_str_t);
+ conf->headers_set_hash->name = "proxy_headers";
+
+ if (ngx_hash_init(conf->headers_set_hash, cf->pool,
+ conf->headers_names->elts, conf->headers_names->nelts) != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
- ngx_memcpy((u_char *) copy + sizeof(ngx_http_script_copy_code_t),
- CRLF, sizeof(CRLF) - 1);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
+ "proxy_headers hash size: %ui, "
+ "max buckets per entry: %ui",
+ conf->headers_set_hash->hash_size,
+ conf->headers_set_hash->min_buckets);
- return NGX_OK;
+ return NGX_CONF_OK;
}
static char *
ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_proxy_loc_conf_t *lcf = conf;
+ ngx_http_proxy_loc_conf_t *plcf = conf;
ngx_uint_t i;
ngx_str_t *value, *url;
@@ -1105,20 +1757,16 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
unix_upstream.url.data = url->data + 7;
unix_upstream.uri_part = 1;
- lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
- if (lcf->peers == NULL) {
+ plcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
+ if (plcf->peers == NULL) {
return NGX_CONF_ERROR;
}
- lcf->peers->peer[0].uri_separator = ":";
+ plcf->peers->peer[0].uri_separator = ":";
- lcf->host_header.len = sizeof("localhost") - 1;
- lcf->host_header.data = (u_char *) "localhost";
- lcf->uri0 = unix_upstream.uri;
-#if 0
- STUB
- lcf->upstream->default_port = 1;
-#endif
+ plcf->host_header.len = sizeof("localhost") - 1;
+ plcf->host_header.data = (u_char *) "localhost";
+ plcf->upstream.uri = unix_upstream.uri;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -1137,34 +1785,35 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
inet_upstream.default_port_value = 80;
inet_upstream.uri_part = 1;
- lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
- if (lcf->peers == NULL) {
+ plcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
+ if (plcf->peers == NULL) {
return NGX_CONF_ERROR;
}
- for (i = 0; i < lcf->peers->number; i++) {
- lcf->peers->peer[i].uri_separator = ":";
+ for (i = 0; i < plcf->peers->number; i++) {
+ plcf->peers->peer[i].uri_separator = ":";
}
- lcf->host_header = inet_upstream.host_header;
- lcf->uri0 = inet_upstream.uri;
-#if 0
- STUB
- lcf->port_text = inet_upstream.port_text;
- lcf->upstream->default_port = inet_upstream.default_port;
-#endif
+ plcf->host_header = inet_upstream.host_header;
+ plcf->port_text = inet_upstream.port_text;
+ plcf->upstream.uri = inet_upstream.uri;
}
+ plcf->upstream.schema.len = sizeof("http://") - 1;
+ plcf->upstream.schema.data = (u_char *) "http://";
+
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_proxy_handler;
#if (NGX_PCRE)
- lcf->location0 = clcf->regex ? &ngx_http_proxy_uri : &clcf->name;
+ plcf->upstream.location = clcf->regex ? &ngx_http_proxy_uri : &clcf->name;
#else
- lcf->location0 = &clcf->name;
+ plcf->upstream.location = &clcf->name;
#endif
+ plcf->upstream.url = *url;
+
if (clcf->name.data[clcf->name.len - 1] == '/') {
clcf->auto_redirect = 1;
}
@@ -1174,8 +1823,84 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
-ngx_http_proxy_set_x_var(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
+ ngx_http_proxy_loc_conf_t *plcf = conf;
+
+ ngx_str_t *value;
+ ngx_array_t *vars_lengths, *vars_values;
+ ngx_http_script_compile_t sc;
+ ngx_http_proxy_redirect_t *pr;
+
+ if (plcf->redirect == 0) {
+ return NGX_CONF_OK;
+ }
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ plcf->redirect = 0;
+ plcf->redirects = NULL;
+ return NGX_CONF_OK;
+ }
+
+ if (plcf->redirects == NULL) {
+ plcf->redirects = ngx_array_create(cf->pool, 1,
+ sizeof(ngx_http_proxy_redirect_t));
+ if (plcf->redirects == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ pr = ngx_array_push(plcf->redirects);
+ if (pr == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "default") == 0) {
+ if (plcf->upstream.url.data == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"proxy_rewrite_location default\" must go "
+ "after the \"proxy_pass\" directive");
+ return NGX_CONF_ERROR;
+ }
+
+ pr->handler = ngx_http_proxy_rewrite_redirect_text;
+ pr->redirect = plcf->upstream.url;
+ pr->replacement.text = *plcf->upstream.location;
+
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_http_script_variables_count(&value[2]) == 0) {
+ pr->handler = ngx_http_proxy_rewrite_redirect_text;
+ pr->redirect = value[1];
+ pr->replacement.text = value[2];
+
+ return NGX_CONF_OK;
+ }
+
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ vars_lengths = NULL;
+ vars_values = NULL;
+
+ sc.cf = cf;
+ sc.source = &value[2];
+ sc.lengths = &vars_lengths;
+ sc.values = &vars_values;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ pr->handler = ngx_http_proxy_rewrite_redirect_vars;
+ pr->redirect = value[1];
+ pr->replacement.vars.lengths = vars_lengths->elts;
+ pr->replacement.vars.values = vars_values->elts;
+
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c
index 84381c930..cfc23f6e1 100644
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -54,7 +54,8 @@ static ngx_int_t ngx_http_range_body_filter_init(ngx_cycle_t *cycle);
static ngx_http_module_t ngx_http_range_header_filter_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -68,7 +69,7 @@ static ngx_http_module_t ngx_http_range_header_filter_module_ctx = {
ngx_module_t ngx_http_range_header_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_range_header_filter_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -78,7 +79,8 @@ ngx_module_t ngx_http_range_header_filter_module = {
static ngx_http_module_t ngx_http_range_body_filter_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -92,7 +94,7 @@ static ngx_http_module_t ngx_http_range_body_filter_module_ctx = {
ngx_module_t ngx_http_range_body_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_range_body_filter_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -120,6 +122,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
if (r->http_version < NGX_HTTP_VERSION_10
|| r->headers_out.status != NGX_HTTP_OK
+ || r->main
|| r->headers_out.content_length_n == -1
|| !r->filter_allow_ranges)
{
@@ -136,6 +139,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
+ r->headers_out.accept_ranges->hash = 1;
r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1;
r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges";
r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
@@ -269,6 +273,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
r->headers_out.content_range = content_range;
+ content_range->hash = 1;
content_range->key.len = sizeof("Content-Range") - 1;
content_range->key.data = (u_char *) "Content-Range";
@@ -303,6 +308,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
r->headers_out.content_range = content_range;
+ content_range->hash = 1;
content_range->key.len = sizeof("Content-Range") - 1;
content_range->key.data = (u_char *) "Content-Range";
@@ -338,7 +344,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN
+ sizeof(CRLF "Content-Type: ") - 1
- + r->headers_out.content_type->value.len
+ + r->headers_out.content_type.len
+ sizeof(CRLF "Content-Range: bytes ") - 1;
if (r->headers_out.charset.len) {
@@ -366,7 +372,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
"Content-Type: %V; charset=%V" CRLF
"Content-Range: bytes ",
boundary,
- &r->headers_out.content_type->value,
+ &r->headers_out.content_type,
&r->headers_out.charset)
- ctx->boundary_header.data;
@@ -378,26 +384,26 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
"Content-Type: %V" CRLF
"Content-Range: bytes ",
boundary,
- &r->headers_out.content_type->value)
+ &r->headers_out.content_type)
- ctx->boundary_header.data;
}
- r->headers_out.content_type->value.data =
- ngx_palloc(r->pool,
- sizeof("Content-Type: multipart/byteranges; boundary=") - 1
- + NGX_ATOMIC_T_LEN);
+ r->headers_out.content_type.data =
+ ngx_palloc(r->pool,
+ sizeof("Content-Type: multipart/byteranges; boundary=") - 1
+ + NGX_ATOMIC_T_LEN);
- if (r->headers_out.content_type->value.data == NULL) {
+ if (r->headers_out.content_type.data == NULL) {
return NGX_ERROR;
}
/* "Content-Type: multipart/byteranges; boundary=0123456789" */
- r->headers_out.content_type->value.len =
- ngx_sprintf(r->headers_out.content_type->value.data,
+ r->headers_out.content_type.len =
+ ngx_sprintf(r->headers_out.content_type.data,
"multipart/byteranges; boundary=%0muA",
boundary)
- - r->headers_out.content_type->value.data;
+ - r->headers_out.content_type.data;
/* the size of the last boundary CRLF "--0123456789--" CRLF */
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 1da475cc8..2dc7a7fff 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -9,136 +9,36 @@
#include <ngx_http.h>
-typedef struct ngx_http_rewrite_engine_s ngx_http_rewrite_engine_t;
-
-typedef void (*ngx_http_rewrite_code_pt) (ngx_http_rewrite_engine_t *e);
-
-
typedef struct {
- ngx_str_t name;
- ngx_uint_t wildcard;
+ ngx_str_t name;
+ ngx_uint_t wildcard;
} ngx_http_rewrite_referer_t;
typedef struct {
- ngx_str_t *name;
- ngx_http_variable_value_t *value;
+ ngx_str_t *name;
+ ngx_http_variable_value_t *value;
} ngx_http_rewrite_variable_t;
typedef struct {
- ngx_array_t *codes; /* uintptr_t */
- ngx_array_t *referers; /* ngx_http_rewrite_referer_t */
+ ngx_array_t *codes; /* uintptr_t */
+ ngx_array_t *referers; /* ngx_http_rewrite_referer_t */
- ngx_uint_t max_captures;
- ngx_uint_t stack_size;
+ ngx_uint_t max_captures;
+ ngx_uint_t stack_size;
- ngx_flag_t log;
+ ngx_flag_t log;
- ngx_flag_t no_referer;
- ngx_flag_t blocked_referer;
+ ngx_flag_t no_referer;
+ ngx_flag_t blocked_referer;
} ngx_http_rewrite_loc_conf_t;
-typedef struct {
- ngx_http_rewrite_code_pt code;
- ngx_regex_t *regex;
- uintptr_t size;
- uintptr_t ncaptures;
- uintptr_t status;
- uintptr_t next;
-
- uintptr_t test:1;
- uintptr_t uri:1;
-
- /* add the r->args to the new arguments */
- uintptr_t args:1;
-
- uintptr_t redirect:1;
- uintptr_t break_cycle:1;
-
- ngx_str_t name;
-} ngx_http_rewrite_regex_code_t;
-
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
-
- uintptr_t uri:1;
-
- /* add the r->args to the new arguments */
- uintptr_t args:1;
-
- uintptr_t redirect:1;
-} ngx_http_rewrite_regex_end_code_t;
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
- uintptr_t n;
-} ngx_http_rewrite_copy_capture_code_t;
-
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
- uintptr_t len;
-} ngx_http_rewrite_copy_code_t;
-
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
- uintptr_t status;
- uintptr_t null;
-} ngx_http_rewrite_return_code_t;
-
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
- uintptr_t next;
- void **loc_conf;
-} ngx_http_rewrite_if_code_t;
-
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
- uintptr_t value;
- uintptr_t text_len;
- uintptr_t text_data;
-} ngx_http_rewrite_value_code_t;
-
-
-typedef struct {
- ngx_http_rewrite_code_pt code;
- uintptr_t index;
-} ngx_http_rewrite_var_code_t;
-
-
-struct ngx_http_rewrite_engine_s {
- u_char *ip;
- ngx_http_variable_value_t *sp;
-
- ngx_str_t buf;
- ngx_str_t *line;
-
- u_char *pos;
-
- /* the start of the rewritten arguments */
- u_char *args;
-
- unsigned quote:1;
-
- ngx_int_t status;
-
- int *captures;
-
- ngx_http_request_t *request;
- ngx_http_rewrite_loc_conf_t *conf;
-};
-
-
-static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle);
static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
+static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle);
static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -150,12 +50,8 @@ static char *ngx_http_rewrite_variable(ngx_conf_t *cf,
ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value);
static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
-static char * ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd,
+static char *ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static void *ngx_http_rewrite_start_code(ngx_pool_t *pool,
- ngx_array_t **codes, size_t size);
-static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size,
- void *code);
static ngx_command_t ngx_http_rewrite_commands[] = {
@@ -211,7 +107,8 @@ static ngx_command_t ngx_http_rewrite_commands[] = {
ngx_http_module_t ngx_http_rewrite_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -225,7 +122,7 @@ ngx_http_module_t ngx_http_rewrite_module_ctx = {
ngx_module_t ngx_http_rewrite_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_rewrite_module_ctx, /* module context */
ngx_http_rewrite_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -234,19 +131,15 @@ ngx_module_t ngx_http_rewrite_module = {
};
-#define ngx_http_rewrite_exit (u_char *) &ngx_http_rewrite_exit_code
-
-uintptr_t ngx_http_rewrite_exit_code = (uintptr_t) NULL;
-
static ngx_http_variable_value_t ngx_http_rewrite_null_value =
- { 0, ngx_string("") };
+ { 0, ngx_string("") };
static ngx_int_t
ngx_http_rewrite_handler(ngx_http_request_t *r)
{
- ngx_http_rewrite_code_pt code;
- ngx_http_rewrite_engine_t *e;
+ ngx_http_script_code_pt code;
+ ngx_http_script_engine_t *e;
ngx_http_rewrite_loc_conf_t *cf;
cf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module);
@@ -255,13 +148,13 @@ ngx_http_rewrite_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- e = ngx_palloc(r->pool, sizeof(ngx_http_rewrite_engine_t));
+ e = ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t));
if (e == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- e->sp = ngx_palloc(r->pool,
- cf->stack_size * sizeof(ngx_http_variable_value_t));
+ e->sp = ngx_pcalloc(r->pool,
+ cf->stack_size * sizeof(ngx_http_variable_value_t));
if (e->sp == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
@@ -277,18 +170,13 @@ ngx_http_rewrite_handler(ngx_http_request_t *r)
}
e->ip = cf->codes->elts;
- e->buf.len = 0;
- e->buf.data = NULL;
- e->line = NULL;
- e->pos = NULL;
- e->args = NULL;
+ e->request = r;
e->quote = 1;
+ e->log = cf->log;
e->status = NGX_DECLINED;
- e->request = r;
- e->conf = cf;
while (*(uintptr_t *) e->ip) {
- code = *(ngx_http_rewrite_code_pt *) e->ip;
+ code = *(ngx_http_script_code_pt *) e->ip;
code(e);
}
@@ -297,392 +185,7 @@ ngx_http_rewrite_handler(ngx_http_request_t *r)
static void
-ngx_http_rewrite_regex_start_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_int_t rc;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_rewrite_regex_code_t *code;
-
- code = (ngx_http_rewrite_regex_code_t *) e->ip;
-
- r = e->request;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http rewrite regex: \"%V\"", &code->name);
-
- if (code->uri) {
- e->line = &r->uri;
- } else {
- e->sp--;
- e->line = &e->sp->text;
- }
-
- rc = ngx_regex_exec(code->regex, e->line, e->captures, code->ncaptures);
-
- if (rc == NGX_REGEX_NO_MATCHED) {
- if (e->conf->log) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "\"%V\" does not match \"%V\"", &code->name, e->line);
- }
-
- if (code->test) {
- e->sp->value = 0;
- e->sp->text.len = 0;
- e->sp->text.data = (u_char *) "";
- e->sp++;
-
- e->ip += sizeof(ngx_http_rewrite_regex_code_t);
- return;
- }
-
- e->ip += code->next;
- return;
- }
-
- if (rc < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
- rc, e->line, &code->name);
-
- e->ip = ngx_http_rewrite_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- if (e->conf->log) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "\"%V\" matches \"%V\"", &code->name, e->line);
- }
-
- if (code->test) {
- e->sp->value = 1;
- e->sp->text.len = 1;
- e->sp->text.data = (u_char *) "1";
- e->sp++;
-
- e->ip += sizeof(ngx_http_rewrite_regex_code_t);
- return;
- }
-
- if (code->status) {
- e->status = code->status;
-
- if (!code->redirect) {
- e->ip = ngx_http_rewrite_exit;
- return;
- }
- }
-
- e->buf.len = code->size;
-
- if (code->uri) {
- if (!code->break_cycle) {
- r->uri_changed = 1;
- r->valid_unparsed_uri = 1;
- }
-
- if (rc && (r->quoted_uri || r->plus_in_uri)) {
- e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
- NGX_ESCAPE_ARGS);
- }
- }
-
- for (n = 1; n < (ngx_uint_t) rc; n++) {
- e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n];
- }
-
- if (code->args && r->args.len) {
- e->buf.len += r->args.len + 1;
- }
-
- e->buf.data = ngx_palloc(r->pool, e->buf.len);
- if (e->buf.data == NULL) {
- e->ip = ngx_http_rewrite_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- e->quote = code->redirect;
-
- e->pos = e->buf.data;
-
- e->ip += sizeof(ngx_http_rewrite_regex_code_t);
-}
-
-
-static void
-ngx_http_rewrite_regex_end_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_request_t *r;
- ngx_http_rewrite_regex_end_code_t *code;
-
- code = (ngx_http_rewrite_regex_end_code_t *) e->ip;
-
- r = e->request;
-
- e->quote = 0;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http rewrite regex end");
-
- if (e->args) {
- e->buf.len = e->args - e->buf.data;
-
- if (code->args && r->args.len) {
- *e->pos++ = '&';
- e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len);
- }
-
- r->args.len = e->pos - e->args;
- r->args.data = e->args;
-
- e->args = NULL;
-
- } else {
- if (code->args && r->args.len) {
- *e->pos++ = '?';
- e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len);
- }
-
- e->buf.len = e->pos - e->buf.data;
- }
-
- if (!code->redirect) {
- if (e->conf->log) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "rewritten data: \"%V\", args: \"%V\"",
- &e->buf, &r->args);
- }
-
- if (code->uri) {
- r->uri = e->buf;
-
- if (ngx_http_set_exten(r) != NGX_OK) {
- e->ip = ngx_http_rewrite_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- }
-
- e->ip += sizeof(ngx_http_rewrite_regex_end_code_t);
- return;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "rewritten redirect: \"%V\"", &e->buf);
-
- r->headers_out.location = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.location == NULL) {
- e->ip = ngx_http_rewrite_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- if (e->buf.data[0] != '/') {
- r->headers_out.location->key.len = sizeof("Location") - 1;
- r->headers_out.location->key.data = (u_char *) "Location";
- }
-
- r->headers_out.location->value = e->buf;
-
- e->ip += sizeof(ngx_http_rewrite_regex_end_code_t);
-}
-
-
-static void
-ngx_http_rewrite_copy_capture_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_rewrite_copy_capture_code_t *code;
-
- code = (ngx_http_rewrite_copy_capture_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_rewrite_copy_capture_code_t);
-
- if ((e->args || e->quote)
- && (e->request->quoted_uri || e->request->plus_in_uri))
- {
- e->pos = (u_char *) ngx_escape_uri(e->pos,
- &e->line->data[e->captures[code->n]],
- e->captures[code->n + 1] - e->captures[code->n],
- NGX_ESCAPE_ARGS);
- } else {
- e->pos = ngx_cpymem(e->pos, &e->line->data[e->captures[code->n]],
- e->captures[code->n + 1] - e->captures[code->n]);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite capture: \"%V\"", &e->buf);
-}
-
-
-static void
-ngx_http_rewrite_copy_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_rewrite_copy_code_t *code;
-
- code = (ngx_http_rewrite_copy_code_t *) e->ip;
-
- e->pos = ngx_cpymem(e->pos, e->ip + sizeof(ngx_http_rewrite_copy_code_t),
- code->len);
-
- e->ip += sizeof(ngx_http_rewrite_copy_code_t)
- + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite copy: \"%V\"", &e->buf);
-}
-
-
-static void
-ngx_http_rewrite_start_args_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite args");
-
- e->args = e->pos;
- e->ip += sizeof(uintptr_t);
-}
-
-
-static void
-ngx_http_rewrite_return_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_rewrite_return_code_t *code;
-
- code = (ngx_http_rewrite_return_code_t *) e->ip;
-
- e->status = code->status;
-
- e->ip += sizeof(ngx_http_rewrite_return_code_t) - sizeof(uintptr_t);
-}
-
-
-static void
-ngx_http_rewrite_if_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_rewrite_if_code_t *code;
-
- code = (ngx_http_rewrite_if_code_t *) e->ip;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite if");
-
- e->sp--;
-
- if (e->sp->value) {
- if (code->loc_conf) {
- e->request->loc_conf = code->loc_conf;
- }
-
- e->ip += sizeof(ngx_http_rewrite_if_code_t);
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite if false");
-
- e->ip += code->next;
-}
-
-
-static void
-ngx_http_rewrite_value_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_rewrite_value_code_t *code;
-
- code = (ngx_http_rewrite_value_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_rewrite_value_code_t);
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite value");
-
- e->sp->value = (ngx_uint_t) code->value;
- e->sp->text.len = (size_t) code->text_len;
- e->sp->text.data = (u_char *) code->text_data;
- e->sp++;
-}
-
-
-static void
-ngx_http_rewrite_set_var_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_request_t *r;
- ngx_http_variable_value_t *value;
- ngx_http_core_main_conf_t *cmcf;
- ngx_http_rewrite_var_code_t *code;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite set var");
-
- code = (ngx_http_rewrite_var_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_rewrite_var_code_t);
-
- r = e->request;
-
- if (r->variables == NULL) {
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
- * sizeof(ngx_http_variable_value_t *));
- if (r->variables == NULL) {
- e->ip = ngx_http_rewrite_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- }
-
- value = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
- if (value == NULL) {
- e->ip = ngx_http_rewrite_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- e->sp--;
-
- *value = *e->sp;
-
- r->variables[code->index] = value;
-}
-
-
-static void
-ngx_http_rewrite_var_code(ngx_http_rewrite_engine_t *e)
-{
- ngx_http_variable_value_t *value;
- ngx_http_rewrite_var_code_t *code;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite var");
-
- code = (ngx_http_rewrite_var_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_rewrite_var_code_t);
-
- value = ngx_http_get_indexed_variable(e->request, code->index);
-
- if (value == NULL || value == NGX_HTTP_VARIABLE_NOT_FOUND) {
- e->sp->value = 0;
- e->sp->text.len = 0;
- e->sp->text.data = (u_char *) "";
- e->sp++;
-
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http rewrite var: %ui, \"%V\"", value->value, &value->text);
-
- *e->sp = *value;
- e->sp++;
-}
-
-
-static void
-ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_engine_t *e)
+ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
{
u_char *ref;
size_t len;
@@ -804,13 +307,6 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_engine_t *e)
}
-static void
-ngx_http_rewrite_nop_code(ngx_http_rewrite_engine_t *e)
-{
- e->ip += sizeof(uintptr_t);
-}
-
-
static ngx_http_variable_value_t *
ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data)
{
@@ -834,25 +330,6 @@ ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data)
}
-static ngx_int_t
-ngx_http_rewrite_init(ngx_cycle_t *cycle)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_rewrite_handler;
-
- return NGX_OK;
-}
-
-
static void *
ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
{
@@ -878,8 +355,7 @@ ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_rewrite_loc_conf_t *prev = parent;
ngx_http_rewrite_loc_conf_t *conf = child;
- uintptr_t *code, *last;
- ngx_http_rewrite_regex_code_t *regex;
+ uintptr_t *code;
ngx_conf_merge_value(conf->log, prev->log, 0);
ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10);
@@ -906,65 +382,6 @@ ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_OK;
}
- code = conf->codes->elts;
- last = (uintptr_t *) ((u_char *) code + conf->codes->nelts);
-
- while (code < last) {
- if (*code == (uintptr_t) NULL) {
- return NGX_CONF_OK;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_regex_start_code) {
- regex = (ngx_http_rewrite_regex_code_t *) code;
- if (conf->max_captures < regex->ncaptures) {
- conf->max_captures = regex->ncaptures;
- }
- code = (uintptr_t *) ((u_char *) code + regex->next);
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_if_code) {
- code += sizeof(ngx_http_rewrite_if_code_t) / sizeof(uintptr_t);
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_return_code) {
- code += sizeof(ngx_http_rewrite_return_code_t) / sizeof(uintptr_t);
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_set_var_code) {
- code += sizeof(ngx_http_rewrite_var_code_t) / sizeof(uintptr_t);
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_var_code) {
- code += sizeof(ngx_http_rewrite_var_code_t) / sizeof(uintptr_t);
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_value_code) {
- code += sizeof(ngx_http_rewrite_value_code_t) / sizeof(uintptr_t);
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_invalid_referer_code) {
- code++;
- continue;
- }
-
- if (*code == (uintptr_t) &ngx_http_rewrite_nop_code) {
- code++;
- continue;
- }
-
-#if (NGX_DEBUG)
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unknown rewrite code: %p", *code);
- return NGX_CONF_ERROR;
-#endif
- }
-
code = ngx_array_push_n(conf->codes, sizeof(uintptr_t));
if (code == NULL) {
return NGX_CONF_ERROR;
@@ -976,29 +393,47 @@ ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
+static ngx_int_t
+ngx_http_rewrite_init(ngx_cycle_t *cycle)
+{
+ ngx_http_handler_pt *h;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
+
+ h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ *h = ngx_http_rewrite_handler;
+
+ return NGX_OK;
+}
+
+
static char *
ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_rewrite_loc_conf_t *lcf = conf;
- u_char *data;
- size_t len, size;
- ngx_str_t *value, err;
- ngx_int_t n;
- ngx_uint_t i, last;
- ngx_http_rewrite_code_pt *code;
- ngx_http_rewrite_copy_code_t *copy;
- ngx_http_rewrite_regex_code_t *regex;
- ngx_http_rewrite_regex_end_code_t *regex_end;
- ngx_http_rewrite_copy_capture_code_t *copy_capture;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- regex = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_regex_code_t));
+ ngx_str_t *value, err;
+ ngx_int_t n;
+ ngx_uint_t last;
+ ngx_http_script_code_pt *code;
+ ngx_http_script_compile_t sc;
+ ngx_http_script_regex_code_t *regex;
+ ngx_http_script_regex_end_code_t *regex_end;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
+
+ regex = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_regex_code_t));
if (regex == NULL) {
return NGX_CONF_ERROR;
}
+ ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t));
+
value = cf->args->elts;
err.len = NGX_MAX_CONF_ERRSTR;
@@ -1013,17 +448,19 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- regex->code = ngx_http_rewrite_regex_start_code;
- regex->size = 0;
- regex->ncaptures = 0;
- regex->status = 0;
- regex->test = 0;
+ regex->code = ngx_http_script_regex_start_code;
regex->uri = 1;
- regex->args = 1;
- regex->redirect = 0;
- regex->break_cycle = 0;
regex->name = value[1];
+ if (value[2].data[value[2].len - 1] == '?') {
+
+ /* the last "?" drops the original arguments */
+ value[2].len--;
+
+ } else {
+ regex->add_args = 1;
+ }
+
last = 0;
if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) {
@@ -1057,113 +494,29 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
- i = 0;
-
- while (i < value[2].len) {
-
- data = &value[2].data[i];
-
- if (value[2].data[i] == '$' && i < value[2].len
- && value[2].data[i + 1] >= '1' && value[2].data[i + 1] <= '9')
- {
-
- /* the "$1" - "$9" captures */
-
- copy_capture = ngx_http_rewrite_add_code(lcf->codes,
- sizeof(ngx_http_rewrite_copy_capture_code_t),
- &regex);
- if (copy_capture == NULL) {
- return NGX_CONF_ERROR;
- }
-
- i++;
-
- copy_capture->code = ngx_http_rewrite_copy_capture_code;
- copy_capture->n = value[2].data[i] - '0';
-
- if (regex->ncaptures < copy_capture->n) {
- regex->ncaptures = copy_capture->n;
- }
-
- copy_capture->n *= 2;
-
- i++;
-
- continue;
- }
-
- if (value[2].data[i] == '?') {
-
- /* the arguments */
-
- if (i == value[2].len - 1) {
- /* the last "?" drops the original arguments */
- regex->args = 0;
- break;
- }
-
- if (!regex->redirect) {
- code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t),
- &regex);
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = ngx_http_rewrite_start_args_code;
-
- i++;
-
- continue;
- }
- }
-
- i++;
-
- /* the substituion strings */
-
- while (i < value[2].len && value[2].data[i] != '$') {
-
- if (value[2].data[i] == '?') {
-
- if (i == value[2].len - 1) {
- /*
- * the last "?" drops the original arguments,
- * and it should not be copied to a substituion
- */
- regex->args = 0;
- break;
- }
-
- if (!regex->redirect) {
- break;
- }
- }
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
- i++;
- }
-
- len = &value[2].data[i] - data;
+ sc.cf = cf;
+ sc.source = &value[2];
+ sc.lengths = &regex->lengths;
+ sc.values = &lcf->codes;
+ sc.variables = ngx_http_script_variables_count(&value[2]);
+ sc.main = regex;
+ sc.complete_lengths = 1;
+ sc.compile_args = !regex->redirect;
- if (len == 0) {
- continue;
- }
-
- regex->size += len;
-
- size = (len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1);
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
- copy = ngx_http_rewrite_add_code(lcf->codes,
- sizeof(ngx_http_rewrite_copy_code_t) + size,
- &regex);
- if (copy == NULL) {
- return NGX_CONF_ERROR;
- }
+ regex = sc.main;
- copy->code = ngx_http_rewrite_copy_code;
- copy->len = len;
+ regex->ncaptures = sc.ncaptures;
+ regex->size = sc.size;
+ regex->args = sc.args;
- ngx_memcpy((u_char *) copy + sizeof(ngx_http_rewrite_copy_code_t),
- data, len);
+ if (sc.variables == 0) {
+ regex->lengths = NULL;
}
n = ngx_regex_capture_count(regex->regex);
@@ -1191,21 +544,26 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
regex->ncaptures = (regex->ncaptures + 1) * 3;
}
- regex_end = ngx_http_rewrite_add_code(lcf->codes,
- sizeof(ngx_http_rewrite_regex_end_code_t),
- &regex);
+ if (lcf->max_captures < regex->ncaptures) {
+ lcf->max_captures = regex->ncaptures;
+ }
+
+ regex_end = ngx_http_script_add_code(lcf->codes,
+ sizeof(ngx_http_script_regex_end_code_t),
+ &regex);
if (regex_end == NULL) {
return NGX_CONF_ERROR;
}
- regex_end->code = ngx_http_rewrite_regex_end_code;
+ regex_end->code = ngx_http_script_regex_end_code;
regex_end->uri = regex->uri;
regex_end->args = regex->args;
+ regex_end->add_args = regex->add_args;
regex_end->redirect = regex->redirect;
if (last) {
- code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t),
- &regex);
+ code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t),
+ &regex);
if (code == NULL) {
return NGX_CONF_ERROR;
}
@@ -1225,18 +583,18 @@ ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_rewrite_loc_conf_t *lcf = conf;
- ngx_str_t *value;
- ngx_http_rewrite_return_code_t *ret;
+ ngx_str_t *value;
+ ngx_http_script_return_code_t *ret;
- ret = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_return_code_t));
+ ret = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_return_code_t));
if (ret == NULL) {
return NGX_CONF_ERROR;
}
value = cf->args->elts;
- ret->code = ngx_http_rewrite_return_code;
+ ret->code = ngx_http_script_return_code;
ret->null = (uintptr_t) NULL;
ret->status = ngx_atoi(value[1].data, value[1].len);
@@ -1262,7 +620,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *pctx;
ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
- ngx_http_rewrite_if_code_t *if_code;
+ ngx_http_script_if_code_t *if_code;
ngx_http_rewrite_loc_conf_t *nlcf;
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
@@ -1324,12 +682,12 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_rewrite_if_code_t));
+ if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t));
if (if_code == NULL) {
return NULL;
}
- if_code->code = ngx_http_rewrite_if_code;
+ if_code->code = ngx_http_script_if_code;
elts = lcf->codes->elts;
@@ -1362,7 +720,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (elts != lcf->codes->elts) {
- if_code = (ngx_http_rewrite_if_code_t *)
+ if_code = (ngx_http_script_if_code_t *)
((u_char *) if_code + ((u_char *) lcf->codes->elts - elts));
}
@@ -1376,10 +734,10 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
{
- ngx_str_t *value, err;
- ngx_uint_t cur, last;
- ngx_http_rewrite_regex_code_t *regex;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_str_t *value, err;
+ ngx_uint_t cur, last;
+ ngx_http_script_regex_code_t *regex;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
value = cf->args->elts;
last = cf->args->nelts - 1;
@@ -1440,12 +798,14 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
return NGX_CONF_ERROR;
}
- regex = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_regex_code_t));
+ regex = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_regex_code_t));
if (regex == NULL) {
return NGX_CONF_ERROR;
}
+ ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t));
+
err.len = NGX_MAX_CONF_ERRSTR;
err.data = errstr;
@@ -1458,16 +818,9 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
return NGX_CONF_ERROR;
}
- regex->code = ngx_http_rewrite_regex_start_code;
- regex->size = 0;
- regex->ncaptures = 0;
- regex->status = 0;
- regex->next = sizeof(ngx_http_rewrite_regex_code_t);
+ regex->code = ngx_http_script_regex_start_code;
+ regex->next = sizeof(ngx_http_script_regex_code_t);
regex->test = 1;
- regex->uri = 0;
- regex->args = 0;
- regex->redirect = 0;
- regex->break_cycle = 0;
regex->name = value[last];
return NGX_CONF_OK;
@@ -1484,9 +837,9 @@ static char *
ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf,
ngx_str_t *value)
{
- ngx_http_variable_t *var;
- ngx_http_rewrite_code_pt *code;
- ngx_http_rewrite_var_code_t *var_code;
+ ngx_int_t index;
+ ngx_http_script_code_pt *code;
+ ngx_http_script_var_code_t *var_code;
value->len--;
value->data++;
@@ -1495,8 +848,8 @@ ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf,
&& ngx_strncmp(value->data, "invalid_referer",
sizeof("invalid_referer") - 1) == 0)
{
- code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_code_pt));
+ code = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_code_pt));
if (code == NULL) {
return NGX_CONF_ERROR;
}
@@ -1504,20 +857,20 @@ ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf,
*code = ngx_http_rewrite_invalid_referer_code;
} else {
- var = ngx_http_add_variable(cf, value, 0);
+ index = ngx_http_get_variable_index(cf, value);
- if (var == NULL) {
+ if (index == NGX_ERROR) {
return NGX_CONF_ERROR;
}
- var_code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_var_code_t));
+ var_code = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_var_code_t));
if (var_code == NULL) {
return NGX_CONF_ERROR;
}
- var_code->code = ngx_http_rewrite_var_code;
- var_code->index = var->index;
+ var_code->code = ngx_http_script_var_code;
+ var_code->index = index;
}
return NGX_CONF_OK;
@@ -1624,11 +977,11 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_rewrite_loc_conf_t *lcf = conf;
- ngx_int_t n;
- ngx_str_t *value;
- ngx_http_variable_t *v;
- ngx_http_rewrite_var_code_t *var;
- ngx_http_rewrite_value_code_t *val;
+ ngx_int_t n, index;
+ ngx_str_t *value;
+ ngx_http_variable_t *v;
+ ngx_http_script_var_code_t *var;
+ ngx_http_script_value_code_t *val;
value = cf->args->elts;
@@ -1641,16 +994,21 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value[1].len--;
value[1].data++;
- v = ngx_http_add_variable(cf, &value[1], 1);
+ v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
if (v == NULL) {
return NGX_CONF_ERROR;
}
+ index = ngx_http_get_variable_index(cf, &value[1]);
+ if (index == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
v->handler = ngx_http_rewrite_var;
- v->data = v->index;
+ v->data = index;
- val = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_value_code_t));
+ val = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_value_code_t));
if (val == NULL) {
return NGX_CONF_ERROR;
}
@@ -1661,55 +1019,19 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
n = 0;
}
- val->code = ngx_http_rewrite_value_code;
+ val->code = ngx_http_script_value_code;
val->value = (uintptr_t) n;
val->text_len = (uintptr_t) value[2].len;
val->text_data = (uintptr_t) value[2].data;
- var = ngx_http_rewrite_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_rewrite_var_code_t));
+ var = ngx_http_script_start_code(cf->pool, &lcf->codes,
+ sizeof(ngx_http_script_var_code_t));
if (var == NULL) {
return NGX_CONF_ERROR;
}
- var->code = ngx_http_rewrite_set_var_code;
- var->index = (uintptr_t) v->index;
+ var->code = ngx_http_script_set_var_code;
+ var->index = (uintptr_t) index;
return NGX_CONF_OK;
}
-
-
-static void *
-ngx_http_rewrite_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
-{
- if (*codes == NULL) {
- *codes = ngx_array_create(pool, 256, 1);
- if (*codes == NULL) {
- return NULL;
- }
- }
-
- return ngx_array_push_n(*codes, size);
-}
-
-
-static void *
-ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, void *code)
-{
- u_char *elts, **p;
- void *new;
-
- elts = codes->elts;
-
- new = ngx_array_push_n(codes, size);
- if (new == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (elts != codes->elts) {
- p = code;
- *p += (u_char *) codes->elts - elts;
- }
-
- return new;
-}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index a351747b5..acaeeeda6 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -16,10 +16,13 @@
#define NGX_HTTP_SSI_ERROR 1
+#define NGX_HTTP_SSI_DATE_LEN 2048
+
typedef struct {
ngx_flag_t enable;
ngx_flag_t silent_errors;
+ ngx_flag_t ignore_recycled_buffers;
size_t min_file_chunk;
size_t value_len;
@@ -50,6 +53,10 @@ typedef struct {
size_t looked;
size_t value_len;
+
+ ngx_uint_t output; /* unsigned output:1; */
+
+ ngx_str_t timefmt;
} ngx_http_ssi_ctx_t;
@@ -70,7 +77,8 @@ typedef struct {
ngx_http_ssi_command_pt handler;
ngx_http_ssi_param_t *params;
- ngx_uint_t flush; /* unsigned flush:1; */
+ unsigned conditional:1;
+ unsigned flush:1;
} ngx_http_ssi_command_t;
@@ -98,12 +106,28 @@ typedef enum {
} ngx_http_ssi_state_e;
+static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx);
static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ctx);
static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+static ngx_int_t ngx_http_ssi_if(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+
+static ngx_http_variable_value_t *
+ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt);
+static ngx_int_t ngx_http_ssi_add_variables(ngx_conf_t *cf);
static void *ngx_http_ssi_create_conf(ngx_conf_t *cf);
static char *ngx_http_ssi_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
@@ -126,6 +150,13 @@ static ngx_command_t ngx_http_ssi_filter_commands[] = {
offsetof(ngx_http_ssi_conf_t, silent_errors),
NULL },
+ { ngx_string("ssi_ignore_recycled_buffers"),
+ 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_ssi_conf_t, ignore_recycled_buffers),
+ NULL },
+
{ ngx_string("ssi_min_file_chunk"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_size_slot,
@@ -139,7 +170,8 @@ static ngx_command_t ngx_http_ssi_filter_commands[] = {
static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
- NULL, /* pre conf */
+ ngx_http_ssi_add_variables, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -153,7 +185,7 @@ static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
ngx_module_t ngx_http_ssi_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_ssi_filter_module_ctx, /* module context */
ngx_http_ssi_filter_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -174,8 +206,16 @@ static u_char ngx_http_ssi_error_string[] =
static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
-#define NGX_HTTP_SSI_ECHO_VAR 0
-#define NGX_HTTP_SSI_ECHO_DEFAULT 1
+#define NGX_HTTP_SSI_ECHO_VAR 0
+#define NGX_HTTP_SSI_ECHO_DEFAULT 1
+
+#define NGX_HTTP_SSI_CONFIG_TIMEFMT 0
+
+#define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0
+#define NGX_HTTP_SSI_INCLUDE_FILE 1
+
+#define NGX_HTTP_SSI_IF_EXPR 0
+
static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
{ ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1 },
@@ -183,13 +223,60 @@ static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
{ ngx_null_string, 0, 0 }
};
+static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
+ { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0 },
+#if 0
+ { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0 },
+#endif
+ { ngx_null_string, 0, 0 }
+};
+
+
+static ngx_http_ssi_param_t ngx_http_ssi_config_params[] = {
+ { ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0 },
+ { ngx_null_string, 0, 0 }
+};
+
+
+static ngx_http_ssi_param_t ngx_http_ssi_if_params[] = {
+ { ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 0 },
+ { ngx_null_string, 0, 0 }
+};
+
+
+static ngx_http_ssi_param_t ngx_http_ssi_no_params[] = {
+ { ngx_null_string, 0, 0 }
+};
+
static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
- { ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0 },
- { ngx_null_string, NULL, NULL, 0 }
+ { ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0, 0 },
+ { ngx_string("config"), ngx_http_ssi_config,
+ ngx_http_ssi_config_params, 0, 0 },
+ { ngx_string("include"), ngx_http_ssi_include,
+ ngx_http_ssi_include_params, 0, 1 },
+
+ { ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0 },
+ { ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params, 1, 0 },
+ { ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params, 1, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0 }
};
+static ngx_http_variable_t ngx_http_ssi_vars[] = {
+
+ { ngx_string("date_local"), ngx_http_ssi_date_gmt_local_variable, 0,
+ NGX_HTTP_VAR_NOCACHABLE },
+
+ { ngx_string("date_gmt"), ngx_http_ssi_date_gmt_local_variable, 1,
+ NGX_HTTP_VAR_NOCACHABLE },
+
+ { ngx_null_string, NULL, 0, 0 }
+};
+
+
+
static ngx_int_t
ngx_http_ssi_header_filter(ngx_http_request_t *r)
{
@@ -204,9 +291,9 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
/* TODO: "text/html" -> custom types */
- if (r->headers_out.content_type
- && ngx_strncasecmp(r->headers_out.content_type->value.data,
- "text/html", 5) != 0)
+ if (r->headers_out.content_type.len == 0
+ || ngx_strncasecmp(r->headers_out.content_type.data, "text/html", 5)
+ != 0)
{
return ngx_http_next_header_filter(r);
}
@@ -223,26 +310,33 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
ctx->value_len = conf->value_len;
ctx->last_out = &ctx->out;
+ ctx->output = 1;
+
ctx->params.elts = ctx->params_array;
ctx->params.size = sizeof(ngx_table_elt_t);
ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N;
ctx->params.pool = r->pool;
- r->headers_out.content_length_n = -1;
- if (r->headers_out.content_length) {
- r->headers_out.content_length->key.len = 0;
- r->headers_out.content_length = NULL;
- }
-
- r->headers_out.last_modified_time = -1;
- if (r->headers_out.last_modified) {
- r->headers_out.last_modified->key.len = 0;
- r->headers_out.last_modified = NULL;
- }
+ ctx->timefmt.len = sizeof("%A, %d-%b-%Y %H:%M:%S %Z") - 1;
+ ctx->timefmt.data = (u_char *) "%A, %d-%b-%Y %H:%M:%S %Z";
r->filter_need_in_memory = 1;
r->filter_ssi_need_in_memory = 1;
+ if (r->main == NULL) {
+ r->headers_out.content_length_n = -1;
+ if (r->headers_out.content_length) {
+ r->headers_out.content_length->hash = 0;
+ r->headers_out.content_length = NULL;
+ }
+
+ r->headers_out.last_modified_time = -1;
+ if (r->headers_out.last_modified) {
+ r->headers_out.last_modified->hash = 0;
+ r->headers_out.last_modified = NULL;
+ }
+ }
+
return ngx_http_next_header_filter(r);
}
@@ -277,8 +371,8 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
conf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ssi filter");
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http ssi filter \"%V\"", &r->uri);
while (ctx->in || ctx->buf) {
@@ -312,19 +406,50 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (ctx->copy_start != ctx->copy_end) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "saved: %d", ctx->saved);
+ if (ctx->output) {
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "saved: %d", ctx->saved);
+
+ if (ctx->saved) {
+
+ if (ctx->free) {
+ cl = ctx->free;
+ ctx->free = ctx->free->next;
+ b = cl->buf;
+ ngx_memzero(b, sizeof(ngx_buf_t));
- if (ctx->saved) {
+ } else {
+ b = ngx_calloc_buf(r->pool);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl = ngx_alloc_chain_link(r->pool);
+ if (cl == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl->buf = b;
+ }
+
+ b->memory = 1;
+ b->pos = ngx_http_ssi_string;
+ b->last = ngx_http_ssi_string + ctx->saved;
+
+ *ctx->last_out = cl;
+ ctx->last_out = &cl->next;
+
+ ctx->saved = 0;
+ }
if (ctx->free) {
cl = ctx->free;
ctx->free = ctx->free->next;
b = cl->buf;
- ngx_memzero(b, sizeof(ngx_buf_t));
} else {
- b = ngx_calloc_buf(r->pool);
+ b = ngx_alloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
@@ -337,56 +462,31 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
cl->buf = b;
}
- b->memory = 1;
- b->pos = ngx_http_ssi_string;
- b->last = ngx_http_ssi_string + ctx->saved;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->saved = 0;
- }
+ ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
- if (ctx->free) {
- cl = ctx->free;
- ctx->free = ctx->free->next;
- b = cl->buf;
+ b->last_buf = 0;
+ b->recycled = 0;
+ b->pos = ctx->copy_start;
+ b->last = ctx->copy_end;
- } else {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
+ if (b->in_file) {
+ if (conf->min_file_chunk < (size_t) (b->last - b->pos))
+ {
+ b->file_last = b->file_pos + (b->last - b->start);
+ b->file_pos += b->pos - b->start;
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
+ } else {
+ b->in_file = 0;
+ }
}
- cl->buf = b;
- }
-
- ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
-
- b->last_buf = 0;
- b->recycled = 0;
- b->pos = ctx->copy_start;
- b->last = ctx->copy_end;
-
- if (b->in_file) {
-
- if (conf->min_file_chunk < (size_t) (b->last - b->pos)) {
- b->file_last = b->file_pos + (b->last - b->start);
- b->file_pos += b->pos - b->start;
+ cl->next = NULL;
+ *ctx->last_out = cl;
+ ctx->last_out = &cl->next;
- } else {
- b->in_file = 0;
- }
+ } else {
+ ctx->saved = 0;
}
-
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
}
if (ctx->state == ssi_start_state) {
@@ -420,12 +520,16 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
break;
}
- if (cmd->name.len == 0) {
+ if (cmd->name.len == 0 && ctx->output) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"invalid SSI command: \"%V\"", &ctx->command);
goto ssi_error;
}
+ if (!ctx->output && !cmd->conditional) {
+ continue;
+ }
+
ngx_memzero(params,
NGX_HTTP_SSI_MAX_PARAMS * sizeof(ngx_str_t *));
@@ -479,6 +583,14 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
+ if (cmd->flush && ctx->out) {
+ rc = ngx_http_ssi_output(r, ctx);
+
+ if (rc == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+ }
+
if (cmd->handler(r, ctx, params) == NGX_OK) {
continue;
}
@@ -525,9 +637,9 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
continue;
}
- if (ctx->buf->recycled || ctx->buf->last_buf) {
- if (b == NULL) {
+ if (ctx->buf->last_buf || ctx->buf->recycled) {
+ if (b == NULL) {
if (ctx->free) {
cl = ctx->free;
ctx->free = ctx->free->next;
@@ -548,14 +660,19 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
cl->buf = b;
}
+ b->sync = 1;
+
cl->next = NULL;
*ctx->last_out = cl;
ctx->last_out = &cl->next;
}
b->last_buf = ctx->buf->last_buf;
- b->flush = ctx->buf->recycled;
b->shadow = ctx->buf;
+
+ if (conf->ignore_recycled_buffers == 0) {
+ b->recycled = ctx->buf->recycled;
+ }
}
ctx->buf = NULL;
@@ -567,6 +684,17 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
return NGX_OK;
}
+ return ngx_http_ssi_output(r, ctx);
+}
+
+
+static ngx_int_t
+ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
+{
+ ngx_int_t rc;
+ ngx_buf_t *b;
+ ngx_chain_t *cl;
+
rc = ngx_http_next_body_filter(r, ctx->out);
if (ctx->busy == NULL) {
@@ -1154,7 +1282,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
var = params[NGX_HTTP_SSI_ECHO_VAR];
for (i = 0; i < var->len; i++) {
- var->data[i] = ngx_toupper(var->data[i]);
+ var->data[i] = ngx_tolower(var->data[i]);
}
vv = ngx_http_get_variable(r, var);
@@ -1163,7 +1291,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
return NGX_HTTP_SSI_ERROR;
}
- if (vv == NGX_HTTP_VARIABLE_NOT_FOUND) {
+ if (vv == NGX_HTTP_VAR_NOT_FOUND) {
value = params[NGX_HTTP_SSI_ECHO_DEFAULT];
if (value == NULL) {
@@ -1204,6 +1332,325 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
+static ngx_int_t
+ngx_http_ssi_config(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
+ ngx_str_t **params)
+{
+ ngx_str_t *value;
+
+ value = params[NGX_HTTP_SSI_CONFIG_TIMEFMT];
+
+ if (value) {
+ ctx->timefmt = *value;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
+ ngx_str_t **params)
+{
+ u_char ch, *p, **value;
+ size_t *size, len;
+ ngx_uint_t i, j, n, bracket;
+ ngx_str_t uri, args, name;
+ ngx_array_t lengths, values;
+ ngx_http_variable_value_t *vv;
+
+ /* TODO: file, virtual vs file */
+
+ uri = *params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
+ args.len = 0;
+ args.data = NULL;
+
+ n = ngx_http_script_variables_count(&uri);
+
+ if (n > 0) {
+
+ if (ngx_array_init(&lengths, r->pool, 8, sizeof(size_t *)) != NGX_OK) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ if (ngx_array_init(&values, r->pool, 8, sizeof(u_char *)) != NGX_OK) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ len = 0;
+
+ for (i = 0; i < uri.len; /* void */ ) {
+
+ name.len = 0;
+
+ if (uri.data[i] == '$') {
+
+ if (++i == uri.len) {
+ goto invalid_variable;
+ }
+
+ if (uri.data[i] == '{') {
+ bracket = 1;
+
+ if (++i == uri.len) {
+ goto invalid_variable;
+ }
+
+ name.data = &uri.data[i];
+
+ } else {
+ bracket = 0;
+ name.data = &uri.data[i];
+ }
+
+ for ( /* void */ ; i < uri.len; i++, name.len++) {
+ ch = uri.data[i];
+
+ if (ch == '}' && bracket) {
+ i++;
+ bracket = 0;
+ break;
+ }
+
+ if ((ch >= 'A' && ch <= 'Z')
+ || (ch >= 'a' && ch <= 'z')
+ || (ch >= '0' && ch <= '9')
+ || ch == '_')
+ {
+ continue;
+ }
+
+ break;
+ }
+
+ if (bracket) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "the closing bracket in \"%V\" "
+ "variable is missing", &name);
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ if (name.len == 0) {
+ goto invalid_variable;
+ }
+
+ for (j = 0; j < name.len; j++) {
+ name.data[j] = ngx_tolower(name.data[j]);
+ }
+
+ vv = ngx_http_get_variable(r, &name);
+
+ if (vv == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ if (vv == NGX_HTTP_VAR_NOT_FOUND) {
+ continue;
+ }
+
+ name = vv->text;
+
+ } else {
+ name.data = &uri.data[i];
+
+ while (i < uri.len && uri.data[i] != '$') {
+ i++;
+ name.len++;
+ }
+ }
+
+ len += name.len;
+
+ size = ngx_array_push(&lengths);
+ if (size == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ *size = name.len;
+
+ value = ngx_array_push(&values);
+ if (value == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ *value = name.data;
+ }
+
+ p = ngx_palloc(r->pool, len);
+ if (p == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ uri.len = len;
+ uri.data = p;
+
+ size = lengths.elts;
+ value = values.elts;
+
+ for (i = 0; i < values.nelts; i++) {
+ p = ngx_cpymem(p, value[i], size[i]);
+ }
+ }
+
+ for (i = 0; i < uri.len; i++) {
+ if (uri.data[i] == '?') {
+ args.len = uri.len - i - 1;
+ args.data = &uri.data[i + 1];
+ uri.len -= args.len + 1;
+
+ break;
+ }
+ }
+
+ if (ngx_http_subrequest(r, &uri, &args) != NGX_OK) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ return NGX_OK;
+
+invalid_variable:
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "invalid variable name in \"%V\"", &uri);
+
+ return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
+ ngx_str_t **params)
+{
+ ngx_str_t *expr, var;
+ ngx_uint_t i;
+ ngx_http_variable_value_t *vv;
+
+ expr = params[NGX_HTTP_SSI_IF_EXPR];
+
+ if (expr->data[0] != '$') {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "invalid variable name in \"%V\"", expr);
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ var.len = expr->len - 1;
+ var.data = expr->data + 1;
+
+ for (i = 0; i < var.len; i++) {
+ var.data[i] = ngx_tolower(var.data[i]);
+ }
+
+ vv = ngx_http_get_variable(r, &var);
+
+ if (vv == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ if (vv != NGX_HTTP_VAR_NOT_FOUND && vv->text.len != 0) {
+ ctx->output = 1;
+
+ } else {
+ ctx->output = 0;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_ssi_else(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
+ ngx_str_t **params)
+{
+ ctx->output = !ctx->output;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
+ ngx_str_t **params)
+{
+ ctx->output = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_http_variable_value_t *
+ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt)
+{
+ ngx_http_ssi_ctx_t *ctx;
+ ngx_http_variable_value_t *vv;
+ struct tm tm;
+ char buf[NGX_HTTP_SSI_DATE_LEN];
+
+ vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+ if (vv == NULL) {
+ return NULL;
+ }
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
+
+ if (ctx->timefmt.len == sizeof("%s") - 1
+ && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's')
+ {
+ vv->value = ngx_time() + (gmt ? 0 : ngx_gmtoff);
+
+ vv->text.data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
+ if (vv->text.data == NULL) {
+ return NULL;
+ }
+
+ vv->text.len = ngx_sprintf(vv->text.data, "%T", vv->value)
+ - vv->text.data;
+ return vv;
+ }
+
+ if (gmt) {
+ ngx_libc_gmtime(&tm);
+ } else {
+ ngx_libc_localtime(&tm);
+ }
+
+ vv->value = ngx_time() + (gmt ? 0 : ngx_gmtoff);
+
+ vv->text.len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
+ (char *) ctx->timefmt.data, &tm);
+ if (vv->text.len == 0) {
+ return NULL;
+ }
+
+ vv->text.data = ngx_palloc(r->pool, vv->text.len);
+ if (vv->text.data == NULL) {
+ return NULL;
+ }
+
+ ngx_memcpy(vv->text.data, buf, vv->text.len);
+
+ return vv;
+}
+
+
+static ngx_int_t
+ngx_http_ssi_add_variables(ngx_conf_t *cf)
+{
+ ngx_http_variable_t *var, *v;
+
+ for (v = ngx_http_ssi_vars; v->name.len; v++) {
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->handler = v->handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
static void *
ngx_http_ssi_create_conf(ngx_conf_t *cf)
{
@@ -1216,6 +1663,7 @@ ngx_http_ssi_create_conf(ngx_conf_t *cf)
conf->enable = NGX_CONF_UNSET;
conf->silent_errors = NGX_CONF_UNSET;
+ conf->ignore_recycled_buffers = NGX_CONF_UNSET;
conf->min_file_chunk = NGX_CONF_UNSET_SIZE;
conf->value_len = NGX_CONF_UNSET_SIZE;
@@ -1232,6 +1680,8 @@ ngx_http_ssi_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
+ ngx_conf_merge_value(conf->ignore_recycled_buffers,
+ prev->ignore_recycled_buffers, 0);
ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256);
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index c18c493ac..04d4c9100 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -64,7 +64,8 @@ static ngx_command_t ngx_http_ssl_commands[] = {
static ngx_http_module_t ngx_http_ssl_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
ngx_http_ssl_create_main_conf, /* create main configuration */
ngx_http_ssl_init_main_conf, /* init main configuration */
@@ -78,7 +79,7 @@ static ngx_http_module_t ngx_http_ssl_module_ctx = {
ngx_module_t ngx_http_ssl_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_ssl_module_ctx, /* module context */
ngx_http_ssl_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -197,6 +198,13 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
+ if (ngx_pool_cleanup_add(cf->pool, ngx_ssl_cleanup_ctx, conf->ssl_ctx)
+ == NULL)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+
#if 0
SSL_CTX_set_options(conf->ssl_ctx, SSL_OP_ALL);
SSL_CTX_set_options(conf->ssl_ctx, SSL_OP_NO_SSLv3);
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index c2c45828f..a84a70eb6 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -17,7 +17,7 @@ typedef struct {
static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
+ void *parent, void *child);
static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle);
@@ -38,9 +38,9 @@ static ngx_command_t ngx_http_static_commands[] = {
};
-
ngx_http_module_t ngx_http_static_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -54,7 +54,7 @@ ngx_http_module_t ngx_http_static_module_ctx = {
ngx_module_t ngx_http_static_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_static_module_ctx, /* module context */
ngx_http_static_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -63,7 +63,8 @@ ngx_module_t ngx_http_static_module = {
};
-static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
+static ngx_int_t
+ngx_http_static_handler(ngx_http_request_t *r)
{
u_char *last;
ngx_fd_t fd;
@@ -75,16 +76,8 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
ngx_buf_t *b;
ngx_chain_t out;
ngx_file_info_t fi;
- ngx_http_cleanup_t *file_cleanup;
-#if (NGX_HTTP_CACHE)
- ngx_http_cleanup_t *redirect_cleanup;
-#endif
+ ngx_pool_cleanup_file_t *cln;
ngx_http_core_loc_conf_t *clcf;
-#if (NGX_HTTP_CACHE)
- ngx_http_static_loc_conf_t *slcf;
- uint32_t file_crc, redirect_crc;
- ngx_http_cache_t *file, *redirect;
-#endif
if (r->uri.data[r->uri.len - 1] == '/') {
return NGX_DECLINED;
@@ -105,19 +98,6 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
return rc;
}
-#if (NGX_HTTP_CACHE)
-
- /*
- * there is a valid cached open file, i.e by the index handler,
- * and it should be already registered in r->cleanup
- */
-
- if (r->cache && !r->cache->expired) {
- return ngx_http_send_cached(r);
- }
-
-#endif
-
log = r->connection->log;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -127,7 +107,19 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
* in a possible redirect and for the last '\0'
*/
- if (clcf->alias) {
+ if (!clcf->alias) {
+ name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2);
+ if (name.data == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
+ last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
+
+ name.len = last - name.data;
+ location.len = last - location.data + 1;
+
+ } else {
name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2
- clcf->name.len);
if (name.data == NULL) {
@@ -147,119 +139,16 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
-#if 0
- /*
- * aliases usually have trailling "/",
- * set it in the start of the possible redirect
- */
-
- if (*location.data != '/') {
- location.data--;
- }
-#endif
-
- location.len = last - location.data + 1;
-
- } else {
- name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2);
- if (name.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
- last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
-
- name.len = last - name.data;
location.len = last - location.data + 1;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
"http filename: \"%s\"", name.data);
-
- /* allocate cleanups */
-
- file_cleanup = ngx_array_push(&r->cleanup);
- if (file_cleanup == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- file_cleanup->valid = 0;
-
-#if (NGX_HTTP_CACHE)
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_static_module);
- if (slcf->redirect_cache) {
- redirect_cleanup = ngx_array_push(&r->cleanup);
- if (redirect_cleanup == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- redirect_cleanup->valid = 0;
-
- } else {
- redirect_cleanup = NULL;
- }
-
- /* look up an open files cache */
-
- if (clcf->open_files) {
- file = ngx_http_cache_get(clcf->open_files, file_cleanup,
- &name, &file_crc);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http open file cache get: %p", file);
-
- if (file && !file->expired) {
- r->cache = file;
- return ngx_http_send_cached(r);
- }
-
- } else {
- file = NULL;
- }
-
-
- /* look up an redirect cache */
-
- if (slcf->redirect_cache) {
- redirect = ngx_http_cache_get(slcf->redirect_cache, redirect_cleanup,
- &name, &redirect_crc);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http redirect cache get: %p", redirect);
-
- if (redirect && !redirect->expired) {
-
- /*
- * We do not copy a cached value so the cache entry is locked
- * until the end of the request. In a single threaded model
- * the redirected request should complete before other event
- * will be processed. In a multithreaded model this locking
- * should keep more popular redirects in cache.
- */
-
- r->headers_out.location = ngx_http_add_header(&r->headers_out,
- ngx_http_headers_out);
- if (r->headers_out.location == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->headers_out.location->value = redirect->data.value;
-
- return NGX_HTTP_MOVED_PERMANENTLY;
- }
-
- } else {
- redirect = NULL;
- }
-
-#endif
-
/* open file */
#if (NGX_WIN9X)
- /* TODO: redirect cache */
-
if (ngx_win32_version < NGX_WIN_NT) {
/*
@@ -285,9 +174,6 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
}
if (ngx_is_dir(&fi)) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "HTTP DIR: \"%s\"", name.data);
-
r->headers_out.location = ngx_http_add_header(&r->headers_out,
ngx_http_headers_out);
if (r->headers_out.location == NULL) {
@@ -356,59 +242,17 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
*last++ = '/';
*last = '\0';
- r->headers_out.location = ngx_list_push(&r->headers_out.headers);
+ r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
if (r->headers_out.location == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->headers_out.location->value = location;
-
-#if (NGX_HTTP_CACHE)
-
- if (slcf->redirect_cache) {
- if (redirect) {
- if (location.len == redirect->data.value.len
- && ngx_memcmp(redirect->data.value.data, location.data,
- location.len) == 0)
- {
- redirect->accessed = ngx_cached_time;
- redirect->updated = ngx_cached_time;
-
- /*
- * we can unlock the cache entry because
- * we have the local copy anyway
- */
-
- ngx_http_cache_unlock(slcf->redirect_cache, redirect, log);
- redirect_cleanup->valid = 0;
-
- return NGX_HTTP_MOVED_PERMANENTLY;
- }
- }
-
- location.len++;
- redirect = ngx_http_cache_alloc(slcf->redirect_cache, redirect,
- redirect_cleanup,
- &name, redirect_crc,
- &location, log);
- location.len--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http redirect cache alloc: %p", redirect);
-
- if (redirect) {
- redirect->fd = NGX_INVALID_FILE;
- redirect->accessed = ngx_cached_time;
- redirect->last_modified = 0;
- redirect->updated = ngx_cached_time;
- redirect->memory = 1;
- ngx_http_cache_unlock(slcf->redirect_cache, redirect, log);
- redirect_cleanup->valid = 0;
- }
-
- }
+ /*
+ * we do not need to set the r->headers_out.location->hash and
+ * r->headers_out.location->key fields
+ */
-#endif
+ r->headers_out.location->value = location;
return NGX_HTTP_MOVED_PERMANENTLY;
}
@@ -429,68 +273,20 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
#endif
+ log->action = "sending response to client";
-#if (NGX_HTTP_CACHE)
-
- if (clcf->open_files) {
-
-#if (NGX_USE_HTTP_FILE_CACHE_UNIQ)
-
- if (file && file->uniq == ngx_file_uniq(&fi)) {
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", name.data);
- }
- file->accessed = ngx_cached_time;
- file->updated = ngx_cached_time;
- file->expired = 0;
- r->cache = file;
-
- return ngx_http_send_cached(r);
-
- } else {
- if (file) {
- ngx_http_cache_unlock(clcf->open_files, file, log);
- file = NULL;
- }
-
- file = ngx_http_cache_alloc(clcf->open_files, file,
- file_cleanup,
- &name, file_crc, NULL, log);
- if (file) {
- file->uniq = ngx_file_uniq(&fi);
- }
- }
-
-#else
- file = ngx_http_cache_alloc(clcf->open_files, file,
- file_cleanup,
- &name, file_crc, NULL, log);
-#endif
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http open file cache alloc: %p", file);
-
- if (file) {
- file->fd = fd;
- file->data.size = ngx_file_size(&fi);
- file->accessed = ngx_cached_time;
- file->last_modified = ngx_file_mtime(&fi);
- file->updated = ngx_cached_time;
- r->cache = file;
- }
-
- return ngx_http_send_cached(r);
+ cln = ngx_palloc(r->pool, sizeof(ngx_pool_cleanup_file_t));
+ if (cln == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
-#endif
-
- log->action = "sending response to client";
+ cln->fd = fd;
+ cln->name = name.data;
+ cln->log = r->pool->log;
- file_cleanup->data.file.fd = fd;
- file_cleanup->data.file.name = name.data;
- file_cleanup->valid = 1;
- file_cleanup->cache = 0;
+ if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = ngx_file_size(&fi);
@@ -532,10 +328,12 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
b->in_file = 1;
- if (!r->main) {
+ if (r->main == NULL) {
b->last_buf = 1;
}
+ b->last_in_chain = 1;
+
b->file_pos = 0;
b->file_last = ngx_file_size(&fi);
@@ -550,7 +348,8 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
}
-static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf)
+static void *
+ngx_http_static_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_static_loc_conf_t *conf;
@@ -565,8 +364,8 @@ static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf)
}
-static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child)
+static char *
+ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_static_loc_conf_t *prev = parent;
ngx_http_static_loc_conf_t *conf = child;
@@ -579,7 +378,8 @@ static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
}
-static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle)
+static ngx_int_t
+ngx_http_static_init(ngx_cycle_t *cycle)
{
ngx_http_handler_pt *h;
ngx_http_core_main_conf_t *cmcf;
diff --git a/src/http/modules/ngx_http_stub_status_module.c b/src/http/modules/ngx_http_stub_status_module.c
index 1a01bcea8..0f1a252a8 100644
--- a/src/http/modules/ngx_http_stub_status_module.c
+++ b/src/http/modules/ngx_http_stub_status_module.c
@@ -22,7 +22,8 @@ static ngx_command_t ngx_http_status_commands[] = {
ngx_http_module_t ngx_http_stub_status_module_ctx = {
- NULL, /* pre conf */
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -36,7 +37,7 @@ ngx_http_module_t ngx_http_stub_status_module_ctx = {
ngx_module_t ngx_http_stub_status_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_stub_status_module_ctx, /* module context */
ngx_http_status_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -63,15 +64,8 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
return rc;
}
- r->headers_out.content_type = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.content_type == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->headers_out.content_type->key.len = 0;
- r->headers_out.content_type->key.data = NULL;
- r->headers_out.content_type->value.len = sizeof("text/plain") - 1;
- r->headers_out.content_type->value.data = (u_char *) "text/plain";
+ r->headers_out.content_type.len = sizeof("text/plain") - 1;
+ r->headers_out.content_type.data = (u_char *) "text/plain";
if (r->method == NGX_HTTP_HEAD) {
r->headers_out.status = NGX_HTTP_OK;
@@ -103,14 +97,14 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
rd = *ngx_stat_reading;
wr = *ngx_stat_writing;
- b->last = ngx_sprintf(b->last, "Active connections: %A \n", ac);
+ b->last = ngx_sprintf(b->last, "Active connections: %uA \n", ac);
b->last = ngx_cpymem(b->last, "server accepts handled requests\n",
sizeof("server accepts handled requests\n") - 1);
- b->last = ngx_sprintf(b->last, " %A %A %A \n", ap, hn, rq);
+ b->last = ngx_sprintf(b->last, " %uA %uA %uA \n", ap, hn, rq);
- b->last = ngx_sprintf(b->last, "Reading: %A Writing: %A Waiting: %A \n",
+ b->last = ngx_sprintf(b->last, "Reading: %uA Writing: %uA Waiting: %uA \n",
rd, wr, ac - (rd + wr));
r->headers_out.status = NGX_HTTP_OK;
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index 4889fbffd..af60d80b3 100644
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -19,7 +19,7 @@
typedef struct {
- ngx_flag_t enable;
+ ngx_uint_t enable;
ngx_int_t service;
@@ -83,7 +83,7 @@ static ngx_conf_enum_t ngx_http_userid_state[] = {
static ngx_conf_post_handler_pt ngx_http_userid_domain_p =
- ngx_http_userid_domain;
+ ngx_http_userid_domain;
static ngx_conf_post_handler_pt ngx_http_userid_path_p = ngx_http_userid_path;
static ngx_conf_post_handler_pt ngx_http_userid_p3p_p = ngx_http_userid_p3p;
@@ -145,7 +145,8 @@ static ngx_command_t ngx_http_userid_commands[] = {
ngx_http_module_t ngx_http_userid_filter_module_ctx = {
- ngx_http_userid_add_log_formats, /* pre conf */
+ ngx_http_userid_add_log_formats, /* preconfiguration */
+ NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
@@ -159,7 +160,7 @@ ngx_http_module_t ngx_http_userid_filter_module_ctx = {
ngx_module_t ngx_http_userid_filter_module = {
- NGX_MODULE,
+ NGX_MODULE_V1,
&ngx_http_userid_filter_module_ctx, /* module context */
ngx_http_userid_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
@@ -186,6 +187,10 @@ ngx_http_userid_filter(ngx_http_request_t *r)
ngx_http_userid_ctx_t *ctx;
ngx_http_userid_conf_t *conf;
+ if (r->main) {
+ return ngx_http_next_header_filter(r);
+ }
+
conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
if (conf->enable == NGX_HTTP_USERID_OFF) {
@@ -225,82 +230,47 @@ static ngx_int_t
ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
ngx_http_userid_conf_t *conf)
{
- u_char *start, *last, *end;
- ngx_uint_t i;
+ ngx_int_t n;
ngx_str_t src, dst;
ngx_table_elt_t **cookies;
- cookies = r->headers_in.cookies.elts;
-
- for (i = 0; i < r->headers_in.cookies.nelts; i++) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "cookie: \"%V\"", &cookies[i]->value);
-
- if (conf->name.len >= cookies[i]->value.len) {
- continue;
- }
-
- start = cookies[i]->value.data;
- end = cookies[i]->value.data + cookies[i]->value.len;
-
- while (start < end) {
-
- if (ngx_strncmp(start, conf->name.data, conf->name.len) != 0) {
-
- while (start < end && *start++ != ';') { /* void */ }
- while (start < end && *start == ' ') { start++; }
-
- continue;
- }
-
- start += conf->name.len;
-
- while (start < end && *start == ' ') { start++; }
-
- if (start == end || *start++ != '=') {
- /* the invalid "Cookie" header */
- break;
- }
-
- while (start < end && *start == ' ') { start++; }
-
- last = start;
+ n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
+ &src);
+ if (n == NGX_DECLINED) {
+ return NGX_OK;
+ }
- while (last < end && *last++ != ';') { /* void */ }
+ if (src.len < 22) {
+ cookies = r->headers_in.cookies.elts;
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "client sent too short userid cookie \"%V\"",
+ &cookies[n]->value);
+ return NGX_OK;
+ }
- if (last - start < 22) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent too short userid cookie \"%V\"",
- &cookies[i]->value);
- break;
- }
+ /*
+ * we have to limit encoded string to 22 characters
+ * because there are already the millions cookies with a garbage
+ * instead of the correct base64 trail "=="
+ */
- /*
- * we have to limit encoded string to 22 characters
- * because there are already the millions cookies with a garbage
- * instead of the correct base64 trail "=="
- */
-
- src.len = 22;
- src.data = start;
- dst.data = (u_char *) ctx->uid_got;
-
- if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid userid cookie \"%V\"",
- &cookies[i]->value);
- break;
- }
+ src.len = 22;
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uid: %08XD%08XD%08XD%08XD",
- ctx->uid_got[0], ctx->uid_got[1],
- ctx->uid_got[2], ctx->uid_got[3]);
+ dst.data = (u_char *) ctx->uid_got;
- return NGX_OK;
- }
+ if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
+ cookies = r->headers_in.cookies.elts;
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "client sent invalid userid cookie \"%V\"",
+ &cookies[n]->value);
+ return NGX_OK;
}
+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "uid: %08XD%08XD%08XD%08XD",
+ ctx->uid_got[0], ctx->uid_got[1],
+ ctx->uid_got[2], ctx->uid_got[3]);
+
return NGX_OK;
}
@@ -404,6 +374,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
return NGX_ERROR;
}
+ set_cookie->hash = 1;
set_cookie->key.len = sizeof("Set-Cookie") - 1;
set_cookie->key.data = (u_char *) "Set-Cookie";
set_cookie->value.len = p - cookie;
@@ -421,6 +392,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
return NGX_ERROR;
}
+ p3p->hash = 1;
p3p->key.len = sizeof("P3P") - 1;
p3p->key.data = (u_char *) "P3P";
p3p->value = conf->p3p;
@@ -570,7 +542,7 @@ ngx_http_userid_create_conf(ngx_conf_t *cf)
* conf->p3p.date = NULL;
*/
- conf->enable = NGX_CONF_UNSET;
+ conf->enable = NGX_CONF_UNSET_UINT;
conf->service = NGX_CONF_UNSET;
conf->expires = NGX_CONF_UNSET;
@@ -584,7 +556,8 @@ ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_userid_conf_t *prev = parent;
ngx_http_userid_conf_t *conf = child;
- ngx_conf_merge_value(conf->enable, prev->enable, NGX_HTTP_USERID_OFF);
+ ngx_conf_merge_unsigned_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, "");
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index 12d417176..bc91df9a1 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -311,7 +311,7 @@ static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = {
-ngx_http_header_t ngx_http_proxy_headers_in[] = {
+ngx_http_header0_t ngx_http_proxy_headers_in[] = {
{ ngx_string("Date"), offsetof(ngx_http_proxy_headers_in_t, date) },
{ ngx_string("Server"), offsetof(ngx_http_proxy_headers_in_t, server) },
@@ -490,13 +490,25 @@ static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p)
#endif
-void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
+void ngx_http_proxy_rd_check_broken_connection(ngx_http_request_t *r)
+{
+ ngx_http_proxy_check_broken_connection(r, r->connection->read);
+}
+
+
+void ngx_http_proxy_wr_check_broken_connection(ngx_http_request_t *r)
+{
+ ngx_http_proxy_check_broken_connection(r, r->connection->read);
+}
+
+
+void ngx_http_proxy_check_broken_connection(ngx_http_request_t *r,
+ ngx_event_t *ev)
{
int n;
char buf[1];
ngx_err_t err;
ngx_connection_t *c;
- ngx_http_request_t *r;
ngx_http_proxy_ctx_t *p;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0,
@@ -510,8 +522,7 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
return;
}
- c = ev->data;
- r = c->data;
+ c = r->connection;
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
ev->eof = 1;
@@ -542,8 +553,7 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
#endif
- c = ev->data;
- r = c->data;
+ c = r->connection;
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
n = recv(c->fd, buf, 1, MSG_PEEK);
@@ -712,13 +722,6 @@ void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc)
p->cache->ctx.file.fd);
}
- if (p->upstream && p->upstream->event_pipe) {
- r->file.fd = p->upstream->event_pipe->temp_file->file.fd;
-
- } else if (p->cache) {
- r->file.fd = p->cache->ctx.file.fd;
- }
-
if (rc == 0 && r->main == NULL) {
rc = ngx_http_send_last(r);
}
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h
index 2c9210f9c..11c24b1ea 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.h
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.h
@@ -249,7 +249,10 @@ void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p);
#endif
-void ngx_http_proxy_check_broken_connection(ngx_event_t *ev);
+void ngx_http_proxy_rd_check_broken_connection(ngx_http_request_t *r);
+void ngx_http_proxy_wr_check_broken_connection(ngx_http_request_t *r);
+void ngx_http_proxy_check_broken_connection(ngx_http_request_t *r,
+ ngx_event_t *ev);
void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev);
void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p);
@@ -265,7 +268,7 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p,
extern ngx_module_t ngx_http_proxy_module;
-extern ngx_http_header_t ngx_http_proxy_headers_in[];
+extern ngx_http_header0_t ngx_http_proxy_headers_in[];
diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c
index 107aba3df..0f17b953f 100644
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -24,6 +24,7 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev);
static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
+static void ngx_http_proxy_process_downstream(ngx_http_request_t *r);
static void ngx_http_proxy_process_body(ngx_event_t *ev);
static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p,
ngx_uint_t ft_type);
@@ -112,7 +113,7 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
len = http_methods[p->upstream->method - 1].len + uc->uri.len;
} else {
- len = r->method_name.len + uc->uri.len;
+ len = r->method_name.len + 1 + uc->uri.len;
}
if (p->lcf->pass_unparsed_uri && r->valid_unparsed_uri) {
@@ -261,7 +262,8 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
http_methods[p->upstream->method - 1].data,
http_methods[p->upstream->method - 1].len);
} else {
- b->last = ngx_cpymem(b->last, r->method_name.data, r->method_name.len);
+ b->last = ngx_cpymem(b->last, r->method_name.data,
+ r->method_name.len + 1);
}
b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len);
@@ -502,12 +504,11 @@ static void ngx_http_proxy_init_upstream(ngx_http_request_t *r)
ngx_del_timer(r->connection->read);
}
- r->connection->read->event_handler = ngx_http_proxy_check_broken_connection;
+ r->read_event_handler = ngx_http_proxy_rd_check_broken_connection;
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
- r->connection->write->event_handler =
- ngx_http_proxy_check_broken_connection;
+ r->write_event_handler = ngx_http_proxy_wr_check_broken_connection;
if (!r->connection->write->active) {
if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
@@ -770,8 +771,8 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
c = p->upstream->peer.connection;
c->data = p;
- c->write->event_handler = ngx_http_proxy_send_request_handler;
- c->read->event_handler = ngx_http_proxy_process_upstream_status_line;
+ c->write->handler = ngx_http_proxy_send_request_handler;
+ c->read->handler = ngx_http_proxy_process_upstream_status_line;
c->sendfile = r->connection->sendfile;
@@ -925,9 +926,9 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
}
#endif
- c->write->event_handler = ngx_http_proxy_dummy_handler;
+ c->write->handler = ngx_http_proxy_dummy_handler;
- if (ngx_handle_level_write_event(c->write) == NGX_ERROR) {
+ if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
@@ -1124,7 +1125,7 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev)
}
- c->read->event_handler = ngx_http_proxy_process_upstream_headers;
+ c->read->handler = ngx_http_proxy_process_upstream_headers;
ngx_http_proxy_process_upstream_headers(rev);
}
@@ -1174,7 +1175,7 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
rc = ngx_http_parse_header_line(p->request, p->header_in);
- if (rc == NGX_OK) {
+ if (rc == NGX_OK && !r->invalid_header) {
/* a header line has been parsed successfully */
@@ -1241,6 +1242,10 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
} else if (rc != NGX_AGAIN) {
+ if (r->invalid_header) {
+ rc = NGX_HTTP_PARSE_INVALID_HEADER;
+ }
+
/* there was error while a header line parsing */
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
@@ -1465,9 +1470,8 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
ep->send_timeout = clcf->send_timeout;
ep->send_lowat = clcf->send_lowat;
- p->upstream->peer.connection->read->event_handler =
- ngx_http_proxy_process_body;
- r->connection->write->event_handler = ngx_http_proxy_process_body;
+ p->upstream->peer.connection->read->handler = ngx_http_proxy_process_body;
+ r->write_event_handler = ngx_http_proxy_process_downstream;
ngx_http_proxy_process_body(p->upstream->peer.connection->read);
@@ -1475,6 +1479,12 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
}
+static void ngx_http_proxy_process_downstream(ngx_http_request_t *r)
+{
+ ngx_http_proxy_process_body(r->connection->write);
+}
+
+
static void ngx_http_proxy_process_body(ngx_event_t *ev)
{
ngx_connection_t *c;