summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-12-27 15:31:36 +0000
committerJonathan Kolb <jon@b0g.us>2007-12-27 15:31:36 +0000
commit37acebc32d2a50b11537edd920af3721b93a1ecc (patch)
tree5338ea420eec0818d8e123a91973ee90308693f5
parent73cd30361418f277067c128cedee4990aa72840b (diff)
downloadnginx-37acebc32d2a50b11537edd920af3721b93a1ecc.tar.gz
Changes with nginx 0.6.23 27 Dec 2007v0.6.23
*) Change: the "off" parameter in the "ssl_session_cache" directive; now this is default parameter. *) Change: the "open_file_cache_retest" directive was renamed to the "open_file_cache_valid". *) Feature: the "open_file_cache_min_uses" directive. *) Feature: the ngx_http_gzip_static_module. *) Feature: the "gzip_disable" directive. *) Feature: the "memcached_pass" directive may be used inside the "if" block. *) Bugfix: a segmentation fault occurred in worker process, if the "memcached_pass" and "if" directives were used in the same location. *) Bugfix: if a "satisfy_any on" directive was used and not all access and auth modules directives were set, then other given access and auth directives were not tested; *) Bugfix: regex parameters in a "valid_referers" directive were not inherited from previous level. *) Bugfix: a "post_action" directive did run if a request was completed with 499 status code. *) Bugfix: optimization of 16K buffer usage in a SSL connection. Thanks to Ben Maurer. *) Bugfix: the STARTTLS in SMTP mode did not work. Thanks to Oleg Motienko. *) Bugfix: in HTTPS mode requests might fail with the "bad write retry" error; bug appeared in 0.5.13.
-rw-r--r--CHANGES40
-rw-r--r--CHANGES.ru44
-rw-r--r--auto/modules6
-rw-r--r--auto/options3
-rw-r--r--auto/sources10
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_open_file_cache.c494
-rw-r--r--src/core/ngx_open_file_cache.h15
-rw-r--r--src/core/ngx_queue.h2
-rw-r--r--src/core/ngx_rbtree.c12
-rw-r--r--src/core/ngx_regex.c33
-rw-r--r--src/core/ngx_regex.h8
-rw-r--r--src/core/ngx_resolver.c27
-rw-r--r--src/core/ngx_slab.c15
-rw-r--r--src/core/ngx_string.c19
-rw-r--r--src/event/ngx_event_openssl.c191
-rw-r--r--src/event/ngx_event_openssl.h13
-rw-r--r--src/http/modules/ngx_http_access_module.c4
-rw-r--r--src/http/modules/ngx_http_auth_basic_module.c2
-rw-r--r--src/http/modules/ngx_http_dav_module.c12
-rw-r--r--src/http/modules/ngx_http_flv_module.c3
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c235
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c302
-rw-r--r--src/http/modules/ngx_http_index_module.c6
-rw-r--r--src/http/modules/ngx_http_memcached_module.c15
-rw-r--r--src/http/modules/ngx_http_proxy_module.c13
-rw-r--r--src/http/modules/ngx_http_referer_module.c72
-rw-r--r--src/http/modules/ngx_http_ssl_module.c8
-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.xs3
-rw-r--r--src/http/ngx_http_copy_filter_module.c3
-rw-r--r--src/http/ngx_http_core_module.c343
-rw-r--r--src/http/ngx_http_core_module.h29
-rw-r--r--src/http/ngx_http_header_filter_module.c6
-rw-r--r--src/http/ngx_http_request.c16
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/http/ngx_http_script.c3
-rw-r--r--src/http/ngx_http_upstream.c10
-rw-r--r--src/mail/ngx_mail_smtp_handler.c3
-rw-r--r--src/mail/ngx_mail_ssl_module.c12
-rw-r--r--src/os/unix/ngx_freebsd.h15
-rw-r--r--src/os/unix/ngx_freebsd_init.c15
43 files changed, 1397 insertions, 674 deletions
diff --git a/CHANGES b/CHANGES
index 939324e73..551173365 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,44 @@
+Changes with nginx 0.6.23 27 Dec 2007
+
+ *) Change: the "off" parameter in the "ssl_session_cache" directive;
+ now this is default parameter.
+
+ *) Change: the "open_file_cache_retest" directive was renamed to the
+ "open_file_cache_valid".
+
+ *) Feature: the "open_file_cache_min_uses" directive.
+
+ *) Feature: the ngx_http_gzip_static_module.
+
+ *) Feature: the "gzip_disable" directive.
+
+ *) Feature: the "memcached_pass" directive may be used inside the "if"
+ block.
+
+ *) Bugfix: a segmentation fault occurred in worker process, if the
+ "memcached_pass" and "if" directives were used in the same location.
+
+ *) Bugfix: if a "satisfy_any on" directive was used and not all access
+ and auth modules directives were set, then other given access and
+ auth directives were not tested;
+
+ *) Bugfix: regex parameters in a "valid_referers" directive were not
+ inherited from previous level.
+
+ *) Bugfix: a "post_action" directive did run if a request was completed
+ with 499 status code.
+
+ *) Bugfix: optimization of 16K buffer usage in a SSL connection.
+ Thanks to Ben Maurer.
+
+ *) Bugfix: the STARTTLS in SMTP mode did not work.
+ Thanks to Oleg Motienko.
+
+ *) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
+ error; bug appeared in 0.5.13.
+
+
Changes with nginx 0.6.22 19 Dec 2007
*) Change: now all ngx_http_perl_module methods return values copied to
diff --git a/CHANGES.ru b/CHANGES.ru
index 490f1cadc..275133a6e 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,46 @@
+Изменения в nginx 0.6.23 27.12.2007
+
+ *) Изменение: параметр "off" в директиве ssl_session_cache; теперь этот
+ параметр используется по умолчанию.
+
+ *) Изменение: директива open_file_cache_retest переименована в
+ open_file_cache_valid.
+
+ *) Добавление: директива open_file_cache_min_uses.
+
+ *) Добавление: модуль ngx_http_gzip_static_module.
+
+ *) Добавление: директива gzip_disable.
+
+ *) Добавление: директиву memcached_pass можно использовать внутри блока
+ if.
+
+ *) Исправление: если внутри одного location'а использовались директивы
+ "memcached_pass" и "if", то в рабочем процессе происходил
+ segmentation fault.
+
+ *) Исправление: если при использовании директивы satisfy_any on" были
+ заданы директивы не всех модулей доступа, то заданные директивы не
+ проверялись.
+
+ *) Исправление: параметры, заданные регулярным выражением в директиве
+ valid_referers, не наследовалась с предыдущего уровня.
+
+ *) Исправление: директива post_action не работала, если запрос
+ завершался с кодом 499.
+
+ *) Исправление: оптимизация использования 16K буфера для
+ SSL-соединения.
+ Спасибо Ben Maurer.
+
+ *) Исправление: STARTTLS в режиме SMTP не работал.
+ Спасибо Олегу Мотиенко.
+
+ *) Исправление: при использовании HTTPS запросы могли завершаться с
+ ошибкой "bad write retry"; ошибка появилась в 0.5.13.
+
+
Изменения в nginx 0.6.22 19.12.2007
*) Изменение: теперь все методы модуля ngx_http_perl_module возвращают
@@ -79,7 +121,7 @@
*) Добавление: директива proxy_pass поддерживает переменные.
- *) Добавление: директива resolver и resolver_timeout.
+ *) Добавление: директивы resolver и resolver_timeout.
*) Добавление: теперь директива "add_header last-modified ''" удаляет в
заголовке ответа строку "Last-Modified".
diff --git a/auto/modules b/auto/modules
index f479ea9df..d81eebafd 100644
--- a/auto/modules
+++ b/auto/modules
@@ -265,6 +265,12 @@ if [ $HTTP_FLV = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
fi
+if [ $HTTP_GZIP_STATIC = YES ]; then
+ have=NGX_HTTP_GZIP . auto/have
+ HTTP_MODULES="$HTTP_MODULES $HTTP_GZIP_STATIC_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_STATIC_SRCS"
+fi
+
if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS"
diff --git a/auto/options b/auto/options
index 25eb6fb5b..ac475c9a6 100644
--- a/auto/options
+++ b/auto/options
@@ -76,6 +76,7 @@ HTTP_LIMIT_ZONE=YES
HTTP_EMPTY_GIF=YES
HTTP_BROWSER=YES
HTTP_FLV=NO
+HTTP_GZIP_STATIC=NO
HTTP_UPSTREAM_IP_HASH=YES
# STUB
@@ -162,6 +163,7 @@ do
--with-http_sub_module) HTTP_SUB=YES ;;
--with-http_dav_module) HTTP_DAV=YES ;;
--with-http_flv_module) HTTP_FLV=YES ;;
+ --with-http_gzip_static_module) HTTP_GZIP_STATIC=YES ;;
--without-http_charset_module) HTTP_CHARSET=NO ;;
--without-http_gzip_module) HTTP_GZIP=NO ;;
@@ -273,6 +275,7 @@ cat << END
--with-http_sub_module enable ngx_http_sub_module
--with-http_dav_module enable ngx_http_dav_module
--with-http_flv_module enable ngx_http_flv_module
+ --with-http_gzip_static_module enable ngx_http_gzip_static_module
--with-http_stub_status_module enable ngx_http_stub_status_module
--without-http_charset_module disable ngx_http_charset_module
diff --git a/auto/sources b/auto/sources
index 788d394a2..fd0cfd2fa 100644
--- a/auto/sources
+++ b/auto/sources
@@ -178,7 +178,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
POSIX_DEPS=src/os/unix/ngx_posix_config.h
-FREEBSD_DEPS=src/os/unix/ngx_freebsd_config.h
+FREEBSD_DEPS="src/os/unix/ngx_freebsd_config.h src/os/unix/ngx_freebsd.h"
FREEBSD_SRCS=src/os/unix/ngx_freebsd_init.c
FREEBSD_SENDFILE_SRCS=src/os/unix/ngx_freebsd_sendfile_chain.c
FREEBSD_RFORK_DEPS="src/os/unix/ngx_freebsd_rfork_thread.h"
@@ -187,12 +187,12 @@ FREEBSD_RFORK_THREAD_SRCS="src/os/unix/rfork_thread.S"
PTHREAD_SRCS="src/os/unix/ngx_pthread_thread.c"
-LINUX_DEPS=src/os/unix/ngx_linux_config.h
+LINUX_DEPS="src/os/unix/ngx_linux_config.h src/os/unix/ngx_linux.h"
LINUX_SRCS=src/os/unix/ngx_linux_init.c
LINUX_SENDFILE_SRCS=src/os/unix/ngx_linux_sendfile_chain.c
-SOLARIS_DEPS=src/os/unix/ngx_solaris_config.h
+SOLARIS_DEPS="src/os/unix/ngx_solaris_config.h src/os/unix/ngx_solaris.h"
SOLARIS_SRCS=src/os/unix/ngx_solaris_init.c
SOLARIS_SENDFILEV_SRCS=src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -417,6 +417,10 @@ HTTP_FLV_MODULE=ngx_http_flv_module
HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
+HTTP_GZIP_STATIC_MODULE=ngx_http_gzip_static_module
+HTTP_GZIP_STATIC_SRCS=src/http/modules/ngx_http_gzip_static_module.c
+
+
HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module
HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c
diff --git a/src/core/nginx.h b/src/core/nginx.h
index bae7d8339..3dac5c798 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.22"
+#define NGINX_VERSION "0.6.23"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index d518f4b96..9c5cc6732 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -18,22 +18,27 @@
static void ngx_open_file_cache_cleanup(void *data);
-static void ngx_open_file_cleanup(void *data);
-static void ngx_close_cached_file(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_log_t *log);
static ngx_int_t ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of,
ngx_log_t *log);
+static void ngx_open_file_add_event(ngx_open_file_cache_t *cache,
+ ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log);
+static void ngx_open_file_cleanup(void *data);
+static void ngx_close_cached_file(ngx_open_file_cache_t *cache,
+ ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log);
+static void ngx_open_file_del_event(ngx_cached_open_file_t *file);
static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache,
ngx_uint_t n, ngx_log_t *log);
static void ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
+static ngx_cached_open_file_t *
+ ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
+ uint32_t hash);
static void ngx_open_file_cache_remove(ngx_event_t *ev);
ngx_open_file_cache_t *
ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive)
{
- ngx_rbtree_node_t *sentinel;
ngx_pool_cleanup_t *cln;
ngx_open_file_cache_t *cache;
@@ -42,20 +47,11 @@ ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive)
return NULL;
}
- cache->list_head.prev = NULL;
- cache->list_head.next = &cache->list_tail;
-
- cache->list_tail.prev = &cache->list_head;
- cache->list_tail.next = NULL;
-
- sentinel = ngx_palloc(pool, sizeof(ngx_rbtree_node_t));
- if (sentinel == NULL) {
- return NULL;
- }
-
- ngx_rbtree_init(&cache->rbtree, sentinel,
+ ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
ngx_open_file_cache_rbtree_insert_value);
+ ngx_queue_init(&cache->expire_queue);
+
cache->current = 0;
cache->max = max;
cache->inactive = inactive;
@@ -77,6 +73,7 @@ ngx_open_file_cache_cleanup(void *data)
{
ngx_open_file_cache_t *cache = data;
+ ngx_queue_t *q;
ngx_cached_open_file_t *file;
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
@@ -84,14 +81,15 @@ ngx_open_file_cache_cleanup(void *data)
for ( ;; ) {
- file = cache->list_tail.prev;
-
- if (file == &cache->list_head) {
+ if (ngx_queue_empty(&cache->expire_queue)) {
break;
}
- file->next->prev = file->prev;
- file->prev->next = file->next;
+ q = ngx_queue_last(&cache->expire_queue);
+
+ file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
+
+ ngx_queue_remove(q);
ngx_rbtree_delete(&cache->rbtree, &file->node);
@@ -103,7 +101,7 @@ ngx_open_file_cache_cleanup(void *data)
if (!file->err && !file->is_dir) {
file->close = 1;
file->count = 0;
- ngx_close_cached_file(cache, file, ngx_cycle->log);
+ ngx_close_cached_file(cache, file, 0, ngx_cycle->log);
} else {
ngx_free(file->name);
@@ -132,11 +130,9 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
time_t now;
uint32_t hash;
ngx_int_t rc;
- ngx_rbtree_node_t *node, *sentinel;
ngx_pool_cleanup_t *cln;
ngx_cached_open_file_t *file;
ngx_pool_cleanup_file_t *clnf;
- ngx_open_file_cache_event_t *fev;
ngx_open_file_cache_cleanup_t *ofcln;
of->err = 0;
@@ -167,145 +163,147 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
return NGX_ERROR;
}
+ now = ngx_time();
+
hash = ngx_crc32_long(name->data, name->len);
- node = cache->rbtree.root;
- sentinel = cache->rbtree.sentinel;
+ file = ngx_open_file_lookup(cache, name, hash);
- now = ngx_time();
+ if (file) {
- while (node != sentinel) {
+ file->uses++;
- if (hash < node->key) {
- node = node->left;
- continue;
- }
+ ngx_queue_remove(&file->queue);
- if (hash > node->key) {
- node = node->right;
- continue;
- }
+ if (file->fd == NGX_INVALID_FILE && file->err == 0 && !file->is_dir) {
- /* hash == node->key */
+ /* file was not used often enough to keep open */
- do {
- file = (ngx_cached_open_file_t *) node;
+ rc = ngx_open_and_stat_file(name->data, of, pool->log);
- rc = ngx_strcmp(name->data, file->name);
+ if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
+ goto failed;
+ }
- if (rc == 0) {
+ goto add_event;
+ }
- file->next->prev = file->prev;
- file->prev->next = file->next;
+ if ((file->event && file->use_event)
+ || (file->event == NULL && now - file->created < of->valid))
+ {
+ if (file->err == 0) {
- if (file->event || now - file->created < of->retest) {
- if (file->err == 0) {
- of->fd = file->fd;
- of->uniq = file->uniq;
- of->mtime = file->mtime;
- of->size = file->size;
+ of->fd = file->fd;
+ of->uniq = file->uniq;
+ of->mtime = file->mtime;
+ of->size = file->size;
- of->is_dir = file->is_dir;
- of->is_file = file->is_file;
- of->is_link = file->is_link;
- of->is_exec = file->is_exec;
+ of->is_dir = file->is_dir;
+ of->is_file = file->is_file;
+ of->is_link = file->is_link;
+ of->is_exec = file->is_exec;
- if (!file->is_dir) {
- file->count++;
- }
+ if (!file->is_dir) {
+ file->count++;
+ ngx_open_file_add_event(cache, file, of, pool->log);
+ }
- } else {
- of->err = file->err;
- }
+ } else {
+ of->err = file->err;
+ }
- goto found;
- }
+ goto found;
+ }
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0,
- "retest open file: %s, fd:%d, c:%d, e:%d",
- file->name, file->fd, file->count, file->err);
+ ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0,
+ "retest open file: %s, fd:%d, c:%d, e:%d",
+ file->name, file->fd, file->count, file->err);
- if (file->is_dir) {
+ if (file->is_dir) {
- /*
- * chances that directory became file are very small
- * so test_dir flag allows to use a single ngx_file_info()
- * syscall instead of three syscalls
- */
+ /*
+ * chances that directory became file are very small
+ * so test_dir flag allows to use a single syscall
+ * in ngx_file_info() instead of three syscalls
+ */
- of->test_dir = 1;
- }
+ of->test_dir = 1;
+ }
- rc = ngx_open_and_stat_file(name->data, of, pool->log);
+ rc = ngx_open_and_stat_file(name->data, of, pool->log);
- if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
- goto failed;
- }
+ if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
+ goto failed;
+ }
- if (of->is_dir) {
- if (file->is_dir || file->err) {
- goto update;
- }
+ if (of->is_dir) {
- /* file became directory */
+ if (file->is_dir || file->err) {
+ goto update;
+ }
- } else if (of->err == 0) { /* file */
+ /* file became directory */
- if (file->is_dir || file->err) {
- goto update;
- }
+ } else if (of->err == 0) { /* file */
- 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 (file->is_dir || file->err) {
+ goto add_event;
+ }
- of->fd = file->fd;
- file->count++;
+ 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);
+ }
- goto renew;
- }
+ of->fd = file->fd;
+ file->count++;
- /* file was changed */
+ if (file->event) {
+ file->use_event = 1;
+ goto renew;
+ }
- } else { /* error to cache */
+ ngx_open_file_add_event(cache, file, of, pool->log);
- if (file->err || file->is_dir) {
- goto update;
- }
+ goto renew;
+ }
- /* file was removed, etc. */
- }
+ /* file was changed */
- if (file->count == 0) {
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- name->data);
- }
+ } else { /* error to cache */
- goto update;
- }
+ if (file->err || file->is_dir) {
+ goto update;
+ }
- ngx_rbtree_delete(&cache->rbtree, &file->node);
+ /* file was removed, etc. */
+ }
- cache->current--;
+ if (file->count == 0) {
- file->close = 1;
+ ngx_open_file_del_event(file);
- goto create;
+ if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed",
+ name->data);
}
- node = (rc < 0) ? node->left : node->right;
+ goto add_event;
+ }
- } while (node != sentinel && hash == node->key);
+ ngx_rbtree_delete(&cache->rbtree, &file->node);
- break;
+ cache->current--;
+
+ file->close = 1;
+
+ goto create;
}
/* not found */
@@ -346,50 +344,16 @@ create:
cache->current++;
+ file->uses = 1;
file->count = 0;
+ file->use_event = 0;
+ file->event = NULL;
-update:
-
- if (of->events
- && (ngx_event_flags & NGX_USE_VNODE_EVENT)
- && of->fd != NGX_INVALID_FILE)
- {
- file->event = ngx_calloc(sizeof(ngx_event_t), pool->log);
- if (file->event== NULL) {
- goto failed;
- }
-
- fev = ngx_alloc(sizeof(ngx_open_file_cache_event_t), pool->log);
- if (fev == NULL) {
- goto failed;
- }
-
- fev->fd = of->fd;
- fev->file = file;
- fev->cache = cache;
-
- file->event->handler = ngx_open_file_cache_remove;
- file->event->data = fev;
-
- /*
- * although vnode event may be called while ngx_cycle->poll
- * destruction; however, cleanup procedures are run before any
- * memory freeing and events will be canceled.
- */
-
- file->event->log = ngx_cycle->log;
+add_event:
- if (ngx_add_event(file->event, NGX_VNODE_EVENT, NGX_ONESHOT_EVENT)
- != NGX_OK)
- {
- ngx_free(file->event->data);
- ngx_free(file->event);
- goto failed;
- }
+ ngx_open_file_add_event(cache, file, of, pool->log);
- } else {
- file->event = NULL;
- }
+update:
file->fd = of->fd;
file->err = of->err;
@@ -419,16 +383,11 @@ found:
file->accessed = now;
- /* add to the inactive list head */
-
- file->next = cache->list_head.next;
- file->next->prev = file;
- file->prev = &cache->list_head;
- cache->list_head.next = file;
+ ngx_queue_insert_head(&cache->expire_queue, &file->queue);
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0,
- "cached open file: %s, fd:%d, c:%d, e:%d",
- file->name, file->fd, file->count, file->err);
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, pool->log, 0,
+ "cached open file: %s, fd:%d, c:%d, e:%d, u:%d",
+ file->name, file->fd, file->count, file->err, file->uses);
if (of->err == 0) {
@@ -438,6 +397,7 @@ found:
ofcln->cache = cache;
ofcln->file = file;
+ ofcln->min_uses = of->min_uses;
ofcln->log = pool->log;
}
@@ -543,6 +503,72 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
}
+/*
+ * we ignore any possible event setting error and
+ * fallback to usual periodic file retests
+ */
+
+static void
+ngx_open_file_add_event(ngx_open_file_cache_t *cache,
+ ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log)
+{
+ ngx_open_file_cache_event_t *fev;
+
+ if (!(ngx_event_flags & NGX_USE_VNODE_EVENT)
+ || !of->events
+ || file->event
+ || of->fd == NGX_INVALID_FILE
+ || file->uses < of->min_uses)
+ {
+ return;
+ }
+
+ file->event = ngx_calloc(sizeof(ngx_event_t), log);
+ if (file->event== NULL) {
+ return;
+ }
+
+ fev = ngx_alloc(sizeof(ngx_open_file_cache_event_t), log);
+ if (fev == NULL) {
+ ngx_free(file->event);
+ file->event = NULL;
+ return;
+ }
+
+ fev->fd = of->fd;
+ fev->file = file;
+ fev->cache = cache;
+
+ file->event->handler = ngx_open_file_cache_remove;
+ file->event->data = fev;
+
+ /*
+ * although vnode event may be called while ngx_cycle->poll
+ * destruction, however, cleanup procedures are run before any
+ * memory freeing and events will be canceled.
+ */
+
+ file->event->log = ngx_cycle->log;
+
+ if (ngx_add_event(file->event, NGX_VNODE_EVENT, NGX_ONESHOT_EVENT)
+ != NGX_OK)
+ {
+ ngx_free(file->event->data);
+ ngx_free(file->event);
+ file->event = NULL;
+ return;
+ }
+
+ /*
+ * 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
+ */
+
+ return;
+}
+
+
static void
ngx_open_file_cleanup(void *data)
{
@@ -550,7 +576,7 @@ ngx_open_file_cleanup(void *data)
c->file->count--;
- ngx_close_cached_file(c->cache, c->file, c->log);
+ ngx_close_cached_file(c->cache, c->file, c->min_uses, c->log);
/* drop one or two expired open files */
ngx_expire_old_cached_files(c->cache, 1, c->log);
@@ -559,50 +585,43 @@ ngx_open_file_cleanup(void *data)
static void
ngx_close_cached_file(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_log_t *log)
+ ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log)
{
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0,
- "close cached open file: %s, fd:%d, c:%d, %d",
- file->name, file->fd, file->count, file->close);
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, log, 0,
+ "close cached open file: %s, fd:%d, c:%d, u:%d, %d",
+ file->name, file->fd, file->count, file->uses, file->close);
if (!file->close) {
file->accessed = ngx_time();
- if (cache->list_head.next != file) {
-
- /* delete from inactive list */
+ ngx_queue_remove(&file->queue);
- file->next->prev = file->prev;
- file->prev->next = file->next;
+ ngx_queue_insert_head(&cache->expire_queue, &file->queue);
- /* add to the inactive list head */
-
- file->next = cache->list_head.next;
- file->next->prev = file;
- file->prev = &cache->list_head;
- cache->list_head.next = file;
+ if (file->uses >= min_uses || file->count) {
+ return;
}
+ }
+ ngx_open_file_del_event(file);
+
+ if (file->count) {
return;
}
- if (file->event) {
- (void) ngx_del_event(file->event, NGX_VNODE_EVENT,
- file->count ? NGX_FLUSH_EVENT : NGX_CLOSE_EVENT);
+ if (file->fd != NGX_INVALID_FILE) {
- ngx_free(file->event->data);
- ngx_free(file->event);
- file->event = NULL;
- }
+ if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", file->name);
+ }
- if (file->count) {
- return;
+ file->fd = NGX_INVALID_FILE;
}
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file->name);
+ if (!file->close) {
+ return;
}
ngx_free(file->name);
@@ -611,10 +630,28 @@ ngx_close_cached_file(ngx_open_file_cache_t *cache,
static void
+ngx_open_file_del_event(ngx_cached_open_file_t *file)
+{
+ if (file->event == NULL) {
+ return;
+ }
+
+ (void) ngx_del_event(file->event, NGX_VNODE_EVENT,
+ file->count ? NGX_FLUSH_EVENT : NGX_CLOSE_EVENT);
+
+ ngx_free(file->event->data);
+ ngx_free(file->event);
+ file->event = NULL;
+ file->use_event = 0;
+}
+
+
+static void
ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n,
ngx_log_t *log)
{
time_t now;
+ ngx_queue_t *q;
ngx_cached_open_file_t *file;
now = ngx_time();
@@ -627,18 +664,19 @@ ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n,
while (n < 3) {
- file = cache->list_tail.prev;
-
- if (file == &cache->list_head) {
+ if (ngx_queue_empty(&cache->expire_queue)) {
return;
}
+ q = ngx_queue_last(&cache->expire_queue);
+
+ file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
+
if (n++ != 0 && now - file->accessed <= cache->inactive) {
return;
}
- file->next->prev = file->prev;
- file->prev->next = file->next;
+ ngx_queue_remove(q);
ngx_rbtree_delete(&cache->rbtree, &file->node);
@@ -649,7 +687,7 @@ ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n,
if (!file->err && !file->is_dir) {
file->close = 1;
- ngx_close_cached_file(cache, file, log);
+ ngx_close_cached_file(cache, file, 0, log);
} else {
ngx_free(file->name);
@@ -700,6 +738,51 @@ ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
}
+static ngx_cached_open_file_t *
+ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
+ uint32_t hash)
+{
+ ngx_int_t rc;
+ ngx_rbtree_node_t *node, *sentinel;
+ ngx_cached_open_file_t *file;
+
+ node = cache->rbtree.root;
+ sentinel = cache->rbtree.sentinel;
+
+ while (node != sentinel) {
+
+ if (hash < node->key) {
+ node = node->left;
+ continue;
+ }
+
+ if (hash > node->key) {
+ node = node->right;
+ continue;
+ }
+
+ /* hash == node->key */
+
+ do {
+ file = (ngx_cached_open_file_t *) node;
+
+ rc = ngx_strcmp(name->data, file->name);
+
+ if (rc == 0) {
+ return file;
+ }
+
+ node = (rc < 0) ? node->left : node->right;
+
+ } while (node != sentinel && hash == node->key);
+
+ break;
+ }
+
+ return NULL;
+}
+
+
static void
ngx_open_file_cache_remove(ngx_event_t *ev)
{
@@ -709,8 +792,7 @@ ngx_open_file_cache_remove(ngx_event_t *ev)
fev = ev->data;
file = fev->file;
- file->next->prev = file->prev;
- file->prev->next = file->next;
+ ngx_queue_remove(&file->queue);
ngx_rbtree_delete(&fev->cache->rbtree, &file->node);
@@ -721,7 +803,7 @@ ngx_open_file_cache_remove(ngx_event_t *ev)
file->close = 1;
- ngx_close_cached_file(fev->cache, file, ev->log);
+ ngx_close_cached_file(fev->cache, file, 0, ev->log);
/* free memory only when fev->cache and fev->file are already not needed */
diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h
index cc0d899a2..dd294e77a 100644
--- a/src/core/ngx_open_file_cache.h
+++ b/src/core/ngx_open_file_cache.h
@@ -19,7 +19,9 @@ typedef struct {
off_t size;
ngx_err_t err;
- time_t retest;
+ time_t valid;
+
+ ngx_uint_t min_uses;
unsigned test_dir:1;
unsigned errors:1;
@@ -36,8 +38,7 @@ typedef struct ngx_cached_open_file_s ngx_cached_open_file_t;
struct ngx_cached_open_file_s {
ngx_rbtree_node_t node;
- ngx_cached_open_file_t *prev;
- ngx_cached_open_file_t *next;
+ ngx_queue_t queue;
u_char *name;
time_t created;
@@ -49,8 +50,11 @@ struct ngx_cached_open_file_s {
off_t size;
ngx_err_t err;
+ uint32_t uses;
+
unsigned count:24;
unsigned close:1;
+ unsigned use_event:1;
unsigned is_dir:1;
unsigned is_file:1;
@@ -63,8 +67,8 @@ struct ngx_cached_open_file_s {
typedef struct {
ngx_rbtree_t rbtree;
- ngx_cached_open_file_t list_head;
- ngx_cached_open_file_t list_tail;
+ ngx_rbtree_node_t sentinel;
+ ngx_queue_t expire_queue;
ngx_uint_t current;
ngx_uint_t max;
@@ -75,6 +79,7 @@ typedef struct {
typedef struct {
ngx_open_file_cache_t *cache;
ngx_cached_open_file_t *file;
+ ngx_uint_t min_uses;
ngx_log_t *log;
} ngx_open_file_cache_cleanup_t;
diff --git a/src/core/ngx_queue.h b/src/core/ngx_queue.h
index 39296add4..1407d85a6 100644
--- a/src/core/ngx_queue.h
+++ b/src/core/ngx_queue.h
@@ -22,7 +22,7 @@ struct ngx_queue_s {
#define ngx_queue_init(q) \
(q)->prev = q; \
- (q)->next = q;
+ (q)->next = q
#define ngx_queue_empty(h) \
diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c
index 7d240fe81..749b601f2 100644
--- a/src/core/ngx_rbtree.c
+++ b/src/core/ngx_rbtree.c
@@ -242,14 +242,14 @@ ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
if (subst->right != sentinel) {
subst->right->parent = subst;
}
-
- /* DEBUG stuff */
- node->left = NULL;
- node->right = NULL;
- node->parent = NULL;
- node->key = 0;
}
+ /* DEBUG stuff */
+ node->left = NULL;
+ node->right = NULL;
+ node->parent = NULL;
+ node->key = 0;
+
if (red) {
return;
}
diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
index eda243bec..be2dae79b 100644
--- a/src/core/ngx_regex.c
+++ b/src/core/ngx_regex.c
@@ -114,6 +114,39 @@ ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size)
}
+ngx_int_t
+ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
+{
+ ngx_int_t n;
+ ngx_uint_t i;
+ ngx_regex_elt_t *re;
+
+ re = a->elts;
+
+ for (i = 0; i < a->nelts; i++) {
+
+ n = ngx_regex_exec(re[i].regex, s, NULL, 0);
+
+ if (n == NGX_REGEX_NO_MATCHED) {
+ continue;
+ }
+
+ if (n < 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"",
+ n, s, re[i].name);
+ return NGX_ERROR;
+ }
+
+ /* match */
+
+ return NGX_OK;
+ }
+
+ return NGX_DECLINED;
+}
+
+
static void * ngx_libc_cdecl
ngx_regex_malloc(size_t size)
{
diff --git a/src/core/ngx_regex.h b/src/core/ngx_regex.h
index 430637721..e31470f9f 100644
--- a/src/core/ngx_regex.h
+++ b/src/core/ngx_regex.h
@@ -20,12 +20,20 @@
typedef pcre ngx_regex_t;
+typedef struct {
+ ngx_regex_t *regex;
+ u_char *name;
+} ngx_regex_elt_t;
+
+
void ngx_regex_init(void);
ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
ngx_pool_t *pool, ngx_str_t *err);
ngx_int_t ngx_regex_capture_count(ngx_regex_t *re);
ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures,
ngx_int_t size);
+ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
+
#define ngx_regex_exec_n "pcre_exec()"
#define ngx_regex_capture_count_n "pcre_fullinfo()"
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index be0121e2e..ef2c92ba4 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -669,17 +669,8 @@ ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
return;
}
-#if (NGX_DEBUG)
- {
- ngx_str_t s;
-
- s.len = rn->nlen;
- s.data = rn->name;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver expire \"%V\"", &s);
- }
-#endif
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolver expire \"%*s\"", (size_t) rn->nlen, rn->name);
ngx_queue_remove(q);
@@ -783,17 +774,9 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
return rn->expire - now;
}
-#if (NGX_DEBUG)
- {
- ngx_str_t s;
-
- s.len = rn->nlen;
- s.data = rn->name;
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver resend \"%V\" %p", &s, rn->waiting);
- }
-#endif
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolver resend \"%*s\" %p",
+ (size_t) rn->nlen, rn->name, rn->waiting);
ngx_queue_remove(q);
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
index 9f63a91eb..b187026d8 100644
--- a/src/core/ngx_slab.c
+++ b/src/core/ngx_slab.c
@@ -58,9 +58,22 @@
#if (NGX_DEBUG_MALLOC)
-#define ngx_slab_junk(p, size) ngx_memset(p, 0xD0, size)
+
+#define ngx_slab_junk(p, size) ngx_memset(p, 0xD0, size)
+
+#else
+
+#if (NGX_FREEBSD)
+
+#define ngx_slab_junk(p, size) \
+ if (ngx_freebsd_debug_malloc) ngx_memset(p, 0xD0, size)
+
#else
+
#define ngx_slab_junk(p, size)
+
+#endif
+
#endif
static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool,
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index f878c559f..d9a5480da 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -63,6 +63,7 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
* %V ngx_str_t *
* %v ngx_variable_value_t *
* %s null-terminated string
+ * %*s length and string
* %Z '\0'
* %N '\n'
* %c char
@@ -112,7 +113,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
* but icc issues the warning
*/
int d;
- size_t len;
+ size_t len, slen;
uint32_t ui32;
int64_t i64;
uint64_t ui64;
@@ -146,6 +147,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
sign = 1;
hexadecimal = 0;
max_width = 0;
+ slen = 0;
p = temp + NGX_INT64_LEN;
@@ -179,6 +181,11 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
fmt++;
continue;
+ case '*':
+ slen = va_arg(args, u_int);
+ fmt++;
+ continue;
+
default:
break;
}
@@ -214,9 +221,15 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
case 's':
p = va_arg(args, u_char *);
- while (*p && buf < last) {
- *buf++ = *p++;
+ if (slen == 0) {
+ while (*p && buf < last) {
+ *buf++ = *p++;
+ }
+
+ } else {
+ buf = ngx_cpymem(buf, p, slen);
}
+
fmt++;
continue;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index bd539c9a3..d1162095c 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -22,6 +22,7 @@ static void ngx_ssl_read_handler(ngx_event_t *rev);
static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
+static void ngx_ssl_clear_error(ngx_log_t *log);
static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
void *data);
@@ -186,8 +187,6 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
}
- SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
SSL_CTX_set_read_ahead(ssl->ctx, 1);
return NGX_OK;
@@ -345,14 +344,7 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
return NGX_ERROR;
}
- if (flags & NGX_SSL_BUFFER) {
- sc->buffer = 1;
-
- sc->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE);
- if (sc->buf == NULL) {
- return NGX_ERROR;
- }
- }
+ sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
sc->connection = SSL_new(ssl->ctx);
@@ -404,6 +396,8 @@ ngx_ssl_handshake(ngx_connection_t *c)
int n, sslerr;
ngx_err_t err;
+ ngx_ssl_clear_error(c->log);
+
n = SSL_do_handshake(c->ssl->connection);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
@@ -605,6 +599,8 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
bytes = 0;
+ ngx_ssl_clear_error(c->log);
+
/*
* SSL_read() may return data in parts, so try to read
* until SSL_read() would return no data
@@ -801,8 +797,28 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
}
-
buf = c->ssl->buf;
+
+ if (buf == NULL) {
+ buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE);
+ if (buf == NULL) {
+ return NGX_CHAIN_ERROR;
+ }
+
+ c->ssl->buf = buf;
+ }
+
+ if (buf->start == NULL) {
+ buf->start = ngx_palloc(c->pool, NGX_SSL_BUFSIZE);
+ if (buf->start == NULL) {
+ return NGX_CHAIN_ERROR;
+ }
+
+ buf->pos = buf->start;
+ buf->last = buf->start;
+ buf->end = buf->start + NGX_SSL_BUFSIZE;
+ }
+
send = 0;
flush = (in == NULL) ? 1 : 0;
@@ -895,6 +911,8 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
int n, sslerr;
ngx_err_t err;
+ ngx_ssl_clear_error(c->log);
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
n = SSL_write(c->ssl->connection, data, size);
@@ -975,12 +993,20 @@ ngx_ssl_read_handler(ngx_event_t *rev)
}
+void
+ngx_ssl_free_buffer(ngx_connection_t *c)
+{
+ if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
+ c->ssl->buf->start = NULL;
+ }
+}
+
+
ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c)
{
- int n, sslerr, mode;
- ngx_err_t err;
- ngx_uint_t again;
+ int n, sslerr, mode;
+ ngx_err_t err;
if (c->timedout) {
mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
@@ -999,40 +1025,34 @@ ngx_ssl_shutdown(ngx_connection_t *c)
SSL_set_shutdown(c->ssl->connection, mode);
- again = 0;
- sslerr = 0;
-
- for ( ;; ) {
- n = SSL_shutdown(c->ssl->connection);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
+ ngx_ssl_clear_error(c->log);
- if (n == 1 || (n == 0 && c->timedout)) {
- SSL_free(c->ssl->connection);
- c->ssl = NULL;
+ n = SSL_shutdown(c->ssl->connection);
- return NGX_OK;
- }
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
- if (n == 0) {
- again = 1;
- break;
- }
+ sslerr = 0;
- break;
- }
+ /* SSL_shutdown() never return -1, on error it return 0 */
- if (!again) {
+ if (n != 1) {
sslerr = SSL_get_error(c->ssl->connection, n);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL_get_error: %d", sslerr);
}
- if (again
- || sslerr == SSL_ERROR_WANT_READ
- || sslerr == SSL_ERROR_WANT_WRITE)
+ if (n == 1
+ || sslerr == SSL_ERROR_ZERO_RETURN
+ || (sslerr == 0 && c->timedout))
{
+ SSL_free(c->ssl->connection);
+ c->ssl = NULL;
+
+ return NGX_OK;
+ }
+
+ if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
c->read->handler = ngx_ssl_shutdown_handler;
c->write->handler = ngx_ssl_shutdown_handler;
@@ -1044,7 +1064,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
return NGX_ERROR;
}
- if (again || sslerr == SSL_ERROR_WANT_READ) {
+ if (sslerr == SSL_ERROR_WANT_READ) {
ngx_add_timer(c->read, 30000);
}
@@ -1125,6 +1145,15 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
}
+static void
+ngx_ssl_clear_error(ngx_log_t *log)
+{
+ if (ERR_peek_error()) {
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
+ }
+}
+
+
void ngx_cdecl
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
{
@@ -1167,6 +1196,11 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
{
long cache_mode;
+ if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
+ SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
+ return NGX_OK;
+ }
+
cache_mode = SSL_SESS_CACHE_SERVER;
if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
@@ -1210,7 +1244,6 @@ static ngx_int_t
ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
{
ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *sentinel;
ngx_ssl_session_cache_t *cache;
if (data) {
@@ -1225,25 +1258,11 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
return NGX_ERROR;
}
- cache->session_cache_head.prev = NULL;
- cache->session_cache_head.next = &cache->session_cache_tail;
-
- cache->session_cache_tail.prev = &cache->session_cache_head;
- cache->session_cache_tail.next = NULL;
-
- cache->session_rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
- if (cache->session_rbtree == NULL) {
- return NGX_ERROR;
- }
-
- sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
- if (sentinel == NULL) {
- return NGX_ERROR;
- }
-
- ngx_rbtree_init(cache->session_rbtree, sentinel,
+ ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
ngx_ssl_session_rbtree_insert_value);
+ ngx_queue_init(&cache->expire_queue);
+
shm_zone->data = cache;
return NGX_OK;
@@ -1274,7 +1293,6 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
u_char *p, *id, *cached_sess;
uint32_t hash;
SSL_CTX *ssl_ctx;
- ngx_time_t *tp;
ngx_shm_zone_t *shm_zone;
ngx_connection_t *c;
ngx_slab_pool_t *shpool;
@@ -1350,22 +1368,17 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
"http ssl new session: %08XD:%d:%d",
hash, sess->session_id_length, len);
- tp = ngx_timeofday();
-
sess_id->node.key = hash;
sess_id->node.data = (u_char) sess->session_id_length;
sess_id->id = id;
sess_id->len = len;
sess_id->session = cached_sess;
- sess_id->expire = tp->sec + SSL_CTX_get_timeout(ssl_ctx);
+ sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx);
- sess_id->next = cache->session_cache_head.next;
- sess_id->next->prev = sess_id;
- sess_id->prev = &cache->session_cache_head;
- cache->session_cache_head.next = sess_id;
+ ngx_queue_insert_head(&cache->expire_queue, &sess_id->queue);
- ngx_rbtree_insert(cache->session_rbtree, &sess_id->node);
+ ngx_rbtree_insert(&cache->session_rbtree, &sess_id->node);
ngx_shmtx_unlock(&shpool->mutex);
@@ -1400,7 +1413,6 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
u_char *p;
uint32_t hash;
ngx_int_t rc;
- ngx_time_t *tp;
ngx_shm_zone_t *shm_zone;
ngx_slab_pool_t *shpool;
ngx_connection_t *c;
@@ -1423,18 +1435,14 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
cache = shm_zone->data;
- if (cache->session_rbtree == NULL) {
- return NULL;
- }
-
sess = NULL;
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
ngx_shmtx_lock(&shpool->mutex);
- node = cache->session_rbtree->root;
- sentinel = cache->session_rbtree->sentinel;
+ node = cache->session_rbtree.root;
+ sentinel = cache->session_rbtree.sentinel;
while (node != sentinel) {
@@ -1457,9 +1465,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
(size_t) len, (size_t) node->data);
if (rc == 0) {
- tp = ngx_timeofday();
-
- if (sess_id->expire > tp->sec) {
+ if (sess_id->expire > ngx_time()) {
ngx_memcpy(buf, sess_id->session, sess_id->len);
ngx_shmtx_unlock(&shpool->mutex);
@@ -1470,10 +1476,9 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
return sess;
}
- sess_id->next->prev = sess_id->prev;
- sess_id->prev->next = sess_id->next;
+ ngx_queue_remove(&sess_id->queue);
- ngx_rbtree_delete(cache->session_rbtree, node);
+ ngx_rbtree_delete(&cache->session_rbtree, node);
ngx_slab_free_locked(shpool, sess_id->session);
#if (NGX_PTR_SIZE == 4)
@@ -1530,8 +1535,8 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
ngx_shmtx_lock(&shpool->mutex);
- node = cache->session_rbtree->root;
- sentinel = cache->session_rbtree->sentinel;
+ node = cache->session_rbtree.root;
+ sentinel = cache->session_rbtree.sentinel;
while (node != sentinel) {
@@ -1553,10 +1558,10 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
if (rc == 0) {
- sess_id->next->prev = sess_id->prev;
- sess_id->prev->next = sess_id->next;
- ngx_rbtree_delete(cache->session_rbtree, node);
+ ngx_queue_remove(&sess_id->queue);
+
+ ngx_rbtree_delete(&cache->session_rbtree, node);
ngx_slab_free_locked(shpool, sess_id->session);
#if (NGX_PTR_SIZE == 4)
@@ -1584,31 +1589,33 @@ static void
ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
ngx_slab_pool_t *shpool, ngx_uint_t n)
{
- ngx_time_t *tp;
+ time_t now;
+ ngx_queue_t *q;
ngx_ssl_sess_id_t *sess_id;
- tp = ngx_timeofday();
+ now = ngx_time();
while (n < 3) {
- sess_id = cache->session_cache_tail.prev;
-
- if (sess_id == &cache->session_cache_head) {
+ if (ngx_queue_empty(&cache->expire_queue)) {
return;
}
- if (n++ != 0 && sess_id->expire > tp->sec) {
+ q = ngx_queue_last(&cache->expire_queue);
+
+ sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);
+
+ if (n++ != 0 && sess_id->expire > now) {
return;
}
- sess_id->next->prev = sess_id->prev;
- sess_id->prev->next = sess_id->next;
-
- ngx_rbtree_delete(cache->session_rbtree, &sess_id->node);
+ ngx_queue_remove(q);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
"expire session: %08Xi", sess_id->node.key);
+ ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);
+
ngx_slab_free_locked(shpool, sess_id->session);
#if (NGX_PTR_SIZE == 4)
ngx_slab_free_locked(shpool, sess_id->id);
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 9e8ce1733..e027dde86 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -53,9 +53,10 @@ typedef struct {
#define NGX_SSL_DFLT_BUILTIN_SCACHE -2
#define NGX_SSL_NO_BUILTIN_SCACHE -3
+#define NGX_SSL_NO_SCACHE -4
-#define NGX_SSL_MAX_SESSION_SIZE (4096)
+#define NGX_SSL_MAX_SESSION_SIZE 4096
typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;
@@ -64,8 +65,7 @@ struct ngx_ssl_sess_id_s {
u_char *id;
size_t len;
u_char *session;
- ngx_ssl_sess_id_t *prev;
- ngx_ssl_sess_id_t *next;
+ ngx_queue_t queue;
time_t expire;
#if (NGX_PTR_SIZE == 8)
void *stub;
@@ -75,9 +75,9 @@ struct ngx_ssl_sess_id_s {
typedef struct {
- ngx_rbtree_t *session_rbtree;
- ngx_ssl_sess_id_t session_cache_head;
- ngx_ssl_sess_id_t session_cache_tail;
+ ngx_rbtree_t session_rbtree;
+ ngx_rbtree_node_t sentinel;
+ ngx_queue_t expire_queue;
} ngx_ssl_session_cache_t;
@@ -132,6 +132,7 @@ ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
ssize_t ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl);
ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
+void ngx_ssl_free_buffer(ngx_connection_t *c);
ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c);
void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
char *fmt, ...);
diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c
index e4e87b243..44a2fbd89 100644
--- a/src/http/modules/ngx_http_access_module.c
+++ b/src/http/modules/ngx_http_access_module.c
@@ -98,7 +98,7 @@ ngx_http_access_handler(ngx_http_request_t *r)
alcf = ngx_http_get_module_loc_conf(r, ngx_http_access_module);
if (alcf->rules == NULL) {
- return NGX_OK;
+ return NGX_DECLINED;
}
/* AF_INET only */
@@ -128,7 +128,7 @@ ngx_http_access_handler(ngx_http_request_t *r)
}
}
- return NGX_OK;
+ return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index 72b4bbdcb..41e53cd94 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -113,7 +113,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module);
if (alcf->realm.len == 0 || alcf->user_file.len == 0) {
- return NGX_OK;
+ return NGX_DECLINED;
}
ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module);
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index e1533e867..2d555c556 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -37,7 +37,6 @@ static ngx_int_t ngx_http_dav_handler(ngx_http_request_t *r);
static void ngx_http_dav_put_handler(ngx_http_request_t *r);
static ngx_int_t ngx_http_dav_delete_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_dav_no_init(void *ctx, void *prev);
static ngx_int_t ngx_http_dav_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path);
static ngx_int_t ngx_http_dav_delete_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path);
static ngx_int_t ngx_http_dav_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path);
@@ -409,13 +408,6 @@ ngx_http_dav_delete_handler(ngx_http_request_t *r)
static ngx_int_t
-ngx_http_dav_no_init(void *ctx, void *prev)
-{
- return NGX_OK;
-}
-
-
-static ngx_int_t
ngx_http_dav_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path)
{
return NGX_OK;
@@ -710,7 +702,7 @@ overwrite_done:
copy.len = path.len;
- tree.init_handler = ngx_http_dav_no_init;
+ tree.init_handler = NULL;
tree.file_handler = ngx_http_dav_copy_file;
tree.pre_tree_handler = ngx_http_dav_copy_dir;
tree.post_tree_handler = ngx_http_dav_copy_dir_time;
@@ -960,7 +952,7 @@ ngx_http_dav_delete_path(ngx_http_request_t *r, ngx_str_t *path, ngx_uint_t dir)
if (dir) {
- tree.init_handler = ngx_http_dav_no_init;
+ tree.init_handler = NULL;
tree.file_handler = ngx_http_dav_delete_file;
tree.pre_tree_handler = ngx_http_dav_noop;
tree.post_tree_handler = ngx_http_dav_delete_dir;
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index a1519394a..1e8f96faf 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -106,7 +106,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;
- of.retest = clcf->open_file_cache_retest;
+ 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;
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 42dfa5021..1587c009d 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -14,15 +14,11 @@
typedef struct {
ngx_flag_t enable;
ngx_flag_t no_buffer;
- ngx_flag_t vary;
ngx_array_t *types; /* array of ngx_str_t */
ngx_bufs_t bufs;
- ngx_uint_t http_version;
- ngx_uint_t proxied;
-
ngx_int_t level;
size_t wbits;
size_t memlevel;
@@ -30,17 +26,6 @@ typedef struct {
} ngx_http_gzip_conf_t;
-#define NGX_HTTP_GZIP_PROXIED_OFF 0x0002
-#define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004
-#define NGX_HTTP_GZIP_PROXIED_NO_CACHE 0x0008
-#define NGX_HTTP_GZIP_PROXIED_NO_STORE 0x0010
-#define NGX_HTTP_GZIP_PROXIED_PRIVATE 0x0020
-#define NGX_HTTP_GZIP_PROXIED_NO_LM 0x0040
-#define NGX_HTTP_GZIP_PROXIED_NO_ETAG 0x0080
-#define NGX_HTTP_GZIP_PROXIED_AUTH 0x0100
-#define NGX_HTTP_GZIP_PROXIED_ANY 0x0200
-
-
typedef struct {
ngx_chain_t *in;
ngx_chain_t *free;
@@ -70,8 +55,6 @@ typedef struct {
} ngx_http_gzip_ctx_t;
-static ngx_int_t ngx_http_gzip_proxied(ngx_http_request_t *r,
- ngx_http_gzip_conf_t *conf);
static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items,
u_int size);
static void ngx_http_gzip_filter_free(void *opaque, void *address);
@@ -99,27 +82,6 @@ static ngx_conf_post_handler_pt ngx_http_gzip_window_p = ngx_http_gzip_window;
static ngx_conf_post_handler_pt ngx_http_gzip_hash_p = ngx_http_gzip_hash;
-static ngx_conf_enum_t ngx_http_gzip_http_version[] = {
- { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
- { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
- { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
- { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
- { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
- { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
- { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
- { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
- { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
- { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
- { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
- { ngx_null_string, 0 }
-};
-
-
static ngx_command_t ngx_http_gzip_filter_commands[] = {
{ ngx_string("gzip"),
@@ -172,20 +134,6 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
offsetof(ngx_http_gzip_conf_t, no_buffer),
NULL },
- { ngx_string("gzip_http_version"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, http_version),
- &ngx_http_gzip_http_version },
-
- { ngx_string("gzip_proxied"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, proxied),
- &ngx_http_gzip_proxied_mask },
-
{ ngx_string("gzip_min_length"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
@@ -193,13 +141,6 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
offsetof(ngx_http_gzip_conf_t, min_length),
NULL },
- { ngx_string("gzip_vary"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, vary),
- NULL },
-
ngx_null_command
};
@@ -255,10 +196,6 @@ struct gztrailer {
static ngx_str_t ngx_http_gzip_ratio = ngx_string("gzip_ratio");
-static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
-static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
-static ngx_str_t ngx_http_gzip_private = ngx_string("private");
-
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
@@ -267,11 +204,12 @@ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
ngx_http_gzip_header_filter(ngx_http_request_t *r)
{
- ngx_str_t *type;
- ngx_uint_t i;
- ngx_table_elt_t *header;
- ngx_http_gzip_ctx_t *ctx;
- ngx_http_gzip_conf_t *conf;
+ ngx_str_t *type;
+ ngx_uint_t i;
+ ngx_table_elt_t *h;
+ ngx_http_gzip_ctx_t *ctx;
+ ngx_http_gzip_conf_t *conf;
+ ngx_http_core_loc_conf_t *clcf;
conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
@@ -280,23 +218,16 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|| r->header_only
- || r != r->main
- || r->http_version < conf->http_version
|| r->headers_out.content_type.len == 0
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
- || r->headers_in.accept_encoding == NULL
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
- || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
- "gzip", 4 - 1)
- == NULL
- )
+ || ngx_http_gzip_ok(r) != NGX_OK)
{
return ngx_http_next_header_filter(r);
}
-
type = conf->types->elts;
for (i = 0; i < conf->types->nelts; i++) {
if (r->headers_out.content_type.len >= type[i].len
@@ -309,32 +240,8 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
return ngx_http_next_header_filter(r);
-
found:
- if (r->headers_in.via) {
- if (conf->proxied & NGX_HTTP_GZIP_PROXIED_OFF) {
- return ngx_http_next_header_filter(r);
- }
-
- if (!(conf->proxied & NGX_HTTP_GZIP_PROXIED_ANY)
- && ngx_http_gzip_proxied(r, conf) == NGX_DECLINED)
- {
- return ngx_http_next_header_filter(r);
- }
- }
-
-
- /*
- * if the URL (without the "http://" prefix) is longer than 253 bytes
- * then MSIE 4.x can not handle the compressed stream - it waits too long,
- * hangs up or crashes
- */
-
- if (r->headers_in.msie4 && r->unparsed_uri.len > 200) {
- return ngx_http_next_header_filter(r);
- }
-
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -342,33 +249,34 @@ found:
ngx_http_set_ctx(r, ctx, ngx_http_gzip_filter_module);
-
ctx->request = r;
- header = ngx_list_push(&r->headers_out.headers);
- if (header == NULL) {
+ h = ngx_list_push(&r->headers_out.headers);
+ if (h == NULL) {
return NGX_ERROR;
}
- header->hash = 1;
- header->key.len = sizeof("Content-Encoding") - 1;
- header->key.data = (u_char *) "Content-Encoding";
- header->value.len = sizeof("gzip") - 1;
- header->value.data = (u_char *) "gzip";
+ h->hash = 1;
+ h->key.len = sizeof("Content-Encoding") - 1;
+ h->key.data = (u_char *) "Content-Encoding";
+ h->value.len = sizeof("gzip") - 1;
+ h->value.data = (u_char *) "gzip";
+
+ r->headers_out.content_encoding = h;
- r->headers_out.content_encoding = header;
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- if (conf->vary) {
- header = ngx_list_push(&r->headers_out.headers);
- if (header == NULL) {
+ if (clcf->gzip_vary) {
+ h = ngx_list_push(&r->headers_out.headers);
+ if (h == NULL) {
return NGX_ERROR;
}
- header->hash = 1;
- header->key.len = sizeof("Vary") - 1;
- header->key.data = (u_char *) "Vary";
- header->value.len = sizeof("Accept-Encoding") - 1;
- header->value.data = (u_char *) "Accept-Encoding";
+ h->hash = 1;
+ h->key.len = sizeof("Vary") - 1;
+ h->key.data = (u_char *) "Vary";
+ h->value.len = sizeof("Accept-Encoding") - 1;
+ h->value.data = (u_char *) "Accept-Encoding";
}
ctx->length = r->headers_out.content_length_n;
@@ -383,89 +291,6 @@ found:
static ngx_int_t
-ngx_http_gzip_proxied(ngx_http_request_t *r, ngx_http_gzip_conf_t *conf)
-{
- time_t date, expires;
-
- if (r->headers_in.authorization
- && (conf->proxied & NGX_HTTP_GZIP_PROXIED_AUTH))
- {
- return NGX_OK;
- }
-
- if (r->headers_out.expires) {
-
- if (!(conf->proxied & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
- return NGX_DECLINED;
- }
-
- expires = ngx_http_parse_time(r->headers_out.expires->value.data,
- r->headers_out.expires->value.len);
- if (expires == NGX_ERROR) {
- return NGX_DECLINED;
- }
-
- if (r->headers_out.date) {
- date = ngx_http_parse_time(r->headers_out.date->value.data,
- r->headers_out.date->value.len);
- if (date == NGX_ERROR) {
- return NGX_DECLINED;
- }
-
- } else {
- date = ngx_time();
- }
-
- if (expires < date) {
- return NGX_OK;
- }
-
- return NGX_DECLINED;
- }
-
- if (r->headers_out.cache_control.elts) {
-
- if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
- && ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
- &ngx_http_gzip_no_cache, NULL) >= 0)
- {
- return NGX_OK;
- }
-
- if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_STORE)
- && ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
- &ngx_http_gzip_no_store, NULL) >= 0)
- {
- return NGX_OK;
- }
-
- if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_PRIVATE)
- && ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
- &ngx_http_gzip_private, NULL) >= 0)
- {
- return NGX_OK;
- }
-
- return NGX_DECLINED;
- }
-
- if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_LM)
- && r->headers_out.last_modified)
- {
- return NGX_DECLINED;
- }
-
- if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_ETAG)
- && r->headers_out.etag)
- {
- return NGX_DECLINED;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
int rc, wbits, memlevel;
@@ -1017,15 +842,11 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf)
* set by ngx_pcalloc():
*
* conf->bufs.num = 0;
- * conf->proxied = 0;
* conf->types = NULL;
*/
conf->enable = NGX_CONF_UNSET;
conf->no_buffer = NGX_CONF_UNSET;
- conf->vary = NGX_CONF_UNSET;
-
- conf->http_version = NGX_CONF_UNSET_UINT;
conf->level = NGX_CONF_UNSET;
conf->wbits = (size_t) NGX_CONF_UNSET;
@@ -1048,18 +869,12 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
- ngx_conf_merge_uint_value(conf->http_version, prev->http_version,
- NGX_HTTP_VERSION_11);
- ngx_conf_merge_bitmask_value(conf->proxied, prev->proxied,
- (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
-
ngx_conf_merge_value(conf->level, prev->level, 1);
ngx_conf_merge_size_value(conf->wbits, prev->wbits, MAX_WBITS);
ngx_conf_merge_size_value(conf->memlevel, prev->memlevel,
MAX_MEM_LEVEL - 1);
ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
- ngx_conf_merge_value(conf->vary, prev->vary, 0);
if (conf->types == NULL) {
if (prev->types == NULL) {
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
new file mode 100644
index 000000000..e4aaeb345
--- /dev/null
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -0,0 +1,302 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+ ngx_flag_t enable;
+} ngx_http_gzip_static_conf_t;
+
+
+static ngx_int_t ngx_http_gzip_static_handler(ngx_http_request_t *r);
+static void *ngx_http_gzip_static_create_conf(ngx_conf_t *cf);
+static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+static ngx_int_t ngx_http_gzip_static_init(ngx_conf_t *cf);
+
+
+static ngx_command_t ngx_http_gzip_static_commands[] = {
+
+ { ngx_string("gzip_static"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_gzip_static_conf_t, enable),
+ NULL },
+
+ ngx_null_command
+};
+
+
+ngx_http_module_t ngx_http_gzip_static_module_ctx = {
+ NULL, /* preconfiguration */
+ ngx_http_gzip_static_init, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ ngx_http_gzip_static_create_conf, /* create location configuration */
+ ngx_http_gzip_static_merge_conf /* merge location configuration */
+};
+
+
+ngx_module_t ngx_http_gzip_static_module = {
+ NGX_MODULE_V1,
+ &ngx_http_gzip_static_module_ctx, /* module context */
+ ngx_http_gzip_static_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_gzip_static_handler(ngx_http_request_t *r)
+{
+ u_char *p;
+ size_t root;
+ ngx_str_t path;
+ ngx_int_t rc;
+ ngx_uint_t level;
+ ngx_log_t *log;
+ ngx_buf_t *b;
+ ngx_chain_t out;
+ ngx_table_elt_t *h;
+ ngx_open_file_info_t of;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_gzip_static_conf_t *gzcf;
+
+ 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;
+ }
+
+ gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
+
+ if (!gzcf->enable || ngx_http_gzip_ok(r) != NGX_OK) {
+ return NGX_DECLINED;
+ }
+
+ log = r->connection->log;
+
+ p = ngx_http_map_uri_to_path(r, &path, &root, sizeof(".gz") - 1);
+ if (p == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ *p++ = '.';
+ *p++ = 'g';
+ *p++ = 'z';
+ *p = '\0';
+
+ path.len = p - path.data;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
+ "http filename: \"%s\"", path.data);
+
+ 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;
+
+ rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
+
+ if (rc == NGX_ERROR) {
+
+ switch (of.err) {
+
+ case 0:
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+
+ case NGX_ENOENT:
+ case NGX_ENOTDIR:
+ case NGX_ENAMETOOLONG:
+
+ return NGX_DECLINED;
+
+ case NGX_EACCES:
+
+ level = NGX_LOG_ERR;
+ rc = NGX_DECLINED;
+ break;
+
+ default:
+
+ level = NGX_LOG_CRIT;
+ rc = NGX_DECLINED;
+ break;
+ }
+
+ ngx_log_error(level, log, of.err,
+ ngx_open_file_n " \"%s\" failed", path.data);
+
+ return rc;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
+
+ if (of.is_dir) {
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
+ return NGX_DECLINED;
+ }
+
+#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
+
+ if (!of.is_file) {
+ ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
+ "\"%s\" is not a regular file", path.data);
+
+ return NGX_HTTP_NOT_FOUND;
+ }
+
+#endif
+
+ rc = ngx_http_discard_request_body(r);
+
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ log->action = "sending response to client";
+
+ r->headers_out.status = NGX_HTTP_OK;
+ r->headers_out.content_length_n = of.size;
+ r->headers_out.last_modified_time = of.mtime;
+
+ if (ngx_http_set_content_type(r) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ h = ngx_list_push(&r->headers_out.headers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ h->hash = 1;
+ h->key.len = sizeof("Content-Encoding") - 1;
+ h->key.data = (u_char *) "Content-Encoding";
+ h->value.len = sizeof("gzip") - 1;
+ h->value.data = (u_char *) "gzip";
+
+ r->headers_out.content_encoding = h;
+
+ if (clcf->gzip_vary) {
+ h = ngx_list_push(&r->headers_out.headers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ h->hash = 1;
+ h->key.len = sizeof("Vary") - 1;
+ h->key.data = (u_char *) "Vary";
+ h->value.len = sizeof("Accept-Encoding") - 1;
+ h->value.data = (u_char *) "Accept-Encoding";
+ }
+
+ /* we need to allocate all before the header would be sent */
+
+ 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 = 0;
+ b->file_last = of.size;
+
+ b->in_file = b->file_last ? 1 : 0;
+ b->last_buf = 1;
+ b->last_in_chain = 1;
+
+ b->file->fd = of.fd;
+ b->file->name = path;
+ b->file->log = log;
+
+ out.buf = b;
+ out.next = NULL;
+
+ return ngx_http_output_filter(r, &out);
+}
+
+
+static void *
+ngx_http_gzip_static_create_conf(ngx_conf_t *cf)
+{
+ ngx_http_gzip_static_conf_t *conf;
+
+ conf = ngx_palloc(cf->pool, sizeof(ngx_http_gzip_static_conf_t));
+ if (conf == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->enable = NGX_CONF_UNSET;
+
+ return conf;
+}
+
+
+static char *
+ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_http_gzip_static_conf_t *prev = parent;
+ ngx_http_gzip_static_conf_t *conf = child;
+
+ ngx_conf_merge_value(conf->enable, prev->enable, 0);
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_gzip_static_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_CONTENT_PHASE].handlers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ *h = ngx_http_gzip_static_handler;
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 7eeaf0a90..c9622835d 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -209,7 +209,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;
- of.retest = clcf->open_file_cache_retest;
+ 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;
@@ -292,7 +293,8 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
"http index check dir: \"%V\"", &dir);
of.test_dir = 1;
- of.retest = clcf->open_file_cache_retest;
+ 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_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index dbca81a7d..1f156cd42 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -58,7 +58,7 @@ static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = {
static ngx_command_t ngx_http_memcached_commands[] = {
{ ngx_string("memcached_pass"),
- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_http_memcached_pass,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -524,8 +524,6 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
- *
- * conf->index = 0;
*/
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
@@ -548,6 +546,8 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
conf->upstream.pass_request_headers = 0;
conf->upstream.pass_request_body = 0;
+ conf->index = NGX_CONF_UNSET;
+
return conf;
}
@@ -582,6 +582,15 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|NGX_HTTP_UPSTREAM_FT_OFF;
}
+ if (conf->upstream.upstream == NULL) {
+ conf->upstream.upstream = prev->upstream.upstream;
+ conf->upstream.schema = prev->upstream.schema;
+ }
+
+ if (conf->index == NGX_CONF_UNSET) {
+ conf->index = prev->index;
+ }
+
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 ec31673ad..0849668ee 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -880,16 +880,9 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
b->last = e.pos;
}
-#if (NGX_DEBUG)
- {
- ngx_str_t s;
-
- s.len = b->last - b->pos;
- s.data = b->pos;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy header:\n\"%V\"", &s);
- }
-#endif
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http proxy header:\n\"%*s\"",
+ (size_t) (b->last - b->pos), b->pos);
if (plcf->body_set == NULL && plcf->upstream.pass_request_body) {
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 0076e9472..15c935194 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -11,14 +11,7 @@
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
-#if (NGX_PCRE)
-
-typedef struct {
- ngx_regex_t *regex;
- ngx_str_t name;
-} ngx_http_referer_regex_t;
-
-#else
+#if !(NGX_PCRE)
#define ngx_regex_t void
@@ -168,34 +161,23 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
#if (NGX_PCRE)
if (rlcf->regex) {
- ngx_int_t n;
- ngx_str_t referer;
- ngx_http_referer_regex_t *regex;
+ ngx_int_t rc;
+ ngx_str_t referer;
referer.len = len - 7;
referer.data = ref;
- regex = rlcf->regex->elts;
-
- for (i = 0; i < rlcf->regex->nelts; i++) {
- n = ngx_regex_exec(regex[i].regex, &referer, NULL, 0);
-
- if (n == NGX_REGEX_NO_MATCHED) {
- continue;
- }
-
- if (n < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n
- " failed: %d on \"%V\" using \"%V\"",
- n, &referer, &regex[i].name);
- return NGX_ERROR;
- }
-
- /* match */
+ rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log);
+ if (rc == NGX_OK) {
goto valid;
}
+
+ if (rc == NGX_ERROR) {
+ return rc;
+ }
+
+ /* NGX_DECLINED */
}
#endif
@@ -242,6 +224,10 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
return NGX_CONF_ERROR;
}
+#if (NGX_PCRE)
+ conf->regex = NGX_CONF_UNSET_PTR;
+#endif
+
conf->no_referer = NGX_CONF_UNSET;
conf->blocked_referer = NGX_CONF_UNSET;
@@ -260,6 +246,7 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->keys == NULL) {
conf->hash = prev->hash;
+ ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
@@ -335,6 +322,8 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
}
+ ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
+
if (conf->no_referer == NGX_CONF_UNSET) {
conf->no_referer = 0;
}
@@ -509,26 +498,25 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
ngx_str_t *name, ngx_regex_t *regex)
{
#if (NGX_PCRE)
- ngx_str_t err;
- ngx_http_referer_regex_t *rr;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_str_t err;
+ ngx_regex_elt_t *re;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
- if (rlcf->regex == NULL) {
- rlcf->regex = ngx_array_create(cf->pool, 2,
- sizeof(ngx_http_referer_regex_t));
+ if (rlcf->regex == NGX_CONF_UNSET_PTR) {
+ rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t));
if (rlcf->regex == NULL) {
return NGX_CONF_ERROR;
}
}
- rr = ngx_array_push(rlcf->regex);
- if (rr == NULL) {
+ re = ngx_array_push(rlcf->regex);
+ if (re == NULL) {
return NGX_CONF_ERROR;
}
if (regex) {
- rr->regex = regex;
- rr->name = *name;
+ re->regex = regex;
+ re->name = name->data;
return NGX_CONF_OK;
}
@@ -539,14 +527,14 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
name->len--;
name->data++;
- rr->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
+ re->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
- if (rr->regex == NULL) {
+ if (re->regex == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
- rr->name = *name;
+ re->name = name->data;
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index c096441d0..3359900fd 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -415,8 +415,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
ngx_conf_merge_value(conf->builtin_session_cache,
- prev->builtin_session_cache,
- NGX_SSL_DFLT_BUILTIN_SCACHE);
+ prev->builtin_session_cache, NGX_SSL_NO_SCACHE);
if (conf->shm_zone == NULL) {
conf->shm_zone = prev->shm_zone;
@@ -448,6 +447,11 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (i = 1; i < cf->args->nelts; i++) {
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+ sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
+ continue;
+ }
+
if (ngx_strcmp(value[i].data, "builtin") == 0) {
sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
continue;
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index 3da2f7ae5..cfc708916 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -97,7 +97,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;
- of.retest = clcf->open_file_cache_retest;
+ 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;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index a90f18eb4..40711ff7a 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.6.22';
+our $VERSION = '0.6.23';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 1182d8527..78455b951 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -643,7 +643,8 @@ sendfile(r, filename, offset = -1, bytes = 0)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
of.test_dir = 0;
- of.retest = clcf->open_file_cache_retest;
+ 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;
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index 3069779c2..3b1a3a730 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -121,11 +121,8 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
r->out = ctx->in;
}
-#if (NGX_DEBUG)
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
-#endif
-
}
return rc;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index dbfa91ac6..edfc3bb81 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -71,6 +71,10 @@ static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+#if (NGX_HTTP_GZIP)
+static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+#endif
static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
@@ -85,6 +89,10 @@ static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = {
ngx_conf_deprecated, "optimize_host_names", "optimize_server_names"
};
+static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = {
+ ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
+};
+
static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
{ ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
@@ -94,6 +102,36 @@ static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
};
+#if (NGX_HTTP_GZIP)
+
+static ngx_conf_enum_t ngx_http_gzip_http_version[] = {
+ { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
+ { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
+ { ngx_null_string, 0 }
+};
+
+
+static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
+ { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
+ { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
+ { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
+ { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
+ { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
+ { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
+ { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
+ { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
+ { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
+ { ngx_null_string, 0 }
+};
+
+
+static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
+static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
+static ngx_str_t ngx_http_gzip_private = ngx_string("private");
+
+#endif
+
+
static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("variables_hash_max_size"),
@@ -473,11 +511,25 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, open_file_cache),
NULL },
+ { ngx_string("open_file_cache_valid"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_sec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
+ NULL },
+
{ ngx_string("open_file_cache_retest"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_sec_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, open_file_cache_retest),
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
+ &ngx_conf_deprecated_open_file_cache_retest },
+
+ { ngx_string("open_file_cache_min_uses"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
NULL },
{ ngx_string("open_file_cache_errors"),
@@ -508,6 +560,38 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
NULL },
+#if (NGX_HTTP_GZIP)
+
+ { ngx_string("gzip_vary"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, gzip_vary),
+ NULL },
+
+ { ngx_string("gzip_http_version"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
+ &ngx_http_gzip_http_version },
+
+ { ngx_string("gzip_proxied"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_conf_set_bitmask_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
+ &ngx_http_gzip_proxied_mask },
+
+ { ngx_string("gzip_disable"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_gzip_disable,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+#endif
+
ngx_null_command
};
@@ -600,6 +684,7 @@ ngx_http_handler(ngx_http_request_t *r)
}
r->valid_location = 1;
+ r->gzip = 0;
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
@@ -1386,6 +1471,164 @@ ngx_http_auth_basic_user(ngx_http_request_t *r)
}
+#if (NGX_HTTP_GZIP)
+
+ngx_int_t
+ngx_http_gzip_ok(ngx_http_request_t *r)
+{
+ time_t date, expires;
+ ngx_uint_t p;
+ ngx_array_t *cc;
+ ngx_table_elt_t *e, *d;
+ ngx_http_core_loc_conf_t *clcf;
+
+ if (r->gzip == 1) {
+ return NGX_OK;
+ }
+
+ if (r->gzip == 2) {
+ return NGX_DECLINED;
+ }
+
+ r->gzip = 2;
+
+ if (r != r->main
+ || r->headers_in.accept_encoding == NULL
+ || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
+ "gzip", 4 - 1)
+ == NULL
+
+ /*
+ * if the URL (without the "http://" prefix) is longer than 253 bytes,
+ * then MSIE 4.x can not handle the compressed stream - it waits
+ * too long, hangs up or crashes
+ */
+
+ || (r->headers_in.msie4 && r->unparsed_uri.len > 200))
+ {
+ return NGX_DECLINED;
+ }
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (r->http_version < clcf->gzip_http_version) {
+ return NGX_DECLINED;
+ }
+
+ if (r->headers_in.via == NULL) {
+ goto ok;
+ }
+
+ p = clcf->gzip_proxied;
+
+ if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
+ return NGX_DECLINED;
+ }
+
+ if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
+ goto ok;
+ }
+
+ if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
+ goto ok;
+ }
+
+ e = r->headers_out.expires;
+
+ if (e) {
+
+ if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
+ return NGX_DECLINED;
+ }
+
+ expires = ngx_http_parse_time(e->value.data, e->value.len);
+ if (expires == NGX_ERROR) {
+ return NGX_DECLINED;
+ }
+
+ d = r->headers_out.date;
+
+ if (d) {
+ date = ngx_http_parse_time(d->value.data, d->value.len);
+ if (date == NGX_ERROR) {
+ return NGX_DECLINED;
+ }
+
+ } else {
+ date = ngx_time();
+ }
+
+ if (expires < date) {
+ goto ok;
+ }
+
+ return NGX_DECLINED;
+ }
+
+ cc = &r->headers_out.cache_control;
+
+ if (cc->elts) {
+
+ if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
+ && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
+ NULL)
+ >= 0)
+ {
+ goto ok;
+ }
+
+ if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
+ && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
+ NULL)
+ >= 0)
+ {
+ goto ok;
+ }
+
+ if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
+ && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
+ NULL)
+ >= 0)
+ {
+ goto ok;
+ }
+
+ return NGX_DECLINED;
+ }
+
+ if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
+ return NGX_DECLINED;
+ }
+
+ if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
+ return NGX_DECLINED;
+ }
+
+ok:
+
+#if (NGX_PCRE)
+
+ if (clcf->gzip_disable && r->headers_in.user_agent) {
+
+ if (ngx_regex_exec_array(clcf->gzip_disable,
+ &r->headers_in.user_agent->value,
+ r->connection->log)
+ != NGX_DECLINED)
+ {
+ return NGX_DECLINED;
+ }
+ }
+
+#endif
+
+ r->gzip = 1;
+
+ return NGX_OK;
+}
+
+#endif
+
+
ngx_int_t
ngx_http_subrequest(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
@@ -2386,6 +2629,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
* lcf->exact_match = 0;
* lcf->auto_redirect = 0;
* lcf->alias = 0;
+ * lcf->gzip_proxied = 0;
*/
lcf->client_max_body_size = NGX_CONF_UNSET;
@@ -2416,11 +2660,19 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->server_tokens = NGX_CONF_UNSET;
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
+
lcf->open_file_cache = NGX_CONF_UNSET_PTR;
- lcf->open_file_cache_retest = NGX_CONF_UNSET;
+ lcf->open_file_cache_valid = NGX_CONF_UNSET;
+ lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
lcf->open_file_cache_errors = NGX_CONF_UNSET;
lcf->open_file_cache_events = NGX_CONF_UNSET;
+#if (NGX_HTTP_GZIP)
+ lcf->gzip_vary = NGX_CONF_UNSET;
+ lcf->gzip_http_version = NGX_CONF_UNSET_UINT;
+ lcf->gzip_disable = NGX_CONF_UNSET_PTR;
+#endif
+
return lcf;
}
@@ -2618,16 +2870,30 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
ngx_conf_merge_ptr_value(conf->open_file_cache,
- prev->open_file_cache, NULL);
+ prev->open_file_cache, NULL);
+
+ ngx_conf_merge_sec_value(conf->open_file_cache_valid,
+ prev->open_file_cache_valid, 60);
- ngx_conf_merge_sec_value(conf->open_file_cache_retest,
- prev->open_file_cache_retest, 60);
+ ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
+ prev->open_file_cache_min_uses, 1);
ngx_conf_merge_sec_value(conf->open_file_cache_errors,
- prev->open_file_cache_errors, 0);
+ prev->open_file_cache_errors, 0);
ngx_conf_merge_sec_value(conf->open_file_cache_events,
- prev->open_file_cache_events, 0);
+ prev->open_file_cache_events, 0);
+#if (NGX_HTTP_GZIP)
+
+ ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
+ ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
+ NGX_HTTP_VERSION_11);
+ ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
+ (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
+
+ ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
+
+#endif
return NGX_CONF_OK;
}
@@ -2869,8 +3135,7 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
sn->regex = NULL;
#endif
sn->core_srv_conf = cscf;
- sn->name.len = value[i].len;
- sn->name.data = value[i].data;
+ sn->name = value[i];
if (value[i].data[0] != '~') {
continue;
@@ -2895,8 +3160,7 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- sn->name.len = value[i].len;
- sn->name.data = value[i].data;
+ sn->name = value[i];
}
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3418,6 +3682,63 @@ ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
+#if (NGX_HTTP_GZIP)
+
+static char *
+ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+#if (NGX_PCRE)
+ ngx_http_core_loc_conf_t *clcf = conf;
+
+ ngx_str_t err, *value;
+ ngx_uint_t i;
+ ngx_regex_elt_t *re;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
+
+ if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
+ clcf->gzip_disable = ngx_array_create(cf->pool, 2,
+ sizeof(ngx_regex_elt_t));
+ if (clcf->gzip_disable == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ value = cf->args->elts;
+
+ err.len = NGX_MAX_CONF_ERRSTR;
+ err.data = errstr;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ re = ngx_array_push(clcf->gzip_disable);
+ if (re == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
+ &err);
+
+ if (re->regex == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
+ return NGX_CONF_ERROR;
+ }
+
+ re->name = value[i].data;
+ }
+
+ return NGX_CONF_OK;
+
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"gzip_disable\" requires PCRE library");
+
+ return NGX_CONF_ERROR;
+#endif
+}
+
+#endif
+
+
static char *
ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 2027f511e..616d0b489 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -13,6 +13,17 @@
#include <ngx_http.h>
+#define NGX_HTTP_GZIP_PROXIED_OFF 0x0002
+#define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004
+#define NGX_HTTP_GZIP_PROXIED_NO_CACHE 0x0008
+#define NGX_HTTP_GZIP_PROXIED_NO_STORE 0x0010
+#define NGX_HTTP_GZIP_PROXIED_PRIVATE 0x0020
+#define NGX_HTTP_GZIP_PROXIED_NO_LM 0x0040
+#define NGX_HTTP_GZIP_PROXIED_NO_ETAG 0x0080
+#define NGX_HTTP_GZIP_PROXIED_AUTH 0x0100
+#define NGX_HTTP_GZIP_PROXIED_ANY 0x0200
+
+
typedef struct {
unsigned default_server:1;
unsigned bind:1;
@@ -290,12 +301,24 @@ struct ngx_http_core_loc_conf_s {
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
ngx_flag_t server_tokens; /* server_tokens */
+#if (NGX_HTTP_GZIP)
+ ngx_flag_t gzip_vary; /* gzip_vary */
+
+ ngx_uint_t gzip_http_version; /* gzip_http_version */
+ ngx_uint_t gzip_proxied; /* gzip_proxied */
+
+#if (NGX_PCRE)
+ ngx_array_t *gzip_disable; /* gzip_disable */
+#endif
+#endif
+
ngx_array_t *error_pages; /* error_page */
ngx_path_t *client_body_temp_path; /* client_body_temp_path */
ngx_open_file_cache_t *open_file_cache;
- time_t open_file_cache_retest;
+ time_t open_file_cache_valid;
+ ngx_uint_t open_file_cache_min_uses;
ngx_flag_t open_file_cache_errors;
ngx_flag_t open_file_cache_events;
@@ -329,6 +352,10 @@ ngx_int_t ngx_http_set_exten(ngx_http_request_t *r);
u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
size_t *root_length, size_t reserved);
ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);
+#if (NGX_HTTP_GZIP)
+ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);
+#endif
+
ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **sr,
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 63ecfa135..6e80f090a 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -521,10 +521,8 @@ ngx_http_header_filter(ngx_http_request_t *r)
*b->last++ = CR; *b->last++ = LF;
}
-#if (NGX_DEBUG)
- *b->last = '\0';
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "%s\n", b->pos);
-#endif
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "%*s\n", (size_t) (b->last - b->pos), b->pos);
/* the end of HTTP header */
*b->last++ = CR; *b->last++ = LF;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index c04c6f9d6..a5ebf1292 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1595,7 +1595,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
}
- if (rc == NGX_ERROR || rc == NGX_HTTP_REQUEST_TIME_OUT || c->error) {
+ if (rc == NGX_ERROR
+ || rc == NGX_HTTP_REQUEST_TIME_OUT
+ || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
+ || c->error)
+ {
if (rc > 0 && r->headers_out.status == 0) {
r->headers_out.status = rc;
}
@@ -1677,8 +1681,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http fast subrequest: \"%V?%V\" done",
- &r->uri, &r->args);
+ "http fast subrequest: \"%V?%V\" done",
+ &r->uri, &r->args);
return;
}
@@ -2112,6 +2116,12 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
hc->nbusy = 0;
}
+#if (NGX_HTTP_SSL)
+ if (c->ssl) {
+ ngx_ssl_free_buffer(c);
+ }
+#endif
+
rev->handler = ngx_http_keepalive_handler;
if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 86687cf91..1ff140aed 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -430,6 +430,8 @@ struct ngx_http_request_s {
unsigned header_timeout_set:1;
+ unsigned gzip:2;
+
unsigned proxy:1;
unsigned bypass_cache:1;
unsigned no_cache:1;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 96f618abe..e30fda254 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -976,7 +976,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;
- of.retest = clcf->open_file_cache_retest;
+ 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;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 2a01a4477..cb9bcd044 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2123,7 +2123,9 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
ngx_str_t *temp, path, *last_modified;
ngx_temp_file_t *tf;
- if (u->pipe->temp_file->file.fd == NGX_INVALID_FILE) {
+ tf = u->pipe->temp_file;
+
+ if (tf->file.fd == NGX_INVALID_FILE) {
/* create file for empty 200 response */
@@ -2148,7 +2150,7 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
u->pipe->temp_file = tf;
}
- temp = &u->pipe->temp_file->file.name;
+ temp = &tf->file.name;
#if !(NGX_WIN32)
@@ -2171,9 +2173,7 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
lm = ngx_http_parse_time(last_modified->data, last_modified->len);
if (lm != NGX_ERROR) {
- if (ngx_set_file_time(temp->data, u->pipe->temp_file->file.fd, lm)
- != NGX_OK)
- {
+ if (ngx_set_file_time(temp->data, tf->file.fd, lm) != NGX_OK) {
err = ngx_errno;
failed = ngx_set_file_time_n;
name = temp->data;
diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c
index 84722f4ee..6a49a0ab7 100644
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -29,6 +29,7 @@ static void ngx_mail_smtp_log_rejected_command(ngx_mail_session_t *s,
static u_char smtp_ok[] = "250 2.0.0 OK" CRLF;
static u_char smtp_bye[] = "221 2.0.0 Bye" CRLF;
+static u_char smtp_starttls[] = "220 2.0.0 Start TLS" CRLF;
static u_char smtp_next[] = "334 " CRLF;
static u_char smtp_username[] = "334 VXNlcm5hbWU6" CRLF;
static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF;
@@ -250,6 +251,8 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
case NGX_SMTP_STARTTLS:
rc = ngx_mail_smtp_starttls(s, c);
+ s->out.len = sizeof(smtp_starttls) - 1;
+ s->out.data = smtp_starttls;
break;
default:
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 07665345a..7360539ca 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -208,10 +208,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
ngx_conf_merge_str_value(conf->certificate, prev->certificate,
- NGX_DEFLAUT_CERTIFICATE);
+ NGX_DEFLAUT_CERTIFICATE);
ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key,
- NGX_DEFLAUT_CERTIFICATE_KEY);
+ NGX_DEFLAUT_CERTIFICATE_KEY);
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFLAUT_CIPHERS);
@@ -261,8 +261,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
ngx_conf_merge_value(conf->builtin_session_cache,
- prev->builtin_session_cache,
- NGX_SSL_DFLT_BUILTIN_SCACHE);
+ prev->builtin_session_cache, NGX_SSL_NO_SCACHE);
if (conf->shm_zone == NULL) {
conf->shm_zone = prev->shm_zone;
@@ -294,6 +293,11 @@ ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (i = 1; i < cf->args->nelts; i++) {
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+ scf->builtin_session_cache = NGX_SSL_NO_SCACHE;
+ continue;
+ }
+
if (ngx_strcmp(value[i].data, "builtin") == 0) {
scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
continue;
diff --git a/src/os/unix/ngx_freebsd.h b/src/os/unix/ngx_freebsd.h
index f202f8f87..c3be2bcfc 100644
--- a/src/os/unix/ngx_freebsd.h
+++ b/src/os/unix/ngx_freebsd.h
@@ -11,13 +11,14 @@
ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
-extern int ngx_freebsd_kern_osreldate;
-extern int ngx_freebsd_hw_ncpu;
-extern u_long ngx_freebsd_net_inet_tcp_sendspace;
-extern int ngx_freebsd_kern_ipc_zero_copy_send;
-
-extern ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
-extern ngx_uint_t ngx_freebsd_use_tcp_nopush;
+extern int ngx_freebsd_kern_osreldate;
+extern int ngx_freebsd_hw_ncpu;
+extern u_long ngx_freebsd_net_inet_tcp_sendspace;
+extern int ngx_freebsd_kern_ipc_zero_copy_send;
+
+extern ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
+extern ngx_uint_t ngx_freebsd_use_tcp_nopush;
+extern ngx_uint_t ngx_freebsd_debug_malloc;
#endif /* _NGX_FREEBSD_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c
index 26499bd32..a2b4c5731 100644
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -23,8 +23,9 @@ int ngx_freebsd_machdep_hlt_logical_cpus;
int ngx_freebsd_kern_ipc_zero_copy_send;
-ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
-ngx_uint_t ngx_freebsd_use_tcp_nopush;
+ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
+ngx_uint_t ngx_freebsd_use_tcp_nopush;
+ngx_uint_t ngx_freebsd_debug_malloc;
static ngx_os_io_t ngx_freebsd_io = {
@@ -86,6 +87,16 @@ ngx_debug_init()
malloc_options = "J";
#endif
+ ngx_freebsd_debug_malloc = 1;
+
+#else
+ char *mo;
+
+ mo = getenv("MALLOC_OPTIONS");
+
+ if (mo && ngx_strchr(mo, 'J')) {
+ ngx_freebsd_debug_malloc = 1;
+ }
#endif
}