summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2010-10-18 12:03:33 +0000
committerJonathan Kolb <jon@b0g.us>2010-10-18 12:03:33 +0000
commitdf5fa5fcb16c6fd65657add97be5f056b58afa36 (patch)
tree762b0932347c1c85ba59028d0030caed81bb8220
parentd2ddc4ba6cf543fa5853ebb2e5f0ee7be6fd2ba5 (diff)
downloadnginx-0.8.53.tar.gz
Changes with nginx 0.8.53 18 Oct 2010v0.8.53
*) Feature: now the "error_page" directive allows to change a status code in a redirect. *) Feature: the "gzip_disable" directive supports special "degradation" mask. *) Bugfix: a socket leak might occurred if file AIO was used. Thanks to Maxim Dounin. *) Bugfix: if the first server had no "listen" directive and there was no explicit default server, then a next server with a "listen" directive became the default server; the bug had appeared in 0.8.21.
-rw-r--r--CHANGES18
-rw-r--r--CHANGES.ru20
-rw-r--r--auto/modules1
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_output_chain.c12
-rw-r--r--src/http/modules/ngx_http_degradation_module.c43
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c12
-rw-r--r--src/http/modules/ngx_http_limit_req_module.c125
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http.h4
-rw-r--r--src/http/ngx_http_copy_filter_module.c7
-rw-r--r--src/http/ngx_http_core_module.c126
-rw-r--r--src/http/ngx_http_core_module.h3
-rw-r--r--src/http/ngx_http_special_response.c8
-rw-r--r--src/os/unix/ngx_linux_aio_read.c4
15 files changed, 246 insertions, 143 deletions
diff --git a/CHANGES b/CHANGES
index 6cad1d127..d88a74b31 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,20 @@
+Changes with nginx 0.8.53 18 Oct 2010
+
+ *) Feature: now the "error_page" directive allows to change a status
+ code in a redirect.
+
+ *) Feature: the "gzip_disable" directive supports special "degradation"
+ mask.
+
+ *) Bugfix: a socket leak might occurred if file AIO was used.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: if the first server had no "listen" directive and there was
+ no explicit default server, then a next server with a "listen"
+ directive became the default server; the bug had appeared in 0.8.21.
+
+
Changes with nginx 0.8.52 28 Sep 2010
*) Bugfix: nginx used SSL mode for a listen socket if any listen option
@@ -131,7 +147,7 @@ Changes with nginx 0.8.44 05 Jul 2010
*) Bugfix: compatibility with HP/UX.
- *) Bugfix: compatibility with AIX xcl_r compiler.
+ *) Bugfix: compatibility with AIX xlC_r compiler.
*) Bugfix: nginx treated large SSLv2 packets as plain requests.
Thanks to Miroslaw Jaworski.
diff --git a/CHANGES.ru b/CHANGES.ru
index e23cf6911..be2892166 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,22 @@
+Изменения в nginx 0.8.53 18.10.2010
+
+ *) Добавление: теперь директива error_page позволяет менять код статуса
+ у редиректа.
+
+ *) Добавление: директива gzip_disable поддерживает специальную маску
+ degradation.
+
+ *) Исправление: при использовании файлового AIO, могла происходить
+ утечка сокетов.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: если в первом сервере не была описана директива listen
+ и нигде явно не описан сервер по умолчанию, то сервером по умолчанию
+ становился следующий сервер с директивой listen; ошибка появилась в
+ 0.8.21.
+
+
Изменения в nginx 0.8.52 28.09.2010
*) Исправление: nginx использовал режим SSL для listen сокета, если для
@@ -129,7 +147,7 @@
*) Исправление: совместимость с HP/UX.
- *) Исправление: совместимость с компилятором AIX xcl_r.
+ *) Исправление: совместимость с компилятором AIX xlC_r.
*) Исправление: nginx считал большие пакеты SSLv2 как обычные текстовые
запросы.
diff --git a/auto/modules b/auto/modules
index 9880b99dc..9ac1ddd07 100644
--- a/auto/modules
+++ b/auto/modules
@@ -322,6 +322,7 @@ if [ $HTTP_SECURE_LINK = YES ]; then
fi
if [ $HTTP_DEGRADATION = YES ]; then
+ have=NGX_HTTP_DEGRADATION . auto/have
HTTP_MODULES="$HTTP_MODULES $HTTP_DEGRADATION_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_DEGRADATION_SRCS"
fi
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 918603817..208a5f634 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8052
-#define NGINX_VERSION "0.8.52"
+#define nginx_version 8053
+#define NGINX_VERSION "0.8.53"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index f51d69000..4f100a818 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -74,18 +74,18 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
}
}
-#if (NGX_HAVE_FILE_AIO)
- if (ctx->aio) {
- return NGX_AGAIN;
- }
-#endif
-
out = NULL;
last_out = &out;
last = NGX_NONE;
for ( ;; ) {
+#if (NGX_HAVE_FILE_AIO)
+ if (ctx->aio) {
+ return NGX_AGAIN;
+ }
+#endif
+
while (ctx->in) {
/*
diff --git a/src/http/modules/ngx_http_degradation_module.c b/src/http/modules/ngx_http_degradation_module.c
index b221f2215..a35733f81 100644
--- a/src/http/modules/ngx_http_degradation_module.c
+++ b/src/http/modules/ngx_http_degradation_module.c
@@ -86,25 +86,38 @@ ngx_module_t ngx_http_degradation_module = {
};
+static ngx_uint_t ngx_degraded;
+
+
static ngx_int_t
ngx_http_degradation_handler(ngx_http_request_t *r)
{
- time_t now;
- static size_t sbrk_size;
- static time_t sbrk_time;
- ngx_http_degradation_loc_conf_t *dlcf;
- ngx_http_degradation_main_conf_t *dmcf;
+ ngx_http_degradation_loc_conf_t *dlcf;
dlcf = ngx_http_get_module_loc_conf(r, ngx_http_degradation_module);
- if (dlcf->degrade == 0) {
- return NGX_DECLINED;
+ if (dlcf->degrade && ngx_http_degraded(r)) {
+ return dlcf->degrade;
}
+ return NGX_DECLINED;
+}
+
+
+ngx_uint_t
+ngx_http_degraded(ngx_http_request_t *r)
+{
+ time_t now;
+ ngx_uint_t log;
+ static size_t sbrk_size;
+ static time_t sbrk_time;
+ ngx_http_degradation_main_conf_t *dmcf;
+
dmcf = ngx_http_get_module_main_conf(r, ngx_http_degradation_module);
if (dmcf->sbrk_size) {
+ log = 0;
now = ngx_time();
/* lock mutex */
@@ -120,19 +133,27 @@ ngx_http_degradation_handler(ngx_http_request_t *r)
sbrk_size = (size_t) sbrk(0) - ((uintptr_t) ngx_palloc & ~0x3FFFFF);
sbrk_time = now;
+ log = 1;
}
/* unlock mutex */
if (sbrk_size >= dmcf->sbrk_size) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "degradation sbrk: %uz", sbrk_size);
+ ngx_degraded = 1;
+
+ if (log) {
+ ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
+ "degradation sbrk:%uzM",
+ sbrk_size / (1024 * 1024));
+ }
- return dlcf->degrade;
+ return 1;
}
}
- return NGX_DECLINED;
+ ngx_degraded = 0;
+
+ return 0;
}
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index e2b204ba2..d624e36ff 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -258,6 +258,18 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
r->gzip_vary = 1;
+#if (NGX_HTTP_DEGRADATION)
+ {
+ ngx_http_core_loc_conf_t *clcf;
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->gzip_disable_degradation && ngx_http_degraded(r)) {
+ return ngx_http_next_header_filter(r);
+ }
+ }
+#endif
+
if (!r->gzip_tested) {
if (ngx_http_gzip_ok(r) != NGX_OK) {
return ngx_http_next_header_filter(r);
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index 38711aa82..718fae8e2 100644
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -51,7 +51,7 @@ typedef struct {
static void ngx_http_limit_req_delay(ngx_http_request_t *r);
static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf,
- ngx_uint_t hash, u_char *data, size_t len, ngx_http_limit_req_node_t **lrp);
+ ngx_uint_t hash, u_char *data, size_t len, ngx_uint_t *ep);
static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx,
ngx_uint_t n);
@@ -186,97 +186,83 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
ngx_http_limit_req_expire(ctx, 1);
- rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &lr);
-
- if (lr) {
- ngx_queue_remove(&lr->queue);
-
- ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
-
- excess = lr->excess;
-
- } else {
- excess = 0;
- }
+ rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &excess);
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000);
- if (rc == NGX_BUSY) {
- ngx_shmtx_unlock(&ctx->shpool->mutex);
+ if (rc == NGX_DECLINED) {
- ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
- "limiting requests, excess: %ui.%03ui by zone \"%V\"",
- excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
+ n = offsetof(ngx_rbtree_node_t, color)
+ + offsetof(ngx_http_limit_req_node_t, data)
+ + len;
- return NGX_HTTP_SERVICE_UNAVAILABLE;
- }
+ node = ngx_slab_alloc_locked(ctx->shpool, n);
+ if (node == NULL) {
- if (rc == NGX_AGAIN) {
- ngx_shmtx_unlock(&ctx->shpool->mutex);
+ ngx_http_limit_req_expire(ctx, 0);
- if (lrcf->nodelay) {
- return NGX_DECLINED;
+ node = ngx_slab_alloc_locked(ctx->shpool, n);
+ if (node == NULL) {
+ ngx_shmtx_unlock(&ctx->shpool->mutex);
+ return NGX_HTTP_SERVICE_UNAVAILABLE;
+ }
}
- ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
- "delaying request, excess: %ui.%03ui, by zone \"%V\"",
- excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
+ lr = (ngx_http_limit_req_node_t *) &node->color;
- if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ node->key = hash;
+ lr->len = (u_char) len;
- r->read_event_handler = ngx_http_test_reading;
- r->write_event_handler = ngx_http_limit_req_delay;
- ngx_add_timer(r->connection->write,
- (ngx_msec_t) excess * 1000 / ctx->rate);
+ tp = ngx_timeofday();
+ lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
- return NGX_AGAIN;
- }
+ lr->excess = 0;
+ ngx_memcpy(lr->data, vv->data, len);
- if (rc == NGX_OK) {
- goto done;
- }
+ ngx_rbtree_insert(&ctx->sh->rbtree, node);
- /* rc == NGX_DECLINED */
+ ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
- n = offsetof(ngx_rbtree_node_t, color)
- + offsetof(ngx_http_limit_req_node_t, data)
- + len;
+ ngx_shmtx_unlock(&ctx->shpool->mutex);
- node = ngx_slab_alloc_locked(ctx->shpool, n);
- if (node == NULL) {
+ return NGX_DECLINED;
+ }
- ngx_http_limit_req_expire(ctx, 0);
+ ngx_shmtx_unlock(&ctx->shpool->mutex);
- node = ngx_slab_alloc_locked(ctx->shpool, n);
- if (node == NULL) {
- ngx_shmtx_unlock(&ctx->shpool->mutex);
- return NGX_HTTP_SERVICE_UNAVAILABLE;
- }
+ if (rc == NGX_OK) {
+ return NGX_DECLINED;
}
- lr = (ngx_http_limit_req_node_t *) &node->color;
-
- node->key = hash;
- lr->len = (u_char) len;
+ if (rc == NGX_BUSY) {
+ ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
+ "limiting requests, excess: %ui.%03ui by zone \"%V\"",
+ excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
- tp = ngx_timeofday();
- lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
+ return NGX_HTTP_SERVICE_UNAVAILABLE;
+ }
- lr->excess = 0;
- ngx_memcpy(lr->data, vv->data, len);
+ /* rc == NGX_AGAIN */
- ngx_rbtree_insert(&ctx->sh->rbtree, node);
+ if (lrcf->nodelay) {
+ return NGX_DECLINED;
+ }
- ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
+ ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
+ "delaying request, excess: %ui.%03ui, by zone \"%V\"",
+ excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
-done:
+ if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
- ngx_shmtx_unlock(&ctx->shpool->mutex);
+ r->read_event_handler = ngx_http_test_reading;
+ r->write_event_handler = ngx_http_limit_req_delay;
+ ngx_add_timer(r->connection->write,
+ (ngx_msec_t) excess * 1000 / ctx->rate);
- return NGX_DECLINED;
+ return NGX_AGAIN;
}
@@ -356,7 +342,7 @@ ngx_http_limit_req_rbtree_insert_value(ngx_rbtree_node_t *temp,
static ngx_int_t
ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
- u_char *data, size_t len, ngx_http_limit_req_node_t **lrp)
+ u_char *data, size_t len, ngx_uint_t *ep)
{
ngx_int_t rc, excess;
ngx_time_t *tp;
@@ -391,6 +377,8 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
if (rc == 0) {
+ ngx_queue_remove(&lr->queue);
+ ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
tp = ngx_timeofday();
@@ -403,16 +391,15 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
excess = 0;
}
+ *ep = excess;
+
if ((ngx_uint_t) excess > lrcf->burst) {
- *lrp = lr;
return NGX_BUSY;
}
lr->excess = excess;
lr->last = now;
- *lrp = lr;
-
if (excess) {
return NGX_AGAIN;
}
@@ -427,7 +414,7 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
break;
}
- *lrp = NULL;
+ *ep = 0;
return NGX_DECLINED;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index c962360b1..faff340e2 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -48,7 +48,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.8.52';
+our $VERSION = '0.8.53';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 9351cb09a..e3619e148 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -142,6 +142,10 @@ char *ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys,
ngx_int_t ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
ngx_str_t *default_type);
+#if (NGX_HTTP_DEGRADATION)
+ngx_uint_t ngx_http_degraded(ngx_http_request_t *);
+#endif
+
extern ngx_module_t ngx_http_module;
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index d492f321d..2eb6487d8 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -118,8 +118,10 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->filter_ctx = r;
#if (NGX_HAVE_FILE_AIO)
- if (ngx_file_aio && clcf->aio) {
- ctx->aio_handler = ngx_http_copy_aio_handler;
+ if (ngx_file_aio) {
+ if (clcf->aio) {
+ ctx->aio_handler = ngx_http_copy_aio_handler;
+ }
#if (NGX_HAVE_AIO_SENDFILE)
c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE);
#endif
@@ -211,6 +213,7 @@ ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, ngx_file_t *file)
r->main->blocked++;
r->aio = 1;
+ ctx->aio = 1;
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 73cde3d82..0345be965 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2427,7 +2427,9 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_uint_t i;
ngx_conf_t pcf;
ngx_http_module_t *module;
+ struct sockaddr_in *sin;
ngx_http_conf_ctx_t *ctx, *http_ctx;
+ ngx_http_listen_opt_t lsopt;
ngx_http_core_srv_conf_t *cscf, **cscfp;
ngx_http_core_main_conf_t *cmcf;
@@ -2506,6 +2508,37 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
*cf = pcf;
+ if (rv == NGX_CONF_OK && !cscf->listen) {
+ ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
+
+ sin = &lsopt.u.sockaddr_in;
+
+ sin->sin_family = AF_INET;
+#if (NGX_WIN32)
+ sin->sin_port = htons(80);
+#else
+ sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
+#endif
+ sin->sin_addr.s_addr = INADDR_ANY;
+
+ lsopt.socklen = sizeof(struct sockaddr_in);
+
+ lsopt.backlog = NGX_LISTEN_BACKLOG;
+ lsopt.rcvbuf = -1;
+ lsopt.sndbuf = -1;
+#if (NGX_HAVE_SETFIB)
+ lsopt.setfib = -1;
+#endif
+ lsopt.wildcard = 1;
+
+ (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
+ NGX_SOCKADDR_STRLEN, 1);
+
+ if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
return rv;
}
@@ -2946,8 +2979,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_core_srv_conf_t *prev = parent;
ngx_http_core_srv_conf_t *conf = child;
- struct sockaddr_in *sin;
- ngx_http_listen_opt_t lsopt;
ngx_http_server_name_t *sn;
/* TODO: it does not merge, it inits only */
@@ -2979,37 +3010,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->underscores_in_headers,
prev->underscores_in_headers, 0);
- if (!conf->listen) {
- ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
-
- sin = &lsopt.u.sockaddr_in;
-
- sin->sin_family = AF_INET;
-#if (NGX_WIN32)
- sin->sin_port = htons(80);
-#else
- sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
-#endif
- sin->sin_addr.s_addr = INADDR_ANY;
-
- lsopt.socklen = sizeof(struct sockaddr_in);
-
- lsopt.backlog = NGX_LISTEN_BACKLOG;
- lsopt.rcvbuf = -1;
- lsopt.sndbuf = -1;
-#if (NGX_HAVE_SETFIB)
- lsopt.setfib = -1;
-#endif
- lsopt.wildcard = 1;
-
- (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
- NGX_SOCKADDR_STRLEN, 1);
-
- if (ngx_http_add_listen(cf, conf, &lsopt) == NGX_OK) {
- return NGX_CONF_OK;
- }
- }
-
if (conf->server_name.data == NULL) {
ngx_str_set(&conf->server_name, "");
@@ -3113,6 +3113,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
clcf->gzip_disable = NGX_CONF_UNSET_PTR;
#endif
clcf->gzip_disable_msie6 = 3;
+#if (NGX_HTTP_DEGRADATION)
+ clcf->gzip_disable_degradation = 3;
+#endif
#endif
return clcf;
@@ -3373,6 +3376,15 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
(prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
}
+#if (NGX_HTTP_DEGRADATION)
+
+ if (conf->gzip_disable_degradation == 3) {
+ conf->gzip_disable_degradation =
+ (prev->gzip_disable_degradation == 3) ?
+ 0 : prev->gzip_disable_degradation;
+ }
+
+#endif
#endif
return NGX_CONF_OK;
@@ -4057,19 +4069,15 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- if (overwrite >= 0) {
- err->overwrite = overwrite;
+ err->overwrite = overwrite;
- } else {
+ if (overwrite == -1) {
switch (err->status) {
case NGX_HTTP_TO_HTTPS:
case NGX_HTTPS_CERT_ERROR:
case NGX_HTTPS_NO_CERT:
err->overwrite = NGX_HTTP_BAD_REQUEST;
- break;
-
default:
- err->overwrite = err->status;
break;
}
}
@@ -4394,6 +4402,15 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+#if (NGX_HTTP_DEGRADATION)
+
+ if (ngx_strcmp(value[i].data, "degradation") == 0) {
+ clcf->gzip_disable_degradation = 1;
+ continue;
+ }
+
+#endif
+
re = ngx_array_push(clcf->gzip_disable);
if (re == NULL) {
return NGX_CONF_ERROR;
@@ -4414,20 +4431,35 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
#else
- ngx_str_t *value;
+ ngx_str_t *value;
+ ngx_uint_t i;
value = cf->args->elts;
- if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "msie6") == 0) {
- clcf->gzip_disable_msie6 = 1;
- return NGX_CONF_OK;
+ for (i = 1; i < cf->args->nelts; i++) {
+ if (ngx_strcmp(value[i].data, "msie6") == 0) {
+ clcf->gzip_disable_msie6 = 1;
+ continue;
+ }
+
+#if (NGX_HTTP_DEGRADATION)
+
+ if (ngx_strcmp(value[i].data, "degradation") == 0) {
+ clcf->gzip_disable_degradation = 1;
+ continue;
+ }
+
+#endif
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "without PCRE library \"gzip_disable\" supports "
+ "builtin \"msie6\" and \"degradation\" mask only");
+
+ return NGX_CONF_ERROR;
}
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "without PCRE library \"gzip_disable\" supports "
- "builtin \"msie6\" mask only");
+ return NGX_CONF_OK;
- return NGX_CONF_ERROR;
#endif
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index f163e9aeb..273586b1c 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -295,6 +295,9 @@ struct ngx_http_core_loc_conf_s {
unsigned auto_redirect:1;
#if (NGX_HTTP_GZIP)
unsigned gzip_disable_msie6:2;
+#if (NGX_HTTP_DEGRADATION)
+ unsigned gzip_disable_degradation:2;
+#endif
#endif
ngx_http_location_tree_node_t *static_locations;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 1b7eacec6..19a4bd9ae 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -523,7 +523,9 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
r->expect_tested = 1;
}
- r->err_status = overwrite;
+ if (overwrite >= 0) {
+ r->err_status = overwrite;
+ }
if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {
return NGX_ERROR;
@@ -556,7 +558,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
return NGX_ERROR;
}
- r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
+ r->err_status = overwrite > 0 ? overwrite : NGX_HTTP_MOVED_TEMPORARILY;
location->hash = 1;
ngx_str_set(&location->key, "Location");
@@ -570,7 +572,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
return ngx_http_send_refresh(r);
}
- return ngx_http_send_special_response(r, clcf, NGX_HTTP_MOVED_TEMPORARILY
+ return ngx_http_send_special_response(r, clcf, r->err_status
- NGX_HTTP_MOVED_PERMANENTLY
+ NGX_HTTP_LEVEL_200);
}
diff --git a/src/os/unix/ngx_linux_aio_read.c b/src/os/unix/ngx_linux_aio_read.c
index 834a11d07..72875ca01 100644
--- a/src/os/unix/ngx_linux_aio_read.c
+++ b/src/os/unix/ngx_linux_aio_read.c
@@ -95,6 +95,10 @@ ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
n = io_submit(ngx_aio_ctx, 1, piocb);
if (n == 1) {
+ ev->active = 1;
+ ev->ready = 0;
+ ev->complete = 0;
+
return NGX_AGAIN;
}