summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2006-10-10 16:10:45 +0000
committerJonathan Kolb <jon@b0g.us>2006-10-10 16:10:45 +0000
commit3c7373afd0117d9196e264d7a6a732c703d62c1c (patch)
treeb74a138028fe7c94dde99b199318a5c8ee43b337
parent3d565750a763f163a008160380b44853e146c511 (diff)
downloadnginx-0.4.7.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.
-rw-r--r--CHANGES21
-rw-r--r--CHANGES.ru22
-rw-r--r--auto/modules5
-rw-r--r--auto/options3
-rw-r--r--auto/sources4
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/event/modules/ngx_eventport_module.c2
-rw-r--r--src/http/modules/ngx_http_addition_filter_module.c7
-rw-r--r--src/http/modules/ngx_http_browser_module.c2
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c63
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c2
-rw-r--r--src/http/modules/ngx_http_flv_module.c255
-rw-r--r--src/http/modules/ngx_http_proxy_module.c2
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c20
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.h2
-rw-r--r--src/http/ngx_http.c2
-rw-r--r--src/http/ngx_http_core_module.c5
-rw-r--r--src/http/ngx_http_core_module.h3
-rw-r--r--src/http/ngx_http_upstream.c16
-rw-r--r--src/http/ngx_http_variables.c30
-rw-r--r--src/os/unix/ngx_sunpro_x86.map2
21 files changed, 435 insertions, 35 deletions
diff --git a/CHANGES b/CHANGES
index f7f274f79..8e343ed7b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,25 @@
+Changes with nginx 0.4.7 10 Oct 2006
+
+ *) 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.
+
+
Changes with nginx 0.4.6 06 Oct 2006
*) Bugfix: nginx did not run on 64-bit platforms except amd64, sparc64,
diff --git a/CHANGES.ru b/CHANGES.ru
index d604acdba..3e12599b9 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,7 +1,27 @@
+Изменения в nginx 0.4.7 10.10.2006
+
+ *) Добавление: модуль ngx_http_flv_module.
+
+ *) Добавление: переменная $request_body_file.
+
+ *) Добавление: директивы charset и source_charset поддерживают
+ переменные.
+
+ *) Исправление: если до команды SSI include с параметром wait
+ выполнялась ещё одна команда SSI include, то параметр wait мог не
+ работать.
+
+ *) Исправление: при использовании директивы "proxy_buffering off" или
+ при работе с memcached соединения могли не закрываться по таймауту.
+
+ *) Исправление: nginx не запускался на 64-битных платформах, отличных
+ от amd64, sparc64 и ppc64.
+
+
Изменения в nginx 0.4.6 06.10.2006
- *) Исправление: nginx не запускался на 64-битных платформах, отличной
+ *) Исправление: nginx не запускался на 64-битных платформах, отличных
от amd64, sparc64 и ppc64.
*) Исправление: при запросе версии HTTP/1.1 nginx передавал ответ
diff --git a/auto/modules b/auto/modules
index 4c8cca0f5..929cad0aa 100644
--- a/auto/modules
+++ b/auto/modules
@@ -250,6 +250,11 @@ if [ $HTTP_BROWSER = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_BROWSER_SRCS"
fi
+if [ $HTTP_FLV = YES ]; then
+ HTTP_MODULES="$HTTP_MODULES $HTTP_FLV_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
+fi
+
# STUB
#USE_MD5=YES
#HTTP_SRCS="$HTTP_SRCS $HTPP_CACHE_SRCS"
diff --git a/auto/options b/auto/options
index 7c5969839..a3b1b5d13 100644
--- a/auto/options
+++ b/auto/options
@@ -70,6 +70,7 @@ HTTP_PERL=NO
HTTP_MEMCACHED=YES
HTTP_EMPTY_GIF=YES
HTTP_BROWSER=YES
+HTTP_FLV=NO
# STUB
HTTP_STUB_STATUS=NO
@@ -150,6 +151,7 @@ do
--with-http_realip_module) HTTP_REALIP=YES ;;
--with-http_addition_module) HTTP_ADDITION=YES ;;
--with-http_dav_module) HTTP_DAV=YES ;;
+ --with-http_flv_module) HTTP_FLV=YES ;;
--without-http_charset_module) HTTP_CHARSET=NO ;;
--without-http_gzip_module) HTTP_GZIP=NO ;;
@@ -251,6 +253,7 @@ cat << END
--with-http_realip_module enable ngx_http_realip_module
--with-http_addition_module enable ngx_http_addition_module
--with-http_dav_module enable ngx_http_dav_module
+ --with-http_flv_module enable ngx_http_flv_module
--without-http_charset_module disable ngx_http_charset_module
--without-http_gzip_module disable ngx_http_gzip_module
diff --git a/auto/sources b/auto/sources
index 613c5820b..5af4dce38 100644
--- a/auto/sources
+++ b/auto/sources
@@ -393,6 +393,10 @@ HTTP_BROWSER_MODULE=ngx_http_browser_module
HTTP_BROWSER_SRCS=src/http/modules/ngx_http_browser_module.c
+HTTP_FLV_MODULE=ngx_http_flv_module
+HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
+
+
IMAP_INCS="src/imap"
IMAP_DEPS="src/imap/ngx_imap.h"
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 707a07168..486d5a8f9 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VER "nginx/0.4.6"
+#define NGINX_VER "nginx/0.4.7"
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index 0334d44e0..740cf4dfd 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -498,7 +498,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
wev->active = 0;
if (revents & POLLIN) {
-
+
if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
rev->posted_ready = 1;
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)
{
diff --git a/src/os/unix/ngx_sunpro_x86.map b/src/os/unix/ngx_sunpro_x86.map
index a73f2289c..971dda649 100644
--- a/src/os/unix/ngx_sunpro_x86.map
+++ b/src/os/unix/ngx_sunpro_x86.map
@@ -1,2 +1,2 @@
# disable { PAUSE ] hwcap for Sun Studio 11
-hwcap_1 = OVERRIDE;
+hwcap_1 = OVERRIDE;