summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-06-30 12:39:01 +0000
committerJonathan Kolb <jon@b0g.us>2008-06-30 12:39:01 +0000
commitc7d870cc248c868cdd9c4c2ba00f104d458869b2 (patch)
treed58884df7512a7f3497f3889405702e761d073f5
parent7c29bc0923869f5d766a72363a2b536c2f17ea7b (diff)
downloadnginx-c7d870cc248c868cdd9c4c2ba00f104d458869b2.tar.gz
Changes with nginx 0.7.4 30 Jun 2008v0.7.4
*) Feature: variables support in the "access_log" directive. *) Feature: the "open_log_file_cache" directive. *) Feature: the -g switch. *) Feature: the "Expect" request header line support. *) Bugfix: large SSI inclusions might be truncated.
-rw-r--r--CHANGES24
-rw-r--r--CHANGES.ru13
-rw-r--r--src/core/nginx.c14
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_conf_file.c87
-rw-r--r--src/core/ngx_conf_file.h1
-rw-r--r--src/core/ngx_cycle.c15
-rw-r--r--src/core/ngx_cycle.h1
-rw-r--r--src/core/ngx_open_file_cache.c88
-rw-r--r--src/core/ngx_open_file_cache.h1
-rw-r--r--src/event/modules/ngx_epoll_module.c5
-rw-r--r--src/event/modules/ngx_select_module.c4
-rw-r--r--src/event/ngx_event.c67
-rw-r--r--src/http/modules/ngx_http_flv_module.c3
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c3
-rw-r--r--src/http/modules/ngx_http_index_module.c6
-rw-r--r--src/http/modules/ngx_http_log_module.c306
-rw-r--r--src/http/modules/ngx_http_proxy_module.c1
-rw-r--r--src/http/modules/ngx_http_static_module.c3
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs19
-rw-r--r--src/http/ngx_http_core_module.c51
-rw-r--r--src/http/ngx_http_postpone_filter_module.c15
-rw-r--r--src/http/ngx_http_request.c4
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/http/ngx_http_script.c3
-rw-r--r--src/mail/ngx_mail_auth_http_module.c2
27 files changed, 601 insertions, 141 deletions
diff --git a/CHANGES b/CHANGES
index d76b458b7..73e01d697 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,17 @@
+Changes with nginx 0.7.4 30 Jun 2008
+
+ *) Feature: variables support in the "access_log" directive.
+
+ *) Feature: the "open_log_file_cache" directive.
+
+ *) Feature: the -g switch.
+
+ *) Feature: the "Expect" request header line support.
+
+ *) Bugfix: large SSI inclusions might be truncated.
+
+
Changes with nginx 0.7.3 23 Jun 2008
*) Change: the "rss" extension MIME type has been changed to
@@ -912,13 +925,13 @@ Changes with nginx 0.5.13 19 Feb 2007
send timeout only.
*) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc and ppc; the bug had appeared in 0.5.8.
+ amd64, sparc, and ppc; the bug had appeared in 0.5.8.
Changes with nginx 0.5.12 12 Feb 2007
*) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc и ppc; the bug had appeared in 0.5.8.
+ amd64, sparc, and ppc; the bug had appeared in 0.5.8.
*) Bugfix: a segmentation fault might occur in worker process if the
temporarily files were used while working with FastCGI server; the
@@ -1624,7 +1637,8 @@ Changes with nginx 0.3.45 06 May 2006
*) Change: the &deg; symbol codes were changed in koi-win conversion
table.
- *) Feature: the euro и N symbols were added to koi-win conversion table.
+ *) Feature: the euro and N symbols were added to koi-win conversion
+ table.
*) Bugfix: if nginx distributed the requests among several backends and
some backend failed, then requests intended for this backend was
@@ -2231,7 +2245,7 @@ Changes with nginx 0.3.7 27 Oct 2005
*) Feature: the "access_log" supports the "buffer=" parameter.
*) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc и ppc; the bug had appeared in 0.3.2.
+ amd64, sparc, and ppc; the bug had appeared in 0.3.2.
Changes with nginx 0.3.6 24 Oct 2005
@@ -2920,7 +2934,7 @@ Changes with nginx 0.1.23 01 Mar 2005
server name of the "server_name" directive.
*) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc и ppc; the bug had appeared in 0.1.22.
+ amd64, sparc, and ppc; the bug had appeared in 0.1.22.
*) Bugfix: the ngx_http_autoindex_module now shows the information not
about the symlink, but about file or directory it points to.
diff --git a/CHANGES.ru b/CHANGES.ru
index 09de84f89..ba9cfa487 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,17 @@
+Изменения в nginx 0.7.4 30.06.2008
+
+ *) Добавление: директива access_log поддерживает переменные.
+
+ *) Добавление: директива open_log_file_cache.
+
+ *) Добавление: ключ -g.
+
+ *) Добавление: поддержка строки "Expect" в заголовке запроса.
+
+ *) Исправление: большие включения в SSI могли передавались не полностью.
+
+
Изменения в nginx 0.7.3 23.06.2008
*) Изменение: MIME-тип для расширения rss изменён на
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 450edf374..fb4ac2616 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -637,8 +637,7 @@ ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
case 'c':
if (argv[i + 1] == NULL) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "the option: \"%s\" requires file name",
- argv[i]);
+ "the option \"-c\" requires file name");
return NGX_ERROR;
}
@@ -646,6 +645,17 @@ ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
cycle->conf_file.len = ngx_strlen(cycle->conf_file.data);
break;
+ case 'g':
+ if (argv[i + 1] == NULL) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
+ "the option \"-g\" requires parameter");
+ return NGX_ERROR;
+ }
+
+ cycle->conf_param.data = (u_char *) argv[++i];
+ cycle->conf_param.len = ngx_strlen(cycle->conf_param.data);
+ break;
+
default:
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
"invalid option: \"%s\"", argv[i]);
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 0032b132e..2e31eb1eb 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.7.3"
+#define NGINX_VERSION "0.7.4"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index b32f0f03c..7da9997ca 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -58,14 +58,52 @@ static int argument_number[] = {
char *
+ngx_conf_param(ngx_conf_t *cf)
+{
+ ngx_str_t *param;
+ ngx_buf_t b;
+ ngx_conf_file_t conf_file;
+
+ param = &cf->cycle->conf_param;
+
+ if (param->len == 0) {
+ return NGX_CONF_OK;
+ }
+
+ ngx_memzero(&conf_file, sizeof(ngx_conf_file_t));
+
+ ngx_memzero(&b, sizeof(ngx_buf_t));
+
+ b.start = param->data;
+ b.pos = param->data;
+ b.last = param->data + param->len;
+ b.end = b.last;
+ b.temporary = 1;
+
+ conf_file.file.fd = NGX_INVALID_FILE;
+ conf_file.file.name.data = (u_char *) "command line";
+ conf_file.line = 1;
+
+ cf->conf_file = &conf_file;
+ cf->conf_file->buffer = &b;
+
+ return ngx_conf_parse(cf, NULL);
+}
+
+
+char *
ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
{
char *rv;
ngx_fd_t fd;
ngx_int_t rc;
ngx_buf_t *b;
- ngx_uint_t block;
ngx_conf_file_t *prev;
+ enum {
+ parse_file = 0,
+ parse_block,
+ parse_param
+ } type;
#if (NGX_SUPPRESS_WARN)
fd = NGX_INVALID_FILE;
@@ -120,10 +158,14 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
cf->conf_file->file.log = cf->log;
cf->conf_file->line = 1;
- block = 0;
+ type = parse_file;
+
+ } else if (cf->conf_file->file.fd != NGX_INVALID_FILE) {
+
+ type = parse_block;
} else {
- block = 1;
+ type = parse_param;
}
@@ -145,24 +187,38 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
}
if (rc == NGX_CONF_BLOCK_DONE) {
- if (!block) {
+
+ if (type != parse_block) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\"");
goto failed;
}
- block = 0;
+ goto done;
}
- if (rc == NGX_CONF_FILE_DONE && block) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected end of file, expecting \"}\"");
- goto failed;
- }
+ if (rc == NGX_CONF_FILE_DONE) {
+
+ if (type == parse_block) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "unexpected end of file, expecting \"}\"");
+ goto failed;
+ }
- if (rc != NGX_OK && rc != NGX_CONF_BLOCK_START) {
goto done;
}
+ if (rc == NGX_CONF_BLOCK_START) {
+
+ if (type == parse_param) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "block directives are not supported "
+ "in -g option");
+ goto failed;
+ }
+ }
+
+ /* rc == NGX_OK || rc == NGX_CONF_BLOCK_START */
+
if (cf->handler) {
/*
@@ -398,10 +454,19 @@ ngx_conf_read_token(ngx_conf_t *cf)
for ( ;; ) {
if (b->pos >= b->last) {
+
if (cf->conf_file->file.offset
>= ngx_file_size(&cf->conf_file->file.info))
{
if (cf->args->nelts > 0) {
+
+ if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "unexpected end of parameter, "
+ "expecting \";\"");
+ return NGX_ERROR;
+ }
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"unexpected end of file, "
"expecting \";\" or \"}\"");
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index c3e3e9a91..5957341ff 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -317,6 +317,7 @@ char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
#define addressof(addr) ((int) &addr)
+char *ngx_conf_param(ngx_conf_t *cf);
char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index a82e8506b..725f54b49 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -90,6 +90,16 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
old_cycle->conf_file.len + 1);
+ cycle->conf_param.len = old_cycle->conf_param.len;
+ cycle->conf_param.data = ngx_pnalloc(pool, old_cycle->conf_param.len);
+ if (cycle->conf_param.data == NULL) {
+ ngx_destroy_pool(pool);
+ return NULL;
+ }
+ ngx_memcpy(cycle->conf_param.data, old_cycle->conf_param.data,
+ old_cycle->conf_param.len);
+
+
n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10;
cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
@@ -238,6 +248,11 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
log->log_level = NGX_LOG_DEBUG_ALL;
#endif
+ if (ngx_conf_param(&conf) != NGX_CONF_OK) {
+ ngx_destroy_cycle_pools(&conf);
+ return NULL;
+ }
+
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
ngx_destroy_cycle_pools(&conf);
return NULL;
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 845ce8771..e42f46bb6 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -60,6 +60,7 @@ struct ngx_cycle_s {
ngx_cycle_t *old_cycle;
ngx_str_t conf_file;
+ ngx_str_t conf_param;
ngx_str_t root;
ngx_str_t lock_file;
ngx_str_t hostname;
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index d9ec1881b..704d0ab79 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -135,6 +135,7 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
ngx_pool_cleanup_file_t *clnf;
ngx_open_file_cache_cleanup_t *ofcln;
+ of->fd = NGX_INVALID_FILE;
of->err = 0;
if (cache == NULL) {
@@ -188,8 +189,10 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
goto add_event;
}
- if ((file->event && file->use_event)
- || (file->event == NULL && now - file->created < of->valid))
+ if (file->use_event
+ || (file->event == NULL
+ && (of->uniq == 0 || of->uniq == file->uniq)
+ && now - file->created < of->valid))
{
if (file->err == 0) {
@@ -230,6 +233,9 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
of->test_dir = 1;
}
+ of->fd = file->fd;
+ of->uniq = file->uniq;
+
rc = ngx_open_and_stat_file(name->data, of, pool->log);
if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
@@ -250,26 +256,14 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
goto add_event;
}
- if (of->uniq == file->uniq
- && of->mtime == file->mtime
- && of->size == file->size)
- {
- if (ngx_close_file(of->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- name->data);
- }
+ if (of->uniq == file->uniq) {
- of->fd = file->fd;
file->count++;
if (file->event) {
file->use_event = 1;
- goto renew;
}
- ngx_open_file_add_event(cache, file, of, pool->log);
-
goto renew;
}
@@ -344,7 +338,6 @@ create:
file->uses = 1;
file->count = 0;
- file->use_event = 0;
file->event = NULL;
add_event:
@@ -446,34 +439,38 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
ngx_fd_t fd;
ngx_file_info_t fi;
- of->fd = NGX_INVALID_FILE;
-
- if (of->test_dir) {
+ if (of->fd != NGX_INVALID_FILE) {
if (ngx_file_info(name, &fi) == -1) {
- of->err = ngx_errno;
+ goto failed;
+ }
- return NGX_ERROR;
+ if (of->uniq == ngx_file_uniq(&fi)) {
+ goto done;
}
- of->uniq = ngx_file_uniq(&fi);
- of->mtime = ngx_file_mtime(&fi);
- of->size = ngx_file_size(&fi);
- of->is_dir = ngx_is_dir(&fi);
- of->is_file = ngx_is_file(&fi);
- of->is_link = ngx_is_link(&fi);
- of->is_exec = ngx_is_exec(&fi);
+ } else if (of->test_dir) {
+
+ if (ngx_file_info(name, &fi) == -1) {
+ goto failed;
+ }
if (of->is_dir) {
- return NGX_OK;
+ goto done;
}
}
- fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+ if (!of->log) {
+ fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+
+ } else {
+ fd = ngx_open_file(name, NGX_FILE_RDWR,
+ NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND,
+ NGX_FILE_DEFAULT_ACCESS);
+ }
if (fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- return NGX_ERROR;
+ goto failed;
}
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
@@ -485,6 +482,8 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
ngx_close_file_n " \"%s\" failed", name);
}
+ of->fd = NGX_INVALID_FILE;
+
return NGX_ERROR;
}
@@ -494,10 +493,14 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
ngx_close_file_n " \"%s\" failed", name);
}
- fd = NGX_INVALID_FILE;
+ of->fd = NGX_INVALID_FILE;
+
+ } else {
+ of->fd = fd;
}
- of->fd = fd;
+done:
+
of->uniq = ngx_file_uniq(&fi);
of->mtime = ngx_file_mtime(&fi);
of->size = ngx_file_size(&fi);
@@ -507,6 +510,13 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
of->is_exec = ngx_is_exec(&fi);
return NGX_OK;
+
+failed:
+
+ of->fd = NGX_INVALID_FILE;
+ of->err = ngx_errno;
+
+ return NGX_ERROR;
}
@@ -530,6 +540,8 @@ ngx_open_file_add_event(ngx_open_file_cache_t *cache,
return;
}
+ file->use_event = 0;
+
file->event = ngx_calloc(sizeof(ngx_event_t), log);
if (file->event== NULL) {
return;
@@ -567,9 +579,10 @@ ngx_open_file_add_event(ngx_open_file_cache_t *cache,
}
/*
- * we do not file->use_event here because there may be a race
- * condition between opening file and adding event, so we rely
- * upon event notification only after first file revalidation
+ * we do not set file->use_event here because there may be a race
+ * condition: a file may be deleted between opening the file and
+ * adding event, so we rely upon event notification only after
+ * one file revalidation on next file access
*/
return;
@@ -807,6 +820,7 @@ ngx_open_file_cache_remove(ngx_event_t *ev)
/* NGX_ONESHOT_EVENT was already deleted */
file->event = NULL;
+ file->use_event = 0;
file->close = 1;
diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h
index dd294e77a..4d8393b5d 100644
--- a/src/core/ngx_open_file_cache.h
+++ b/src/core/ngx_open_file_cache.h
@@ -24,6 +24,7 @@ typedef struct {
ngx_uint_t min_uses;
unsigned test_dir:1;
+ unsigned log:1;
unsigned errors:1;
unsigned events:1;
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 432164bc4..71d847107 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -143,15 +143,12 @@ ngx_module_t ngx_epoll_module = {
static ngx_int_t
ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{
- ngx_event_conf_t *ecf;
ngx_epoll_conf_t *epcf;
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module);
if (ep == -1) {
- ep = epoll_create(ecf->connections / 2);
+ ep = epoll_create(cycle->connection_n / 2);
if (ep == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index 19215a79c..a50088ba4 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -436,10 +436,10 @@ ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
#if !(NGX_WIN32)
- if ((unsigned) ecf->connections > FD_SETSIZE) {
+ if (cycle->connection_n > FD_SETSIZE) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
"the maximum number of files "
- "supported by select() is " ngx_value(FD_SETSIZE));
+ "supported by select() is %ud", FD_SETSIZE);
return NGX_CONF_ERROR;
}
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 1ec0119cc..9379aa30c 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -596,22 +596,23 @@ ngx_event_process_init(ngx_cycle_t *cycle)
return NGX_ERROR;
}
- cycle->connection_n = ecf->connections;
-
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
continue;
}
- if (ngx_modules[m]->ctx_index == ecf->use) {
- module = ngx_modules[m]->ctx;
- if (module->actions.init(cycle, ngx_timer_resolution) == NGX_ERROR)
- {
- /* fatal */
- exit(2);
- }
- break;
+ if (ngx_modules[m]->ctx_index != ecf->use) {
+ continue;
}
+
+ module = ngx_modules[m]->ctx;
+
+ if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
+ /* fatal */
+ exit(2);
+ }
+
+ break;
}
#if !(NGX_WIN32)
@@ -661,15 +662,15 @@ ngx_event_process_init(ngx_cycle_t *cycle)
#endif
- cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections,
- cycle->log);
+ cycle->connections =
+ ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
if (cycle->connections == NULL) {
return NGX_ERROR;
}
c = cycle->connections;
- cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,
+ cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
cycle->log);
if (cycle->read_events == NULL) {
return NGX_ERROR;
@@ -685,7 +686,7 @@ ngx_event_process_init(ngx_cycle_t *cycle)
#endif
}
- cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,
+ cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
cycle->log);
if (cycle->write_events == NULL) {
return NGX_ERROR;
@@ -719,7 +720,7 @@ ngx_event_process_init(ngx_cycle_t *cycle)
} while (i);
cycle->free_connections = next;
- cycle->free_connection_n = ecf->connections;
+ cycle->free_connection_n = cycle->connection_n;
/* for each listening socket */
@@ -1137,11 +1138,10 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_uint_t rtsig;
ngx_core_conf_t *ccf;
#endif
- ngx_int_t i, connections;
+ ngx_int_t i;
ngx_module_t *module;
ngx_event_module_t *event_module;
- connections = NGX_CONF_UNSET_UINT;
module = NULL;
#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
@@ -1150,11 +1150,9 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
if (fd != -1) {
close(fd);
- connections = DEFAULT_CONNECTIONS;
module = &ngx_epoll_module;
} else if (ngx_errno != NGX_ENOSYS) {
- connections = DEFAULT_CONNECTIONS;
module = &ngx_epoll_module;
}
@@ -1163,7 +1161,6 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
#if (NGX_HAVE_RTSIG)
if (module == NULL) {
- connections = DEFAULT_CONNECTIONS;
module = &ngx_rtsig_module;
rtsig = 1;
@@ -1175,14 +1172,12 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
#if (NGX_HAVE_DEVPOLL)
- connections = DEFAULT_CONNECTIONS;
module = &ngx_devpoll_module;
#endif
#if (NGX_HAVE_KQUEUE)
- connections = DEFAULT_CONNECTIONS;
module = &ngx_kqueue_module;
#endif
@@ -1190,12 +1185,6 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
#if (NGX_HAVE_SELECT)
if (module == NULL) {
-
-#if (NGX_WIN32 || FD_SETSIZE >= DEFAULT_CONNECTIONS)
- connections = DEFAULT_CONNECTIONS;
-#else
- connections = FD_SETSIZE;
-#endif
module = &ngx_select_module;
}
@@ -1203,18 +1192,20 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
if (module == NULL) {
for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type == NGX_EVENT_MODULE) {
- event_module = ngx_modules[i]->ctx;
- if (ngx_strcmp(event_module->name->data, event_core_name.data)
- == 0)
- {
- continue;
- }
+ if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
+ continue;
+ }
+
+ event_module = ngx_modules[i]->ctx;
- module = ngx_modules[i];
- break;
+ if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
+ {
+ continue;
}
+
+ module = ngx_modules[i];
+ break;
}
}
@@ -1223,7 +1214,7 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
return NGX_CONF_ERROR;
}
- ngx_conf_init_uint_value(ecf->connections, connections);
+ ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);
cycle->connection_n = ecf->connections;
ngx_conf_init_uint_value(ecf->use, module->ctx_index);
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 0e190910c..cc2ec4da1 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -105,7 +105,8 @@ ngx_http_flv_handler(ngx_http_request_t *r)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- of.test_dir = 0;
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
of.valid = clcf->open_file_cache_valid;
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index e6d44ec7b..41ac0d3ee 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -119,7 +119,8 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- of.test_dir = 0;
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
of.valid = clcf->open_file_cache_valid;
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index bd9c18c9d..bc4cd5009 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -208,7 +208,8 @@ ngx_http_index_handler(ngx_http_request_t *r)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "open index \"%V\"", &path);
- of.test_dir = 0;
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
of.valid = clcf->open_file_cache_valid;
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
@@ -291,9 +292,10 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http index check dir: \"%V\"", &dir);
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
of.test_dir = 1;
of.valid = clcf->open_file_cache_valid;
- of.min_uses = 0;
of.errors = clcf->open_file_cache_errors;
if (ngx_open_cached_file(clcf->open_file_cache, &dir, &of, r->pool)
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 47358ed54..b2a23dd70 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -40,7 +40,14 @@ typedef struct {
typedef struct {
+ ngx_array_t *lengths;
+ ngx_array_t *values;
+} ngx_http_log_script_t;
+
+
+typedef struct {
ngx_open_file_t *file;
+ ngx_http_log_script_t *script;
time_t disk_full_time;
time_t error_log_time;
ngx_array_t *ops; /* array of ngx_http_log_op_t */
@@ -49,6 +56,11 @@ typedef struct {
typedef struct {
ngx_array_t *logs; /* array of ngx_http_log_t */
+
+ ngx_open_file_cache_t *open_file_cache;
+ time_t open_file_cache_valid;
+ ngx_uint_t open_file_cache_min_uses;
+
ngx_uint_t off; /* unsigned off:1 */
} ngx_http_log_loc_conf_t;
@@ -62,6 +74,8 @@ typedef struct {
static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
u_char *buf, size_t len);
+static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
+ ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len);
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op);
@@ -101,6 +115,8 @@ static char *ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_log_compile_format(ngx_conf_t *cf,
ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s);
+static char *ngx_http_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static ngx_int_t ngx_http_log_init(ngx_conf_t *cf);
@@ -121,6 +137,13 @@ static ngx_command_t ngx_http_log_commands[] = {
0,
NULL },
+ { ngx_string("open_log_file_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
+ ngx_http_log_open_file_cache,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
ngx_null_command
};
@@ -235,7 +258,7 @@ ngx_http_log_handler(ngx_http_request_t *r)
file = log[l].file;
- if (file->buffer) {
+ if (file && file->buffer) {
if (len > (size_t) (file->last - file->pos)) {
@@ -285,11 +308,19 @@ static void
ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
size_t len)
{
- time_t now;
- ssize_t n;
- ngx_err_t err;
+ u_char *name;
+ time_t now;
+ ssize_t n;
+ ngx_err_t err;
- n = ngx_write_fd(log->file->fd, buf, len);
+ if (log->script == NULL) {
+ name = log->file->name.data;
+ n = ngx_write_fd(log->file->fd, buf, len);
+
+ } else {
+ name = NULL;
+ n = ngx_http_log_script_write(r, log->script, &name, buf, len);
+ }
if (n == (ssize_t) len) {
return;
@@ -306,8 +337,7 @@ ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
if (now - log->error_log_time > 59) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
- ngx_write_fd_n " to \"%V\" failed",
- &log->file->name);
+ ngx_write_fd_n " to \"%s\" failed", name);
log->error_log_time = now;
}
@@ -317,14 +347,93 @@ ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
if (now - log->error_log_time > 59) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_write_fd_n " to \"%V\" was incomplete: %z of %uz",
- &log->file->name, n, len);
+ ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
+ name, n, len);
log->error_log_time = now;
}
}
+static ssize_t
+ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
+ u_char **name, u_char *buf, size_t len)
+{
+ size_t root;
+ ssize_t n;
+ ngx_str_t log, path;
+ ngx_open_file_info_t of;
+ ngx_http_log_loc_conf_t *llcf;
+ ngx_http_core_loc_conf_t *clcf;
+
+ if (r->err_status == NGX_HTTP_NOT_FOUND) {
+
+ /* test root directory existance */
+
+ if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
+ /* simulate successfull logging */
+ return len;
+ }
+
+ path.data[root] = '\0';
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
+ of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
+ of.errors = clcf->open_file_cache_errors;
+ of.events = clcf->open_file_cache_events;
+
+ if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
+ != NGX_OK
+ || !of.is_dir)
+ {
+ /* no root directory: simulate successfull logging */
+ return len;
+ }
+ }
+
+ if (ngx_http_script_run(r, &log, script->lengths->elts, 1,
+ script->values->elts)
+ == NULL)
+ {
+ /* simulate successfull logging */
+ return len;
+ }
+
+ log.data[log.len - 1] = '\0';
+ *name = log.data;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http log \"%s\"", log.data);
+
+ llcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
+
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
+ of.log = 1;
+ of.valid = llcf->open_file_cache_valid;
+ of.min_uses = llcf->open_file_cache_min_uses;
+
+ if (ngx_open_cached_file(llcf->open_file_cache, &log, &of, r->pool)
+ != NGX_OK)
+ {
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", log.data);
+ return -1;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http log #%d", of.fd);
+
+ n = ngx_write_fd(of.fd, buf, len);
+
+ return n;
+}
+
+
static u_char *
ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)
@@ -620,6 +729,8 @@ ngx_http_log_create_loc_conf(ngx_conf_t *cf)
return NGX_CONF_ERROR;
}
+ conf->open_file_cache = NGX_CONF_UNSET_PTR;
+
return conf;
}
@@ -634,6 +745,17 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_log_fmt_t *fmt;
ngx_http_log_main_conf_t *lmcf;
+ if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
+
+ conf->open_file_cache = prev->open_file_cache;
+ conf->open_file_cache_valid = prev->open_file_cache_valid;
+ conf->open_file_cache_min_uses = prev->open_file_cache_min_uses;
+
+ if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
+ conf->open_file_cache = NULL;
+ }
+ }
+
if (conf->logs || conf->off) {
return NGX_CONF_OK;
}
@@ -678,12 +800,13 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_log_loc_conf_t *llcf = conf;
- ssize_t buf;
- ngx_uint_t i;
- ngx_str_t *value, name;
- ngx_http_log_t *log;
- ngx_http_log_fmt_t *fmt;
- ngx_http_log_main_conf_t *lmcf;
+ ssize_t buf;
+ ngx_uint_t i, n;
+ ngx_str_t *value, name;
+ ngx_http_log_t *log;
+ ngx_http_log_fmt_t *fmt;
+ ngx_http_log_main_conf_t *lmcf;
+ ngx_http_script_compile_t sc;
value = cf->args->elts;
@@ -706,13 +829,40 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- log->file = ngx_conf_open_file(cf->cycle, &value[1]);
- if (log->file == NULL) {
- return NGX_CONF_ERROR;
- }
+ ngx_memzero(log, sizeof(ngx_http_log_t));
- log->disk_full_time = 0;
- log->error_log_time = 0;
+ n = ngx_http_script_variables_count(&value[1]);
+
+ if (n == 0) {
+ log->file = ngx_conf_open_file(cf->cycle, &value[1]);
+ if (log->file == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ } else {
+ if (ngx_conf_full_name(cf->cycle, &value[1], 0) == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ log->script = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_script_t));
+ if (log->script == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ sc.cf = cf;
+ sc.source = &value[1];
+ sc.lengths = &log->script->lengths;
+ sc.values = &log->script->values;
+ sc.variables = n;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
if (cf->args->nelts >= 3) {
name = value[2];
@@ -750,6 +900,12 @@ buffer:
return NGX_CONF_ERROR;
}
+ if (log->script) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "buffered logs can not have variables in name");
+ return NGX_CONF_ERROR;
+ }
+
name.len = value[3].len - 7;
name.data = value[3].data + 7;
@@ -992,6 +1148,114 @@ invalid:
}
+static char *
+ngx_http_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_log_loc_conf_t *llcf = conf;
+
+ time_t inactive, valid;
+ ngx_str_t *value, s;
+ ngx_int_t max, min_uses;
+ ngx_uint_t i;
+
+ if (llcf->open_file_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 10;
+ valid = 60;
+ min_uses = 1;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max == NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive < 0) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "min_uses=", 9) == 0) {
+
+ min_uses = ngx_atoi(value[i].data + 9, value[i].len - 9);
+ if (min_uses == NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
+
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ valid = ngx_parse_time(&s, 1);
+ if (valid < 0) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ llcf->open_file_cache = NULL;
+
+ continue;
+ }
+
+ failed:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid \"open_log_file_cache\" parameter \"%V\"",
+ &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (llcf->open_file_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"open_log_file_cache\" must have \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ llcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
+
+ if (llcf->open_file_cache) {
+
+ llcf->open_file_cache_valid = valid;
+ llcf->open_file_cache_min_uses = min_uses;
+
+ return NGX_CONF_OK;
+ }
+
+ return NGX_CONF_ERROR;
+}
+
+
static ngx_int_t
ngx_http_log_init(ngx_conf_t *cf)
{
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 278edb69f..8a7f2ab9e 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -402,6 +402,7 @@ static ngx_keyval_t ngx_http_proxy_headers[] = {
{ ngx_string("Host"), ngx_string("$proxy_host") },
{ ngx_string("Connection"), ngx_string("close") },
{ ngx_string("Keep-Alive"), ngx_string("") },
+ { ngx_string("Expect"), ngx_string("") },
{ ngx_null_string, ngx_null_string }
};
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index fc84268dc..f5d697101 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -96,7 +96,8 @@ ngx_http_static_handler(ngx_http_request_t *r)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- of.test_dir = 0;
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
of.valid = clcf->open_file_cache_valid;
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 62084b488..c23e89d28 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.7.3';
+our $VERSION = '0.7.4';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 94d6a2fdd..f86b76f3e 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -639,23 +639,24 @@ sendfile(r, filename, offset = -1, bytes = 0)
XSRETURN_EMPTY;
}
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- of.test_dir = 0;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
path.len = ngx_strlen(filename);
- path.data = ngx_pcalloc(r->pool, path.len + 1);
+ path.data = ngx_pnalloc(r->pool, path.len + 1);
if (path.data == NULL) {
XSRETURN_EMPTY;
}
(void) ngx_cpystrn(path.data, filename, path.len + 1);
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
+ of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
+ of.errors = clcf->open_file_cache_errors;
+ of.events = clcf->open_file_cache_events;
+
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
{
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index aa557c450..f7b8b5b17 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -25,6 +25,7 @@ typedef struct {
static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
ngx_http_location_tree_node_t *node);
+static ngx_int_t ngx_http_core_send_continue(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@@ -771,7 +772,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
{
u_char *p;
size_t len;
- ngx_int_t rc;
+ ngx_int_t rc, expect;
ngx_http_core_loc_conf_t *clcf;
r->content_handler = NULL;
@@ -815,6 +816,15 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
return NGX_OK;
}
+ if (r->headers_in.expect) {
+ expect = ngx_http_core_send_continue(r);
+
+ if (expect != NGX_OK) {
+ ngx_http_finalize_request(r, expect);
+ return NGX_OK;
+ }
+ }
+
if (rc == NGX_DONE) {
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
@@ -1244,6 +1254,45 @@ ngx_http_core_find_static_location(ngx_http_request_t *r,
}
+static ngx_int_t
+ngx_http_core_send_continue(ngx_http_request_t *r)
+{
+ ngx_int_t n;
+ ngx_str_t *expect;
+
+ if (r->expect_tested) {
+ return NGX_OK;
+ }
+
+ r->expect_tested = 1;
+
+ expect = &r->headers_in.expect->value;
+
+ if (expect->len != sizeof("100-continue") - 1
+ || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
+ sizeof("100-continue") - 1)
+ != 0)
+ {
+ return NGX_OK;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "send 100 Continue");
+
+ n = r->connection->send(r->connection,
+ (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
+ sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
+
+ if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
+ return NGX_OK;
+ }
+
+ /* we assume that such small packet should be send successfully */
+
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+}
+
+
ngx_int_t
ngx_http_set_content_type(ngx_http_request_t *r)
{
diff --git a/src/http/ngx_http_postpone_filter_module.c b/src/http/ngx_http_postpone_filter_module.c
index 32621664c..ca5cb9e63 100644
--- a/src/http/ngx_http_postpone_filter_module.c
+++ b/src/http/ngx_http_postpone_filter_module.c
@@ -168,7 +168,7 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
pr = r->postponed;
if (pr == NULL) {
- return NGX_OK;
+ break;
}
if (pr->request) {
@@ -196,7 +196,7 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
}
if (pr == NULL) {
- return NGX_OK;
+ break;
}
out = pr->out;
@@ -215,6 +215,17 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
r->postponed = r->postponed->next;
}
+
+ if (r->out) {
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http postpone filter out again \"%V?%V\"",
+ &r->uri, &r->args);
+
+ r->connection->data = r;
+ return NGX_AGAIN;
+ }
+
+ return NGX_OK;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index a42d1e23b..d707e33be 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -106,6 +106,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
offsetof(ngx_http_headers_in_t, transfer_encoding),
ngx_http_process_header_line },
+ { ngx_string("Expect"),
+ offsetof(ngx_http_headers_in_t, expect),
+ ngx_http_process_unique_header_line },
+
#if (NGX_HTTP_GZIP)
{ ngx_string("Accept-Encoding"),
offsetof(ngx_http_headers_in_t, accept_encoding),
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 2e7ff54b6..1a4eae106 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -171,6 +171,7 @@ typedef struct {
ngx_table_elt_t *if_range;
ngx_table_elt_t *transfer_encoding;
+ ngx_table_elt_t *expect;
#if (NGX_HTTP_GZIP)
ngx_table_elt_t *accept_encoding;
@@ -467,6 +468,7 @@ struct ngx_http_request_s {
unsigned request_complete:1;
unsigned request_output:1;
unsigned header_sent:1;
+ unsigned expect_tested:1;
unsigned done:1;
unsigned utf8:1;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 0bdb944a9..7a47417e4 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -994,7 +994,8 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- of.test_dir = 0;
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
of.valid = clcf->open_file_cache_valid;
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c
index 876ac404e..d92e2c303 100644
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -528,7 +528,7 @@ ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
continue;
}
- p = ngx_pcalloc(s->connection->pool, size);
+ p = ngx_pnalloc(s->connection->pool, size);
if (p == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);