summaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
authornginx <nginx@nginx.org>2013-08-27 14:05:15 +0000
committerJon Kolb <jon@b0g.us>2013-08-27 14:05:15 +0000
commitb4f0587460c1cec132bbf547b658057a674aa94e (patch)
tree1a3cc61bb188774ed3c180f6d09e99b2428e0ed8 /src/http
parentc1d6dbb45ec3f5494f8d94d51e44807e04eda5fc (diff)
downloadnginx-b4f0587460c1cec132bbf547b658057a674aa94e.tar.gz
Changes with nginx 1.5.4 27 Aug 2013v1.5.4
*) Change: the "js" extension MIME type has been changed to "application/javascript"; default value of the "charset_types" directive was changed accordingly. *) Change: now the "image_filter" directive with the "size" parameter returns responses with the "application/json" MIME type. *) Feature: the ngx_http_auth_request_module. *) Bugfix: a segmentation fault might occur on start or during reconfiguration if the "try_files" directive was used with an empty parameter. *) Bugfix: memory leak if relative paths were specified using variables in the "root" or "auth_basic_user_file" directives. *) Bugfix: the "valid_referers" directive incorrectly executed regular expressions if a "Referer" header started with "https://". Thanks to Liangbin Li. *) Bugfix: responses might hang if subrequests were used and an SSL handshake error happened during subrequest processing. Thanks to Aviram Cohen. *) Bugfix: in the ngx_http_autoindex_module. *) Bugfix: in the ngx_http_spdy_module.
Diffstat (limited to 'src/http')
-rw-r--r--src/http/modules/ngx_http_auth_request_module.c444
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c6
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_referer_module.c4
-rw-r--r--src/http/ngx_http_core_module.c14
-rw-r--r--src/http/ngx_http_file_cache.c3
-rw-r--r--src/http/ngx_http_parse.c3
-rw-r--r--src/http/ngx_http_script.c9
-rw-r--r--src/http/ngx_http_spdy.c26
-rw-r--r--src/http/ngx_http_special_response.c2
-rw-r--r--src/http/ngx_http_upstream.c6
-rw-r--r--src/http/ngx_http_variables.c10
13 files changed, 506 insertions, 25 deletions
diff --git a/src/http/modules/ngx_http_auth_request_module.c b/src/http/modules/ngx_http_auth_request_module.c
new file mode 100644
index 000000000..b4307be2e
--- /dev/null
+++ b/src/http/modules/ngx_http_auth_request_module.c
@@ -0,0 +1,444 @@
+
+/*
+ * Copyright (C) Maxim Dounin
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+ ngx_str_t uri;
+ ngx_array_t *vars;
+} ngx_http_auth_request_conf_t;
+
+
+typedef struct {
+ ngx_uint_t done;
+ ngx_uint_t status;
+ ngx_http_request_t *subrequest;
+} ngx_http_auth_request_ctx_t;
+
+
+typedef struct {
+ ngx_int_t index;
+ ngx_http_complex_value_t value;
+ ngx_http_set_variable_pt set_handler;
+} ngx_http_auth_request_variable_t;
+
+
+static ngx_int_t ngx_http_auth_request_handler(ngx_http_request_t *r);
+static ngx_int_t ngx_http_auth_request_done(ngx_http_request_t *r,
+ void *data, ngx_int_t rc);
+static ngx_int_t ngx_http_auth_request_set_variables(ngx_http_request_t *r,
+ ngx_http_auth_request_conf_t *arcf, ngx_http_auth_request_ctx_t *ctx);
+static ngx_int_t ngx_http_auth_request_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+static void *ngx_http_auth_request_create_conf(ngx_conf_t *cf);
+static char *ngx_http_auth_request_merge_conf(ngx_conf_t *cf,
+ void *parent, void *child);
+static ngx_int_t ngx_http_auth_request_init(ngx_conf_t *cf);
+static char *ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_http_auth_request_set(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+
+
+static ngx_command_t ngx_http_auth_request_commands[] = {
+
+ { ngx_string("auth_request"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_auth_request,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("auth_request_set"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_http_auth_request_set,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_http_module_t ngx_http_auth_request_module_ctx = {
+ NULL, /* preconfiguration */
+ ngx_http_auth_request_init, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ ngx_http_auth_request_create_conf, /* create location configuration */
+ ngx_http_auth_request_merge_conf /* merge location configuration */
+};
+
+
+ngx_module_t ngx_http_auth_request_module = {
+ NGX_MODULE_V1,
+ &ngx_http_auth_request_module_ctx, /* module context */
+ ngx_http_auth_request_commands, /* module directives */
+ NGX_HTTP_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_int_t
+ngx_http_auth_request_handler(ngx_http_request_t *r)
+{
+ ngx_table_elt_t *h, *ho;
+ ngx_http_request_t *sr;
+ ngx_http_post_subrequest_t *ps;
+ ngx_http_auth_request_ctx_t *ctx;
+ ngx_http_auth_request_conf_t *arcf;
+
+ arcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_request_module);
+
+ if (arcf->uri.len == 0) {
+ return NGX_DECLINED;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "auth request handler");
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_auth_request_module);
+
+ if (ctx != NULL) {
+ if (!ctx->done) {
+ return NGX_AGAIN;
+ }
+
+ /*
+ * as soon as we are done - explicitly set variables to make
+ * sure they will be available after internal redirects
+ */
+
+ if (ngx_http_auth_request_set_variables(r, arcf, ctx) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ /* return appropriate status */
+
+ if (ctx->status == NGX_HTTP_FORBIDDEN) {
+ return ctx->status;
+ }
+
+ if (ctx->status == NGX_HTTP_UNAUTHORIZED) {
+ sr = ctx->subrequest;
+
+ h = sr->headers_out.www_authenticate;
+
+ if (!h && sr->upstream) {
+ h = sr->upstream->headers_in.www_authenticate;
+ }
+
+ if (h) {
+ ho = ngx_list_push(&r->headers_out.headers);
+ if (ho == NULL) {
+ return NGX_ERROR;
+ }
+
+ *ho = *h;
+
+ r->headers_out.www_authenticate = ho;
+ }
+
+ return ctx->status;
+ }
+
+ if (ctx->status >= NGX_HTTP_OK
+ && ctx->status < NGX_HTTP_SPECIAL_RESPONSE)
+ {
+ return NGX_OK;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "auth request unexpected status: %d", ctx->status);
+
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_auth_request_ctx_t));
+ if (ctx == NULL) {
+ return NGX_ERROR;
+ }
+
+ ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
+ if (ps == NULL) {
+ return NGX_ERROR;
+ }
+
+ ps->handler = ngx_http_auth_request_done;
+ ps->data = ctx;
+
+ if (ngx_http_subrequest(r, &arcf->uri, NULL, &sr, ps,
+ NGX_HTTP_SUBREQUEST_WAITED)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ /*
+ * allocate fake request body to avoid attempts to read it and to make
+ * sure real body file (if already read) won't be closed by upstream
+ */
+
+ sr->request_body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
+ if (sr->request_body == NULL) {
+ return NGX_ERROR;
+ }
+
+ sr->header_only = 1;
+
+ ctx->subrequest = sr;
+
+ ngx_http_set_ctx(r, ctx, ngx_http_auth_request_module);
+
+ return NGX_AGAIN;
+}
+
+
+static ngx_int_t
+ngx_http_auth_request_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
+{
+ ngx_http_auth_request_ctx_t *ctx = data;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "auth request done s:%d", r->headers_out.status);
+
+ ctx->done = 1;
+ ctx->status = r->headers_out.status;
+
+ return rc;
+}
+
+
+static ngx_int_t
+ngx_http_auth_request_set_variables(ngx_http_request_t *r,
+ ngx_http_auth_request_conf_t *arcf, ngx_http_auth_request_ctx_t *ctx)
+{
+ ngx_str_t val;
+ ngx_http_variable_t *v;
+ ngx_http_variable_value_t *vv;
+ ngx_http_auth_request_variable_t *av, *last;
+ ngx_http_core_main_conf_t *cmcf;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "auth request set variables");
+
+ if (arcf->vars == NULL) {
+ return NGX_OK;
+ }
+
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+ v = cmcf->variables.elts;
+
+ av = arcf->vars->elts;
+ last = av + arcf->vars->nelts;
+
+ while (av < last) {
+ /*
+ * explicitly set new value to make sure it will be available after
+ * internal redirects
+ */
+
+ vv = &r->variables[av->index];
+
+ if (ngx_http_complex_value(ctx->subrequest, &av->value, &val)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ vv->valid = 1;
+ vv->not_found = 0;
+ vv->data = val.data;
+ vv->len = val.len;
+
+ if (av->set_handler) {
+ /*
+ * set_handler only available in cmcf->variables_keys, so we store
+ * it explicitly
+ */
+
+ av->set_handler(r, vv, v[av->index].data);
+ }
+
+ av++;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_auth_request_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "auth request variable");
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static void *
+ngx_http_auth_request_create_conf(ngx_conf_t *cf)
+{
+ ngx_http_auth_request_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_request_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ /*
+ * set by ngx_pcalloc():
+ *
+ * conf->uri = { 0, NULL };
+ */
+
+ conf->vars = NGX_CONF_UNSET_PTR;
+
+ return conf;
+}
+
+
+static char *
+ngx_http_auth_request_merge_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_http_auth_request_conf_t *prev = parent;
+ ngx_http_auth_request_conf_t *conf = child;
+
+ ngx_conf_merge_str_value(conf->uri, prev->uri, "");
+ ngx_conf_merge_ptr_value(conf->vars, prev->vars, NULL);
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_auth_request_init(ngx_conf_t *cf)
+{
+ ngx_http_handler_pt *h;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
+
+ h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ *h = ngx_http_auth_request_handler;
+
+ return NGX_OK;
+}
+
+
+static char *
+ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_auth_request_conf_t *arcf = conf;
+
+ ngx_str_t *value;
+
+ if (arcf->uri.data != NULL) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ arcf->uri.len = 0;
+ arcf->uri.data = (u_char *) "";
+
+ return NGX_CONF_OK;
+ }
+
+ arcf->uri = value[1];
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_auth_request_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_auth_request_conf_t *arcf = conf;
+
+ ngx_str_t *value;
+ ngx_http_variable_t *v;
+ ngx_http_auth_request_variable_t *av;
+ ngx_http_compile_complex_value_t ccv;
+
+ value = cf->args->elts;
+
+ if (value[1].data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ value[1].len--;
+ value[1].data++;
+
+ if (arcf->vars == NGX_CONF_UNSET_PTR) {
+ arcf->vars = ngx_array_create(cf->pool, 1,
+ sizeof(ngx_http_auth_request_variable_t));
+ if (arcf->vars == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ av = ngx_array_push(arcf->vars);
+ if (av == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
+ if (v == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ av->index = ngx_http_get_variable_index(cf, &value[1]);
+ if (av->index == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (v->get_handler == NULL) {
+ v->get_handler = ngx_http_auth_request_variable;
+ v->data = (uintptr_t) av;
+ }
+
+ av->set_handler = v->set_handler;
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[2];
+ ccv.complex_value = &av->value;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index e3dcfd07e..221455120 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -304,7 +304,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) {
err = ngx_errno;
- if (err != NGX_ENOENT) {
+ if (err != NGX_ENOENT && err != NGX_ELOOP) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
ngx_de_info_n " \"%s\" failed", filename);
@@ -388,7 +388,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
b = ngx_create_temp_buf(r->pool, len);
if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
if (entries.nelts > 1) {
@@ -649,7 +649,7 @@ ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, ngx_str_t *name)
ngx_close_dir_n " \"%V\" failed", name);
}
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return r->header_sent ? NGX_ERROR : NGX_HTTP_INTERNAL_SERVER_ERROR;
}
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 27a00d09a..c9b7e9e89 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -128,7 +128,7 @@ ngx_str_t ngx_http_charset_default_types[] = {
ngx_string("text/xml"),
ngx_string("text/plain"),
ngx_string("text/vnd.wap.wml"),
- ngx_string("application/x-javascript"),
+ ngx_string("application/javascript"),
ngx_string("application/rss+xml"),
ngx_null_string
};
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index c6c3b747a..6d3f47dcb 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -567,7 +567,7 @@ ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
ngx_http_clean_header(r);
r->headers_out.status = NGX_HTTP_OK;
- ngx_str_set(&r->headers_out.content_type, "text/plain");
+ ngx_str_set(&r->headers_out.content_type, "application/json");
r->headers_out.content_type_lowcase = NULL;
if (ctx == NULL) {
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index d18b8b9d8..85b75ab3d 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -147,10 +147,12 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) {
ref += 7;
+ len -= 7;
goto valid_scheme;
} else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) {
ref += 8;
+ len -= 8;
goto valid_scheme;
}
}
@@ -191,7 +193,7 @@ valid_scheme:
ngx_int_t rc;
ngx_str_t referer;
- referer.len = len - 7;
+ referer.len = len;
referer.data = ref;
rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 12a82eb9c..85b4fe882 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1933,6 +1933,12 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
ngx_int_t
ngx_http_send_header(ngx_http_request_t *r)
{
+ if (r->header_sent) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "header already sent");
+ return NGX_ERROR;
+ }
+
if (r->err_status) {
r->headers_out.status = r->err_status;
r->headers_out.status_line.len = 0;
@@ -2016,7 +2022,9 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
return NULL;
}
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) {
+ if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, path)
+ != NGX_OK)
+ {
return NULL;
}
@@ -4758,7 +4766,9 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
tf[i].name = value[i + 1];
- if (tf[i].name.data[tf[i].name.len - 1] == '/') {
+ if (tf[i].name.len > 0
+ && tf[i].name.data[tf[i].name.len - 1] == '/')
+ {
tf[i].test_dir = 1;
tf[i].name.len--;
tf[i].name.data[tf[i].name.len] = '\0';
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index eacca595a..cf27683e6 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -445,8 +445,7 @@ ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev)
timer = c->wait_time - ngx_current_msec;
if ((ngx_msec_int_t) timer <= 0) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "http file cache lock timeout");
+ ngx_log_error(NGX_LOG_INFO, ev->log, 0, "cache lock timeout");
c->lock = 0;
goto wakeup;
}
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 697d856a0..973bc7430 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -212,14 +212,17 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
case 5:
if (ngx_str5cmp(m, 'M', 'K', 'C', 'O', 'L')) {
r->method = NGX_HTTP_MKCOL;
+ break;
}
if (ngx_str5cmp(m, 'P', 'A', 'T', 'C', 'H')) {
r->method = NGX_HTTP_PATCH;
+ break;
}
if (ngx_str5cmp(m, 'T', 'R', 'A', 'C', 'E')) {
r->method = NGX_HTTP_TRACE;
+ break;
}
break;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 54d019589..5fc4cfca0 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1327,16 +1327,17 @@ ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
{
ngx_http_script_full_name_code_t *code;
- ngx_str_t value;
+ ngx_str_t value, *prefix;
code = (ngx_http_script_full_name_code_t *) e->ip;
value.data = e->buf.data;
value.len = e->pos - e->buf.data;
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->conf_prefix)
- != NGX_OK)
- {
+ prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
+ (ngx_str_t *) &ngx_cycle->prefix;
+
+ if (ngx_get_full_name(e->request->pool, prefix, &value) != NGX_OK) {
e->ip = ngx_http_script_exit;
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
return;
diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c
index f8136213a..e7bebccd5 100644
--- a/src/http/ngx_http_spdy.c
+++ b/src/http/ngx_http_spdy.c
@@ -809,6 +809,8 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
sc->zstream_in.next_in = pos;
sc->zstream_in.avail_in = size;
sc->zstream_in.next_out = buf->last;
+
+ /* one byte is reserved for null-termination of the last header value */
sc->zstream_in.avail_out = buf->end - buf->last - 1;
z = inflate(&sc->zstream_in, Z_NO_FLUSH);
@@ -912,9 +914,14 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
return ngx_http_spdy_state_headers_error(sc, pos, end);
}
+ /* null-terminate the last processed header name or value */
+ *buf->pos = '\0';
+
buf = r->header_in;
sc->zstream_in.next_out = buf->last;
+
+ /* one byte is reserved for null-termination */
sc->zstream_in.avail_out = buf->end - buf->last - 1;
z = inflate(&sc->zstream_in, Z_NO_FLUSH);
@@ -996,6 +1003,9 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
ngx_http_spdy_state_headers);
}
+ /* null-terminate the last header value */
+ *buf->pos = '\0';
+
ngx_http_spdy_run_request(r);
return ngx_http_spdy_state_complete(sc, pos, end);
@@ -1936,6 +1946,9 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
return NGX_HTTP_PARSE_INVALID_HEADER;
}
+ /* null-terminate the previous header value */
+ *p = '\0';
+
p += NGX_SPDY_NV_NLEN_SIZE;
r->header_name_end = p + len;
@@ -2001,9 +2014,8 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
len = ngx_spdy_frame_parse_uint16(p);
- if (!len) {
- return NGX_ERROR;
- }
+ /* null-terminate header name */
+ *p = '\0';
p += NGX_SPDY_NV_VLEN_SIZE;
@@ -2163,11 +2175,9 @@ ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
h->key.len = r->lowcase_index;
h->key.data = r->header_name_start;
- h->key.data[h->key.len] = '\0';
h->value.len = r->header_size;
h->value.data = r->header_start;
- h->value.data[h->value.len] = '\0';
h->lowcase_key = h->key.data;
@@ -2653,7 +2663,8 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
ev = fc->read;
if (ev->active || ev->disabled) {
- ngx_del_event(ev, NGX_READ_EVENT, 0);
+ ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
+ "spdy fake read event was activated");
}
if (ev->timer_set) {
@@ -2667,7 +2678,8 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
ev = fc->write;
if (ev->active || ev->disabled) {
- ngx_del_event(ev, NGX_WRITE_EVENT, 0);
+ ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
+ "spdy fake write event was activated");
}
if (ev->timer_set) {
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 875c24d9c..546400539 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -370,7 +370,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
ngx_http_core_loc_conf_t *clcf;
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http special response: %d, \"%V?%V\"",
+ "http special response: %i, \"%V?%V\"",
error, &r->uri, &r->args);
r->err_status = error;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 9e2830d07..652222f8f 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1338,13 +1338,19 @@ ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
c->write->handler = ngx_http_upstream_handler;
c->read->handler = ngx_http_upstream_handler;
+ c = r->connection;
+
ngx_http_upstream_send_request(r, u);
+ ngx_http_run_posted_requests(c);
return;
}
+ c = r->connection;
+
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
+ ngx_http_run_posted_requests(c);
}
#endif
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 0b1a33430..4138bda42 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -487,7 +487,7 @@ ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
if (cmcf->variables.nelts <= index) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "unknown variable index: %d", index);
+ "unknown variable index: %ui", index);
return NULL;
}
@@ -1374,7 +1374,9 @@ ngx_http_variable_document_root(ngx_http_request_t *r,
return NGX_ERROR;
}
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0) != NGX_OK) {
+ if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, &path)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
@@ -1416,7 +1418,9 @@ ngx_http_variable_realpath_root(ngx_http_request_t *r,
path.data[path.len - 1] = '\0';
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0) != NGX_OK) {
+ if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, &path)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
}