diff options
author | nginx <nginx@nginx.org> | 2013-08-27 14:05:15 +0000 |
---|---|---|
committer | Jon Kolb <jon@b0g.us> | 2013-08-27 14:05:15 +0000 |
commit | b4f0587460c1cec132bbf547b658057a674aa94e (patch) | |
tree | 1a3cc61bb188774ed3c180f6d09e99b2428e0ed8 /src/http | |
parent | c1d6dbb45ec3f5494f8d94d51e44807e04eda5fc (diff) | |
download | nginx-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.c | 444 | ||||
-rw-r--r-- | src/http/modules/ngx_http_autoindex_module.c | 6 | ||||
-rw-r--r-- | src/http/modules/ngx_http_charset_filter_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_image_filter_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_referer_module.c | 4 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 14 | ||||
-rw-r--r-- | src/http/ngx_http_file_cache.c | 3 | ||||
-rw-r--r-- | src/http/ngx_http_parse.c | 3 | ||||
-rw-r--r-- | src/http/ngx_http_script.c | 9 | ||||
-rw-r--r-- | src/http/ngx_http_spdy.c | 26 | ||||
-rw-r--r-- | src/http/ngx_http_special_response.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.c | 6 | ||||
-rw-r--r-- | src/http/ngx_http_variables.c | 10 |
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; } } |