diff options
author | Igor Sysoev <igor@sysoev.ru> | 2006-10-10 16:10:45 +0000 |
---|---|---|
committer | Jonathan Kolb <jon@b0g.us> | 2006-10-10 16:10:45 +0000 |
commit | 3c7373afd0117d9196e264d7a6a732c703d62c1c (patch) | |
tree | b74a138028fe7c94dde99b199318a5c8ee43b337 /src/http | |
parent | 3d565750a763f163a008160380b44853e146c511 (diff) | |
download | nginx-3c7373afd0117d9196e264d7a6a732c703d62c1c.tar.gz |
Changes with nginx 0.4.7 10 Oct 2006v0.4.7
*) Feature: the ngx_http_flv_module.
*) Feature: the $request_body_file variable.
*) Feature: the "charset" and "source_charset" directives support the
variables.
*) Bugfix: if before an "include" SSI command with an "wait" parameter
were yet another "include" SSI command, then the "wait" parameter
might not work.
*) Bugfix: if the "proxy_buffering off" directive was used or while
working with memcached the connections might not be closed on
timeout.
*) Bugfix: nginx did not run on 64-bit platforms except amd64, sparc64,
and ppc64.
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/modules/ngx_http_addition_filter_module.c | 7 | ||||
-rw-r--r-- | src/http/modules/ngx_http_browser_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_charset_filter_module.c | 63 | ||||
-rw-r--r-- | src/http/modules/ngx_http_fastcgi_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_flv_module.c | 255 | ||||
-rw-r--r-- | src/http/modules/ngx_http_proxy_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssi_filter_module.c | 20 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssi_filter_module.h | 2 | ||||
-rw-r--r-- | src/http/ngx_http.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 5 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.h | 3 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.c | 16 | ||||
-rw-r--r-- | src/http/ngx_http_variables.c | 30 |
13 files changed, 378 insertions, 31 deletions
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c index 9db87bda9..6f15a72cc 100644 --- a/src/http/modules/ngx_http_addition_filter_module.c +++ b/src/http/modules/ngx_http_addition_filter_module.c @@ -124,6 +124,7 @@ ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_int_t rc; ngx_uint_t last; ngx_chain_t *cl; + ngx_http_request_t *sr; ngx_http_addition_ctx_t *ctx; ngx_http_addition_conf_t *conf; @@ -143,7 +144,7 @@ ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->before_body_sent = 1; if (conf->before_body.len) { - if (ngx_http_subrequest(r, &conf->before_body, NULL, NULL, 0) + if (ngx_http_subrequest(r, &conf->before_body, NULL, &sr, NULL, 0) == NGX_ERROR) { return NGX_ERROR; @@ -167,7 +168,9 @@ ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return rc; } - if (ngx_http_subrequest(r, &conf->after_body, NULL, NULL, 0) == NGX_ERROR) { + if (ngx_http_subrequest(r, &conf->after_body, NULL, &sr, NULL, 0) + == NGX_ERROR) + { return NGX_ERROR; } diff --git a/src/http/modules/ngx_http_browser_module.c b/src/http/modules/ngx_http_browser_module.c index a2fb4bd36..98df6c575 100644 --- a/src/http/modules/ngx_http_browser_module.c +++ b/src/http/modules/ngx_http_browser_module.c @@ -61,7 +61,7 @@ static ngx_int_t ngx_http_browser_variable(ngx_http_request_t *r, static ngx_uint_t ngx_http_browser(ngx_http_request_t *r, ngx_http_browser_conf_t *cf); - + static ngx_int_t ngx_http_browser_add_variable(ngx_conf_t *cf); static void *ngx_http_browser_create_conf(ngx_conf_t *cf); static char *ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent, diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c index bf6ecc8cc..b9c9ade91 100644 --- a/src/http/modules/ngx_http_charset_filter_module.c +++ b/src/http/modules/ngx_http_charset_filter_module.c @@ -10,6 +10,7 @@ #define NGX_HTTP_NO_CHARSET -2 +#define NGX_HTTP_CHARSET_VAR 0x10000 /* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */ #define NGX_UTF_LEN 4 @@ -79,7 +80,7 @@ typedef struct { static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets, - ngx_uint_t n, u_char *charset); + ngx_uint_t n, ngx_str_t *charset); static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r, ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset); static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table); @@ -190,6 +191,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r) ngx_uint_t n; ngx_http_charset_t *charsets; ngx_http_charset_ctx_t *ctx; + ngx_http_variable_value_t *vv; ngx_http_charset_loc_conf_t *lcf, *mlcf; ngx_http_charset_main_conf_t *mcf; @@ -210,7 +212,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r) && r->headers_out.override_charset->len) { charset = ngx_http_charset_get_charset(charsets, n, - r->headers_out.override_charset->data); + r->headers_out.override_charset); if (charset == NGX_HTTP_NO_CHARSET) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, @@ -243,6 +245,14 @@ ngx_http_charset_header_filter(ngx_http_request_t *r) return ngx_http_next_header_filter(r); } } + + if (charset >= NGX_HTTP_CHARSET_VAR) { + vv = ngx_http_get_indexed_variable(r, + charset - NGX_HTTP_CHARSET_VAR); + + charset = ngx_http_charset_get_charset(charsets, n, + (ngx_str_t *) vv); + } } } else { @@ -263,7 +273,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r) ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module); - charset = ngx_http_charset_get_charset(charsets, n, mc->data); + charset = ngx_http_charset_get_charset(charsets, n, mc); ctx->charset = charset; @@ -277,23 +287,33 @@ ngx_http_charset_header_filter(ngx_http_request_t *r) if (r->headers_out.charset.len == 0) { lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); + source_charset = lcf->source_charset; + + if (source_charset >= NGX_HTTP_CHARSET_VAR) { + vv = ngx_http_get_indexed_variable(r, + source_charset - NGX_HTTP_CHARSET_VAR); + + source_charset = ngx_http_charset_get_charset(charsets, n, + (ngx_str_t *) vv); + } + if (charset != NGX_HTTP_NO_CHARSET) { return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset, - lcf->source_charset); + source_charset); } - if (lcf->source_charset == NGX_CONF_UNSET) { + if (source_charset == NGX_CONF_UNSET) { return ngx_http_next_header_filter(r); } - from = &charsets[lcf->source_charset].name; + from = &charsets[source_charset].name; to = &r->main->headers_out.charset; goto no_charset_map; } source_charset = ngx_http_charset_get_charset(charsets, n, - r->headers_out.charset.data); + &r->headers_out.charset); if (charset == NGX_HTTP_NO_CHARSET || source_charset == NGX_HTTP_NO_CHARSET) @@ -341,12 +361,19 @@ no_charset_map: static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n, - u_char *charset) + ngx_str_t *charset) { + size_t len; ngx_uint_t i; + len = charset->len & 0xffff; + for (i = 0; i < n; i++) { - if (ngx_strcasecmp(charsets[i].name.data, charset) == 0) { + if (charsets[i].name.len != len) { + continue; + } + + if (ngx_strncasecmp(charsets[i].name.data, charset->data, len) == 0) { return i; } } @@ -1261,7 +1288,7 @@ ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) char *p = conf; ngx_int_t *cp; - ngx_str_t *value; + ngx_str_t *value, var; ngx_http_charset_main_conf_t *mcf; cp = (ngx_int_t *) (p + cmd->offset); @@ -1279,6 +1306,22 @@ ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_OK; } + + if (value[1].data[0] == '$') { + var.len = value[1].len - 1; + var.data = value[1].data + 1; + + *cp = ngx_http_get_variable_index(cf, &var); + + if (*cp == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + *cp += NGX_HTTP_CHARSET_VAR; + + return NGX_CONF_OK; + } + mcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_charset_filter_module); diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index 98e098b49..cce31010c 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -1826,7 +1826,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) hash.hash = &conf->upstream.hide_headers_hash; hash.key = ngx_hash_key_lc; hash.max_size = 512; - hash.bucket_size = ngx_cacheline_size; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); hash.name = "fastcgi_hide_headers_hash"; hash.pool = cf->pool; hash.temp_pool = NULL; diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c new file mode 100644 index 000000000..7fa736d80 --- /dev/null +++ b/src/http/modules/ngx_http_flv_module.c @@ -0,0 +1,255 @@ + +/* + * Copyright (C) Igor Sysoev + */ + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_http.h> + + +static char *ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); + +static ngx_command_t ngx_http_flv_commands[] = { + + { ngx_string("flv"), + NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, + ngx_http_flv, + 0, + 0, + NULL }, + + ngx_null_command +}; + + +static u_char ngx_flv_header[] = "FLV\x1\x1\0\0\0\x9\0\0\0\x9"; + + +static ngx_http_module_t ngx_http_flv_module_ctx = { + NULL, /* preconfiguration */ + NULL, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL /* merge location configuration */ +}; + + +ngx_module_t ngx_http_flv_module = { + NGX_MODULE_V1, + &ngx_http_flv_module_ctx, /* module context */ + ngx_http_flv_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_flv_handler(ngx_http_request_t *r) +{ + u_char *p; + off_t start, len; + ngx_fd_t fd; + ngx_int_t rc; + ngx_uint_t level; + ngx_str_t path; + ngx_err_t err; + ngx_log_t *log; + ngx_buf_t *b; + ngx_chain_t out[2]; + ngx_file_info_t fi; + ngx_pool_cleanup_t *cln; + ngx_pool_cleanup_file_t *clnf; + ngx_http_core_loc_conf_t *clcf; + + if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { + return NGX_HTTP_NOT_ALLOWED; + } + + if (r->uri.data[r->uri.len - 1] == '/') { + return NGX_DECLINED; + } + + /* TODO: Win32 */ + if (r->zero_in_uri) { + return NGX_DECLINED; + } + + rc = ngx_http_discard_body(r); + + if (rc != NGX_OK && rc != NGX_AGAIN) { + return rc; + } + + if (ngx_http_map_uri_to_path(r, &path, 0) == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + log = r->connection->log; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, + "http flv filename: \"%s\"", path.data); + + cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); + if (cln == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN); + + if (fd == NGX_INVALID_FILE) { + err = ngx_errno; + + if (err == NGX_ENOENT + || err == NGX_ENOTDIR + || err == NGX_ENAMETOOLONG) + { + level = NGX_LOG_ERR; + rc = NGX_HTTP_NOT_FOUND; + + } else if (err == NGX_EACCES) { + level = NGX_LOG_ERR; + rc = NGX_HTTP_FORBIDDEN; + + } else { + level = NGX_LOG_CRIT; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) { + ngx_log_error(level, log, err, + ngx_open_file_n " \"%s\" failed", path.data); + } + + return rc; + } + + if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + ngx_fd_info_n " \"%s\" failed", path.data); + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", path.data); + } + + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (!ngx_is_file(&fi)) { + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", path.data); + } + + return NGX_DECLINED; + } + + start = 0; + len = ngx_file_size(&fi); + + if (r->args.len) { + p = (u_char *) ngx_strstr(r->args.data, "start="); + + if (p) { + p += 6; + + start = ngx_atoof(p, r->args.len - (p - r->args.data)); + + if (start == NGX_ERROR || start >= len) { + start = 0; + } + + len -= start; + } + } + + log->action = "sending flv to client"; + + cln->handler = ngx_pool_cleanup_file; + clnf = cln->data; + + clnf->fd = fd; + clnf->name = path.data; + clnf->log = r->pool->log; + + r->headers_out.status = NGX_HTTP_OK; + r->headers_out.content_length_n = sizeof(ngx_flv_header) - 1 + len; + r->headers_out.last_modified_time = ngx_file_mtime(&fi); + + if (ngx_http_set_content_type(r) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + if (b == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b->pos = ngx_flv_header; + b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1; + b->memory = 1; + + out[0].buf = b; + out[0].next = &out[1]; + + b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + if (b == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); + if (b->file == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + rc = ngx_http_send_header(r); + + if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { + return rc; + } + + b->file_pos = start; + b->file_last = ngx_file_size(&fi); + + b->in_file = b->file_last ? 1: 0; + b->last_buf = 1; + b->last_in_chain = 1; + + b->file->fd = fd; + b->file->name = path; + b->file->log = log; + + out[1].buf = b; + out[1].next = NULL; + + return ngx_http_output_filter(r, out); +} + + +static char * +ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_core_loc_conf_t *clcf; + + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + clcf->handler = ngx_http_flv_handler; + + return NGX_CONF_OK; +} diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index f4007be8e..f85454968 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1823,7 +1823,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) hash.hash = &conf->upstream.hide_headers_hash; hash.key = ngx_hash_key_lc; hash.max_size = 512; - hash.bucket_size = ngx_cacheline_size; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); hash.name = "proxy_hide_headers_hash"; hash.pool = cf->pool; hash.temp_pool = NULL; diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c index 8faf14c72..dc0cb74fb 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -417,10 +417,11 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_AGAIN; } - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http ssi filter \"%V\" continue", &r->uri); - - ctx->wait = 0; + if (ctx->wait == r) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http ssi filter \"%V\" continue", &r->uri); + ctx->wait = NULL; + } } slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); @@ -1814,6 +1815,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_buf_t *b; ngx_uint_t flags, i; ngx_chain_t *out, *cl, *tl, **ll; + ngx_http_request_t *sr; ngx_http_ssi_ctx_t *mctx; ngx_http_ssi_block_t *bl; @@ -1936,7 +1938,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, } } - rc = ngx_http_subrequest(r, uri, &args, out, flags); + rc = ngx_http_subrequest(r, uri, &args, &sr, out, flags); if (rc == NGX_ERROR) { return NGX_HTTP_SSI_ERROR; @@ -1947,7 +1949,13 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, } if (rc == NGX_AGAIN) { - ctx->wait = 1; + if (ctx->wait == NULL) { + ctx->wait = sr; + + } else { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "only one subrequest may be waited at the same time"); + } } return rc; diff --git a/src/http/modules/ngx_http_ssi_filter_module.h b/src/http/modules/ngx_http_ssi_filter_module.h index dc3eff064..2891969e3 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.h +++ b/src/http/modules/ngx_http_ssi_filter_module.h @@ -63,8 +63,8 @@ typedef struct { unsigned block:1; unsigned output:1; unsigned output_chosen:1; - unsigned wait:1; + ngx_http_request_t *wait; void *value_buf; ngx_str_t timefmt; ngx_str_t errmsg; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 395282d85..7a1eb89b3 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -365,7 +365,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) hash.hash = &cmcf->headers_in_hash; hash.key = ngx_hash_key_lc; hash.max_size = 512; - hash.bucket_size = ngx_cacheline_size; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); hash.name = "headers_in_hash"; hash.pool = cf->pool; hash.temp_pool = NULL; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index fc24d904f..c132a2d52 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1283,7 +1283,8 @@ ngx_http_auth_basic_user(ngx_http_request_t *r) ngx_int_t ngx_http_subrequest(ngx_http_request_t *r, - ngx_str_t *uri, ngx_str_t *args, ngx_chain_t *out, ngx_uint_t flags) + ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr, + ngx_chain_t *out, ngx_uint_t flags) { ngx_connection_t *c; ngx_http_request_t *sr; @@ -1417,6 +1418,8 @@ ngx_http_subrequest(ngx_http_request_t *r, ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http subrequest done \"%V?%V\"", uri, &sr->args); + *psr = sr; + if (sr->fast_subrequest) { sr->fast_subrequest = 0; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 50156b1b2..f8ea3281a 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -305,7 +305,8 @@ u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name, ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r); ngx_int_t ngx_http_subrequest(ngx_http_request_t *r, - ngx_str_t *uri, ngx_str_t *args, ngx_chain_t *out, ngx_uint_t flags); + ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **sr, + ngx_chain_t *out, ngx_uint_t flags); ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args); diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 2cdfdc8ba..e4a4d4058 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -1137,6 +1137,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev) umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); if (r->upstream->headers_in.x_accel_redirect) { + ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); part = &r->upstream->headers_in.headers.part; @@ -1159,8 +1160,8 @@ ngx_http_upstream_process_header(ngx_event_t *rev) if (hh && hh->redirect) { if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, - NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_http_finalize_request(r, + NGX_HTTP_INTERNAL_SERVER_ERROR); return; } } @@ -1172,7 +1173,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev) flags = 0; if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND); + ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); return; } @@ -1500,6 +1501,8 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) ngx_http_core_loc_conf_t *clcf; c = ev->data; + r = c->data; + u = r->upstream; if (ev->write) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, @@ -1520,10 +1523,11 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) } else { ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); } + + ngx_http_upstream_finalize_request(r, u, 0); + return; } - r = c->data; - u = r->upstream; client = r->connection; b = &u->buffer; @@ -2941,7 +2945,7 @@ ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf) hash.hash = &umcf->headers_in_hash; hash.key = ngx_hash_key_lc; hash.max_size = 512; - hash.bucket_size = ngx_cacheline_size; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); hash.name = "upstream_headers_in_hash"; hash.pool = cf->pool; hash.temp_pool = NULL; diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 374a29e70..9dee6ee9e 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -50,6 +50,8 @@ static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -170,6 +172,10 @@ static ngx_http_variable_t ngx_http_core_variables[] = { ngx_http_variable_request_completion, 0, 0, 0 }, + { ngx_string("request_body_file"), NULL, + ngx_http_variable_request_body_file, + 0, 0, 0 }, + { ngx_string("sent_http_content_type"), NULL, ngx_http_variable_sent_content_type, 0, 0, 0 }, @@ -1134,6 +1140,30 @@ ngx_http_variable_request_completion(ngx_http_request_t *r, } +static ngx_int_t +ngx_http_variable_request_body_file(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + if (r->request_body == NULL || r->request_body->temp_file == NULL) { + v->len = 0; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = (u_char *) ""; + + return NGX_OK; + } + + v->len = r->request_body->temp_file->file.name.len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = r->request_body->temp_file->file.name.data; + + return NGX_OK; +} + + ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf) { |