summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2011-11-28 16:01:26 +0000
committerJonathan Kolb <jon@b0g.us>2011-11-28 16:01:26 +0000
commit7989e17482b6bd13b83a9e63a9c4f58f3432945a (patch)
tree1cdcc09ac8773fe4b03e110b296db210d6d22265
parentfe0ffd542b079021418c77ba3281df919ed1bf71 (diff)
downloadnginx-7989e17482b6bd13b83a9e63a9c4f58f3432945a.tar.gz
Changes with nginx 1.1.9 28 Nov 2011v1.1.9
*) Change: now double quotes are encoded in an "echo" SSI-command output. Thanks to Zaur Abasmirzoev. *) Feature: the "valid" parameter of the "resolver" directive. By default TTL returned by a DNS server is used. Thanks to Kirill A. Korinskiy. *) Bugfix: nginx might hang after a worker process abnormal termination. *) Bugfix: a segmentation fault might occur in a worker process if SNI was used; the bug had appeared in 1.1.2. *) Bugfix: in the "keepalive_disable" directive; the bug had appeared in 1.1.8. Thanks to Alexander Usov. *) Bugfix: SIGWINCH signal did not work after first binary upgrade; the bug had appeared in 1.1.1. *) Bugfix: backend responses with length not matching "Content-Length" header line are no longer cached. *) Bugfix: in the "scgi_param" directive, if complex parameters were used. *) Bugfix: in the "epoll" event method. Thanks to Yichun Zhang. *) Bugfix: in the ngx_http_flv_module. Thanks to Piotr Sikora. *) Bugfix: in the ngx_http_mp4_module. *) Bugfix: IPv6 addresses are now handled properly in a request line and in a "Host" request header line. *) Bugfix: "add_header" and "expires" directives did not work if a request was proxied and response status code was 206. *) Bugfix: nginx could not be built on FreeBSD 10. *) Bugfix: nginx could not be built on AIX. Maxim Dounin _______________________________________________ nginx-announce mailing list nginx-announce@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-announce
-rw-r--r--CHANGES47
-rw-r--r--CHANGES.ru47
-rw-r--r--auto/install18
-rwxr-xr-xauto/unix9
-rw-r--r--conf/mime.types2
-rw-r--r--src/core/nginx.c4
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_cycle.c2
-rw-r--r--src/core/ngx_resolver.c45
-rw-r--r--src/core/ngx_shmtx.c113
-rw-r--r--src/core/ngx_shmtx.h13
-rw-r--r--src/core/ngx_slab.h2
-rw-r--r--src/core/ngx_string.c9
-rw-r--r--src/event/modules/ngx_epoll_module.c12
-rw-r--r--src/event/ngx_event.c3
-rw-r--r--src/http/modules/ngx_http_flv_module.c2
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c1
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c12
-rw-r--r--src/http/modules/ngx_http_mp4_module.c2
-rw-r--r--src/http/modules/ngx_http_scgi_module.c4
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c2
-rw-r--r--src/http/ngx_http_parse.c64
-rw-r--r--src/http/ngx_http_request.c103
-rw-r--r--src/http/ngx_http_upstream.c12
-rw-r--r--src/os/unix/ngx_files.c2
-rw-r--r--src/os/unix/ngx_process.c61
27 files changed, 472 insertions, 125 deletions
diff --git a/CHANGES b/CHANGES
index 8eb55250d..56bed277b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,51 @@
+Changes with nginx 1.1.9 28 Nov 2011
+
+ *) Change: now double quotes are encoded in an "echo" SSI-command
+ output.
+ Thanks to Zaur Abasmirzoev.
+
+ *) Feature: the "valid" parameter of the "resolver" directive. By
+ default TTL returned by a DNS server is used.
+ Thanks to Kirill A. Korinskiy.
+
+ *) Bugfix: nginx might hang after a worker process abnormal termination.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if SNI
+ was used; the bug had appeared in 1.1.2.
+
+ *) Bugfix: in the "keepalive_disable" directive; the bug had appeared in
+ 1.1.8.
+ Thanks to Alexander Usov.
+
+ *) Bugfix: SIGWINCH signal did not work after first binary upgrade; the
+ bug had appeared in 1.1.1.
+
+ *) Bugfix: backend responses with length not matching "Content-Length"
+ header line are no longer cached.
+
+ *) Bugfix: in the "scgi_param" directive, if complex parameters were
+ used.
+
+ *) Bugfix: in the "epoll" event method.
+ Thanks to Yichun Zhang.
+
+ *) Bugfix: in the ngx_http_flv_module.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: in the ngx_http_mp4_module.
+
+ *) Bugfix: IPv6 addresses are now handled properly in a request line and
+ in a "Host" request header line.
+
+ *) Bugfix: "add_header" and "expires" directives did not work if a
+ request was proxied and response status code was 206.
+
+ *) Bugfix: nginx could not be built on FreeBSD 10.
+
+ *) Bugfix: nginx could not be built on AIX.
+
+
Changes with nginx 1.1.8 14 Nov 2011
*) Change: the ngx_http_limit_zone_module was renamed to the
diff --git a/CHANGES.ru b/CHANGES.ru
index 350b64b69..b4af1fe1c 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,51 @@
+Изменения в nginx 1.1.9 28.11.2011
+
+ *) Изменение: теперь двойные кавычки экранируется при выводе
+ SSI-командой echo.
+ Спасибо Зауру Абасмирзоеву.
+
+ *) Добавление: параметр valid в директиве resolver. По умолчанию теперь
+ используется TTL, возвращённый DNS-сервером.
+ Спасибо Кириллу Коринскому.
+
+ *) Исправление: nginx мог перестать отвечать, если рабочий процесс
+ завершался аварийно.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если использовалось SNI; ошибка появилась в 1.1.2.
+
+ *) Исправление: в директиве keepalive_disable; ошибка появилась в 1.1.8.
+ Спасибо Александру Усову.
+
+ *) Исправление: сигнал SIGWINCH переставал работать после первого
+ обновления исполняемого файла; ошибка появилась в 1.1.1.
+
+ *) Исправление: теперь ответы бэкендов, длина которых не соответствует
+ заголовку Content-Length, не кэширутся.
+
+ *) Исправление: в директиве scgi_param при использовании составных
+ параметров.
+
+ *) Исправление: в методе epoll.
+ Спасибо Yichun Zhang.
+
+ *) Исправление: в модуле ngx_http_flv_module.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: в модуле ngx_http_mp4_module.
+
+ *) Исправление: теперь nginx понимает IPv6-адреса в строке запроса и в
+ заголовке Host.
+
+ *) Исправление: директивы add_header и expires не работали для ответов с
+ кодом 206, если запрос проксировался.
+
+ *) Исправление: nginx не собирался на FreeBSD 10.
+
+ *) Исправление: nginx не собирался на AIX.
+
+
Изменения в nginx 1.1.8 14.11.2011
*) Изменение: модуль ngx_http_limit_zone_module переименован в
diff --git a/auto/install b/auto/install
index d77efbf74..d56be27ef 100644
--- a/auto/install
+++ b/auto/install
@@ -72,16 +72,28 @@ case ".$NGX_HTTP_LOG_PATH" in
esac
+if test -e man/nginx.8 ; then
+ NGX_MAN=man/nginx.8
+else
+ NGX_MAN=docs/man/nginx.8
+fi
+
+if test -d html ; then
+ NGX_HTML=html
+else
+ NGX_HTML=docs/html
+fi
+
cat << END >> $NGX_MAKEFILE
manpage: $NGX_OBJS/nginx.8
-$NGX_OBJS/nginx.8: man/nginx.8 $NGX_AUTO_CONFIG_H
+$NGX_OBJS/nginx.8: $NGX_MAN $NGX_AUTO_CONFIG_H
sed -e "s|%%PREFIX%%|$NGX_PREFIX|" \\
-e "s|%%PID_PATH%%|$NGX_PID_PATH|" \\
-e "s|%%CONF_PATH%%|$NGX_CONF_PATH|" \\
-e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\
- < man/nginx.8 > $NGX_OBJS/nginx.8
+ < $NGX_MAN > \$@
install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
$NGX_INSTALL_PERL_MODULES
@@ -135,7 +147,7 @@ install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`'
test -d '\$(DESTDIR)$NGX_PREFIX/html' \
- || cp -r html '\$(DESTDIR)$NGX_PREFIX'
+ || cp -R $NGX_HTML '\$(DESTDIR)$NGX_PREFIX'
END
diff --git a/auto/unix b/auto/unix
index ca533487c..7621e8fa2 100755
--- a/auto/unix
+++ b/auto/unix
@@ -496,7 +496,8 @@ ngx_feature_test="char buf[1]; ssize_t n; n = pwrite(1, buf, 1, 0)"
ngx_feature="sys_nerr"
ngx_feature_name="NGX_SYS_NERR"
ngx_feature_run=value
-ngx_feature_incs='#include <stdio.h>'
+ngx_feature_incs='#include <errno.h>
+ #include <stdio.h>'
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test='printf("%d", sys_nerr);'
@@ -538,10 +539,10 @@ if [ $ngx_found = no ]; then
|| p == NULL
|| strncmp(p, "Unknown error", 13) == 0)
{
- printf("%d", n);
- return 0;
+ break;
}
- }'
+ }
+ printf("%d", n);'
. auto/feature
fi
diff --git a/conf/mime.types b/conf/mime.types
index 0c4a00d59..8a218b22a 100644
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -21,7 +21,7 @@ types {
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
- image/svg+xml svg;
+ image/svg+xml svg svgz;
image/webp webp;
application/java-archive jar war ear;
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 9e00a2d86..5de48351a 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -374,6 +374,10 @@ main(int argc, char *const *argv)
ngx_daemonized = 1;
}
+ if (ngx_inherited) {
+ ngx_daemonized = 1;
+ }
+
#endif
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 4b8badc02..4bde2c713 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1001008
-#define NGINX_VERSION "1.1.8"
+#define nginx_version 1001009
+#define NGINX_VERSION "1.1.9"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index db473571f..525ef41d7 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -952,7 +952,7 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
#endif
- if (ngx_shmtx_create(&sp->mutex, (void *) &sp->lock, file) != NGX_OK) {
+ if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
return NGX_ERROR;
}
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 35818a7ae..d4af2f016 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -93,6 +93,7 @@ static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
ngx_resolver_t *
ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
{
+ ngx_str_t s;
ngx_url_t u;
ngx_uint_t i;
ngx_resolver_t *r;
@@ -146,12 +147,27 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
r->resend_timeout = 5;
r->expire = 30;
- r->valid = 300;
+ r->valid = 0;
r->log = &cf->cycle->new_log;
r->log_level = NGX_LOG_ERR;
for (i = 0; i < n; i++) {
+ if (ngx_strncmp(names[i].data, "valid=", 6) == 0) {
+ s.len = names[i].len - 6;
+ s.data = names[i].data + 6;
+
+ r->valid = ngx_parse_time(&s, 1);
+
+ if (r->valid == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter: %V", &names[i]);
+ return NULL;
+ }
+
+ continue;
+ }
+
ngx_memzero(&u, sizeof(ngx_url_t));
u.host = names[i];
@@ -1149,6 +1165,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
char *err;
u_char *cname;
size_t len;
+ int32_t ttl;
uint32_t hash;
in_addr_t addr, *addrs;
ngx_str_t name;
@@ -1219,6 +1236,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
addrs = NULL;
cname = NULL;
qtype = 0;
+ ttl = 0;
for (a = 0; a < nan; a++) {
@@ -1258,6 +1276,12 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
qtype = (an->type_hi << 8) + an->type_lo;
len = (an->len_hi << 8) + an->len_lo;
+ ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
+ + (an->ttl[2] << 8) + (an->ttl[3]);
+
+ if (ttl < 0) {
+ ttl = 0;
+ }
if (qtype == NGX_RESOLVE_A) {
@@ -1287,8 +1311,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
}
}
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver naddrs:%ui cname:%p", naddrs, cname);
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolver naddrs:%ui cname:%p ttl:%d",
+ naddrs, cname, ttl);
if (naddrs) {
@@ -1357,7 +1382,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
ngx_queue_remove(&rn->queue);
- rn->valid = ngx_time() + r->valid;
+ rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
rn->expire = ngx_time() + r->expire;
ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
@@ -1399,7 +1424,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
rn->cnlen = (u_short) name.len;
rn->u.cname = name.data;
- rn->valid = ngx_time() + r->valid;
+
+ rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
rn->expire = ngx_time() + r->expire;
ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
@@ -1450,6 +1476,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
char *err;
size_t len;
in_addr_t addr;
+ int32_t ttl;
ngx_int_t digit;
ngx_str_t name;
ngx_uint_t i, mask, qident;
@@ -1545,6 +1572,12 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
an = (ngx_resolver_an_t *) &buf[i + 2];
len = (an->len_hi << 8) + an->len_lo;
+ ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
+ + (an->ttl[2] << 8) + (an->ttl[3]);
+
+ if (ttl < 0) {
+ ttl = 0;
+ }
ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
"resolver qt:%ui cl:%ui len:%uz",
@@ -1581,7 +1614,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
ngx_queue_remove(&rn->queue);
- rn->valid = ngx_time() + r->valid;
+ rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
rn->expire = ngx_time() + r->expire;
ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
diff --git a/src/core/ngx_shmtx.c b/src/core/ngx_shmtx.c
index 3b429c4f9..8a3178e61 100644
--- a/src/core/ngx_shmtx.c
+++ b/src/core/ngx_shmtx.c
@@ -11,10 +11,13 @@
#if (NGX_HAVE_ATOMIC_OPS)
+static void ngx_shmtx_wakeup(ngx_shmtx_t *mtx);
+
+
ngx_int_t
-ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name)
+ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
{
- mtx->lock = addr;
+ mtx->lock = &addr->lock;
if (mtx->spin == (ngx_uint_t) -1) {
return NGX_OK;
@@ -24,6 +27,8 @@ ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name)
#if (NGX_HAVE_POSIX_SEM)
+ mtx->wait = &addr->wait;
+
if (sem_init(&mtx->sem, 1, 0) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
"sem_init() failed");
@@ -56,12 +61,7 @@ ngx_shmtx_destory(ngx_shmtx_t *mtx)
ngx_uint_t
ngx_shmtx_trylock(ngx_shmtx_t *mtx)
{
- ngx_atomic_uint_t val;
-
- val = *mtx->lock;
-
- return ((val & 0x80000000) == 0
- && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000));
+ return (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid));
}
@@ -69,17 +69,12 @@ void
ngx_shmtx_lock(ngx_shmtx_t *mtx)
{
ngx_uint_t i, n;
- ngx_atomic_uint_t val;
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx lock");
for ( ;; ) {
- val = *mtx->lock;
-
- if ((val & 0x80000000) == 0
- && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000))
- {
+ if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
return;
}
@@ -91,10 +86,8 @@ ngx_shmtx_lock(ngx_shmtx_t *mtx)
ngx_cpu_pause();
}
- val = *mtx->lock;
-
- if ((val & 0x80000000) == 0
- && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000))
+ if (*mtx->lock == 0
+ && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid))
{
return;
}
@@ -104,24 +97,24 @@ ngx_shmtx_lock(ngx_shmtx_t *mtx)
#if (NGX_HAVE_POSIX_SEM)
if (mtx->semaphore) {
- val = *mtx->lock;
+ (void) ngx_atomic_fetch_add(mtx->wait, 1);
- if ((val & 0x80000000)
- && ngx_atomic_cmp_set(mtx->lock, val, val + 1))
- {
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "shmtx wait %XA", val);
+ if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
+ return;
+ }
- while (sem_wait(&mtx->sem) == -1) {
- ngx_err_t err;
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
+ "shmtx wait %uA", *mtx->wait);
- err = ngx_errno;
+ while (sem_wait(&mtx->sem) == -1) {
+ ngx_err_t err;
- if (err != NGX_EINTR) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
- "sem_wait() failed while waiting on shmtx");
- break;
- }
+ err = ngx_errno;
+
+ if (err != NGX_EINTR) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
+ "sem_wait() failed while waiting on shmtx");
+ break;
}
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
@@ -141,31 +134,56 @@ ngx_shmtx_lock(ngx_shmtx_t *mtx)
void
ngx_shmtx_unlock(ngx_shmtx_t *mtx)
{
- ngx_atomic_uint_t val, old, wait;
-
if (mtx->spin != (ngx_uint_t) -1) {
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx unlock");
}
- for ( ;; ) {
+ if (ngx_atomic_cmp_set(mtx->lock, ngx_pid, 0)) {
+ ngx_shmtx_wakeup(mtx);
+ }
+}
- old = *mtx->lock;
- wait = old & 0x7fffffff;
- val = wait ? wait - 1 : 0;
- if (ngx_atomic_cmp_set(mtx->lock, old, val)) {
- break;
- }
+ngx_uint_t
+ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid)
+{
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
+ "shmtx forced unlock");
+
+ if (ngx_atomic_cmp_set(mtx->lock, pid, 0)) {
+ ngx_shmtx_wakeup(mtx);
+ return 1;
}
+ return 0;
+}
+
+
+static void
+ngx_shmtx_wakeup(ngx_shmtx_t *mtx)
+{
#if (NGX_HAVE_POSIX_SEM)
+ ngx_atomic_uint_t wait;
- if (wait == 0 || !mtx->semaphore) {
+ if (!mtx->semaphore) {
return;
}
+ for ( ;; ) {
+
+ wait = *mtx->wait;
+
+ if (wait == 0) {
+ return;
+ }
+
+ if (ngx_atomic_cmp_set(mtx->wait, wait, wait - 1)) {
+ break;
+ }
+ }
+
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "shmtx wake %XA", old);
+ "shmtx wake %uA", wait);
if (sem_post(&mtx->sem) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
@@ -180,7 +198,7 @@ ngx_shmtx_unlock(ngx_shmtx_t *mtx)
ngx_int_t
-ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name)
+ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
{
if (mtx->name) {
@@ -280,4 +298,11 @@ ngx_shmtx_unlock(ngx_shmtx_t *mtx)
ngx_log_abort(err, ngx_unlock_fd_n " %s failed", mtx->name);
}
+
+ngx_uint_t
+ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid)
+{
+ return 0;
+}
+
#endif
diff --git a/src/core/ngx_shmtx.h b/src/core/ngx_shmtx.h
index 714f73aa6..3ee7d3a79 100644
--- a/src/core/ngx_shmtx.h
+++ b/src/core/ngx_shmtx.h
@@ -13,9 +13,18 @@
typedef struct {
+ ngx_atomic_t lock;
+#if (NGX_HAVE_POSIX_SEM)
+ ngx_atomic_t wait;
+#endif
+} ngx_shmtx_sh_t;
+
+
+typedef struct {
#if (NGX_HAVE_ATOMIC_OPS)
ngx_atomic_t *lock;
#if (NGX_HAVE_POSIX_SEM)
+ ngx_atomic_t *wait;
ngx_uint_t semaphore;
sem_t sem;
#endif
@@ -27,11 +36,13 @@ typedef struct {
} ngx_shmtx_t;
-ngx_int_t ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name);
+ngx_int_t ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr,
+ u_char *name);
void ngx_shmtx_destory(ngx_shmtx_t *mtx);
ngx_uint_t ngx_shmtx_trylock(ngx_shmtx_t *mtx);
void ngx_shmtx_lock(ngx_shmtx_t *mtx);
void ngx_shmtx_unlock(ngx_shmtx_t *mtx);
+ngx_uint_t ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid);
#endif /* _NGX_SHMTX_H_INCLUDED_ */
diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h
index 291e1b51e..202fd9380 100644
--- a/src/core/ngx_slab.h
+++ b/src/core/ngx_slab.h
@@ -22,7 +22,7 @@ struct ngx_slab_page_s {
typedef struct {
- ngx_atomic_t lock;
+ ngx_shmtx_sh_t lock;
size_t min_size;
size_t min_shift;
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 29f8e0d67..f5e1d4bf3 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1657,6 +1657,10 @@ ngx_escape_html(u_char *dst, u_char *src, size_t size)
len += sizeof("&amp;") - 2;
break;
+ case '"':
+ len += sizeof("&quot;") - 2;
+ break;
+
default:
break;
}
@@ -1684,6 +1688,11 @@ ngx_escape_html(u_char *dst, u_char *src, size_t size)
*dst++ = ';';
break;
+ case '"':
+ *dst++ = '&'; *dst++ = 'q'; *dst++ = 'u'; *dst++ = 'o';
+ *dst++ = 't'; *dst++ = ';';
+ break;
+
default:
*dst++ = ch;
break;
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 31c10c6dc..4f9c5118e 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -681,6 +681,18 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
wev = c->write;
+ if (c->fd == -1 || wev->instance != instance) {
+
+ /*
+ * the stale event from a file descriptor
+ * that was just closed in this iteration
+ */
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+ "epoll: stale event %p", c);
+ continue;
+ }
+
if ((revents & EPOLLOUT) && wev->active) {
if (flags & NGX_POST_THREAD_EVENTS) {
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 8a472ffe8..7d297d96b 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -521,7 +521,8 @@ ngx_event_module_init(ngx_cycle_t *cycle)
ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
ngx_accept_mutex.spin = (ngx_uint_t) -1;
- if (ngx_shmtx_create(&ngx_accept_mutex, shared, cycle->lock_file.data)
+ if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared,
+ cycle->lock_file.data)
!= NGX_OK)
{
return NGX_ERROR;
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 270d969db..30af834ab 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -23,7 +23,7 @@ static ngx_command_t ngx_http_flv_commands[] = {
};
-static u_char ngx_flv_header[] = "FLV\x1\x1\0\0\0\x9\0\0\0\x9";
+static u_char ngx_flv_header[] = "FLV\x1\x5\0\0\0\x9\0\0\0\0";
static ngx_http_module_t ngx_http_flv_module_ctx = {
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index c846c5fea..754473355 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -145,6 +145,7 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|| r != r->main
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_NO_CONTENT
+ && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
&& r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
&& r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY
&& r->headers_out.status != NGX_HTTP_NOT_MODIFIED))
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index 31f26ec50..66ed34541 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -115,7 +115,7 @@ static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf);
static ngx_command_t ngx_http_image_filter_commands[] = {
{ ngx_string("image_filter"),
- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE13|NGX_CONF_TAKE2,
+ NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ngx_http_image_filter,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -1262,7 +1262,11 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
} else if (cf->args->nelts == 3) {
if (ngx_strcmp(value[i].data, "rotate") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_ROTATE;
+ if (imcf->filter != NGX_HTTP_IMAGE_RESIZE
+ && imcf->filter != NGX_HTTP_IMAGE_CROP)
+ {
+ imcf->filter = NGX_HTTP_IMAGE_ROTATE;
+ }
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
@@ -1405,7 +1409,7 @@ ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd,
if (n <= 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[1]);
+ "invalid value \"%V\"", &value[1]);
return NGX_CONF_ERROR;
}
@@ -1452,7 +1456,7 @@ ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd,
if (n < 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[1]);
+ "invalid value \"%V\"", &value[1]);
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index a4a47ee8e..3c9f88cfc 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -1899,7 +1899,7 @@ ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"count:%uD, duration:%uD", count, duration);
- if (start_time < count * duration) {
+ if (start_time < (uint64_t) count * duration) {
start_sample += (ngx_uint_t) (start_time / duration);
count -= start_sample;
ngx_mp4_set_32value(entry->count, count);
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 1feac713b..168f497ce 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -558,8 +558,10 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
while (*(uintptr_t *) le.ip) {
lcode = *(ngx_http_script_len_code_pt *) le.ip;
- len += lcode(&le) + 1;
+ len += lcode(&le);
}
+ len++;
+
le.ip += sizeof(uintptr_t);
}
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 8a77ac601..001acc792 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 = '1.1.8';
+our $VERSION = '1.1.9';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index ba5191069..96be42369 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -3267,12 +3267,12 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
* clcf->auto_redirect = 0;
* clcf->alias = 0;
* clcf->gzip_proxied = 0;
+ * clcf->keepalive_disable = 0;
*/
clcf->client_max_body_size = NGX_CONF_UNSET;
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
- clcf->keepalive_disable = NGX_CONF_UNSET_UINT;
clcf->satisfy = NGX_CONF_UNSET_UINT;
clcf->if_modified_since = NGX_CONF_UNSET_UINT;
clcf->max_ranges = NGX_CONF_UNSET_UINT;
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index a7a4c6ee6..28842cf9d 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -110,7 +110,10 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
sw_schema,
sw_schema_slash,
sw_schema_slash_slash,
+ sw_host_start,
sw_host,
+ sw_host_end,
+ sw_host_ip_literal,
sw_port,
sw_host_http_09,
sw_after_slash_in_uri,
@@ -323,14 +326,26 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
case sw_schema_slash_slash:
switch (ch) {
case '/':
- r->host_start = p + 1;
- state = sw_host;
+ state = sw_host_start;
break;
default:
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
+ case sw_host_start:
+
+ r->host_start = p;
+
+ if (ch == '[') {
+ state = sw_host_ip_literal;
+ break;
+ }
+
+ state = sw_host;
+
+ /* fall through */
+
case sw_host:
c = (u_char) (ch | 0x20);
@@ -342,6 +357,10 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
+ /* fall through */
+
+ case sw_host_end:
+
r->host_end = p;
switch (ch) {
@@ -366,6 +385,47 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
}
break;
+ case sw_host_ip_literal:
+
+ if (ch >= '0' && ch <= '9') {
+ break;
+ }
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'z') {
+ break;
+ }
+
+ switch (ch) {
+ case ':':
+ break;
+ case ']':
+ state = sw_host_end;
+ break;
+ case '-':
+ case '.':
+ case '_':
+ case '~':
+ /* unreserved */
+ break;
+ case '!':
+ case '$':
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case ';':
+ case '=':
+ /* sub-delims */
+ break;
+ default:
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+ }
+ break;
+
case sw_port:
if (ch >= '0' && ch <= '9') {
break;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index c0d56ecaa..fbb7915b3 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -671,25 +671,27 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
- SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
+ if (sscf->ssl.ctx) {
+ SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
- /*
- * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
- * adjust other things we care about
- */
+ /*
+ * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
+ * adjust other things we care about
+ */
- SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
- SSL_CTX_get_verify_callback(sscf->ssl.ctx));
+ SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
+ SSL_CTX_get_verify_callback(sscf->ssl.ctx));
- SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
+ SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
#ifdef SSL_CTRL_CLEAR_OPTIONS
- /* only in 0.9.8m+ */
- SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
- ~SSL_CTX_get_options(sscf->ssl.ctx));
+ /* only in 0.9.8m+ */
+ SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
+ ~SSL_CTX_get_options(sscf->ssl.ctx));
#endif
- SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
+ SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
+ }
return SSL_TLSEXT_ERR_OK;
}
@@ -1672,56 +1674,85 @@ static ssize_t
ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
ngx_uint_t alloc)
{
- u_char *h, ch;
- size_t i, last;
- ngx_uint_t dot;
+ u_char *h, ch;
+ size_t i, dot_pos, host_len;
+
+ enum {
+ sw_usual = 0,
+ sw_literal,
+ sw_rest
+ } state;
+
+ dot_pos = len;
+ host_len = len;
- last = len;
h = *host;
- dot = 0;
+
+ state = sw_usual;
for (i = 0; i < len; i++) {
ch = h[i];
- if (ch == '.') {
- if (dot) {
+ switch (ch) {
+
+ case '.':
+ if (dot_pos == i - 1) {
return 0;
}
+ dot_pos = i;
+ break;
- dot = 1;
- continue;
- }
+ case ':':
+ if (state == sw_usual) {
+ host_len = i;
+ state = sw_rest;
+ }
+ break;
- dot = 0;
+ case '[':
+ if (i == 0) {
+ state = sw_literal;
+ }
+ break;
- if (ch == ':') {
- last = i;
- continue;
- }
+ case ']':
+ if (state == sw_literal) {
+ host_len = i + 1;
+ state = sw_rest;
+ }
+ break;
- if (ngx_path_separator(ch) || ch == '\0') {
+ case '\0':
return 0;
- }
- if (ch >= 'A' || ch < 'Z') {
- alloc = 1;
+ default:
+
+ if (ngx_path_separator(ch)) {
+ return 0;
+ }
+
+ if (ch >= 'A' && ch <= 'Z') {
+ alloc = 1;
+ }
+
+ break;
}
}
- if (dot) {
- last--;
+ if (dot_pos == host_len - 1) {
+ host_len--;
}
if (alloc) {
- *host = ngx_pnalloc(r->pool, last) ;
+ *host = ngx_pnalloc(r->pool, host_len);
if (*host == NULL) {
return -1;
}
- ngx_strlow(*host, h, last);
+ ngx_strlow(*host, h, host_len);
}
- return last;
+ return host_len;
}
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 3645d3bd4..25b6de2e8 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2696,9 +2696,17 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
} else if (p->upstream_eof) {
- /* TODO: check length & update cache */
+ tf = u->pipe->temp_file;
- ngx_http_file_cache_update(r, u->pipe->temp_file);
+ if (u->headers_in.content_length_n == -1
+ || u->headers_in.content_length_n
+ == tf->offset - (off_t) r->cache->body_start)
+ {
+ ngx_http_file_cache_update(r, tf);
+
+ } else {
+ ngx_http_file_cache_free(r->cache, tf);
+ }
} else if (p->upstream_error) {
ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index ad26d2752..196323727 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -464,7 +464,7 @@ ngx_unlock_fd(ngx_fd_t fd)
}
-#if (NGX_HAVE_POSIX_FADVISE)
+#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
ngx_int_t
ngx_read_ahead(ngx_fd_t fd, size_t n)
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index 08069c4b6..3eba6ce23 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -22,6 +22,7 @@ typedef struct {
static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
static void ngx_signal_handler(int signo);
static void ngx_process_get_status(void);
+static void ngx_unlock_mutexes(ngx_pid_t pid);
int ngx_argc;
@@ -497,17 +498,6 @@ ngx_process_get_status(void)
}
- if (ngx_accept_mutex_ptr) {
-
- /*
- * unlock the accept mutex if the abnormally exited process
- * held it
- */
-
- ngx_atomic_cmp_set(ngx_accept_mutex_ptr, pid, 0);
- }
-
-
one = 1;
process = "unknown process";
@@ -545,6 +535,55 @@ ngx_process_get_status(void)
process, pid, WEXITSTATUS(status));
ngx_processes[i].respawn = 0;
}
+
+ ngx_unlock_mutexes(pid);
+ }
+}
+
+
+static void
+ngx_unlock_mutexes(ngx_pid_t pid)
+{
+ ngx_uint_t i;
+ ngx_shm_zone_t *shm_zone;
+ ngx_list_part_t *part;
+ ngx_slab_pool_t *sp;
+
+ /*
+ * unlock the accept mutex if the abnormally exited process
+ * held it
+ */
+
+ if (ngx_accept_mutex_ptr) {
+ (void) ngx_shmtx_force_unlock(&ngx_accept_mutex, pid);
+ }
+
+ /*
+ * unlock shared memory mutexes if held by the abnormally exited
+ * process
+ */
+
+ part = (ngx_list_part_t *) &ngx_cycle->shared_memory.part;
+ shm_zone = part->elts;
+
+ for (i = 0; /* void */ ; i++) {
+
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+ part = part->next;
+ shm_zone = part->elts;
+ i = 0;
+ }
+
+ sp = (ngx_slab_pool_t *) shm_zone[i].shm.addr;
+
+ if (ngx_shmtx_force_unlock(&sp->mutex, pid)) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "shared memory zone \"%V\" was locked by %P",
+ &shm_zone[i].shm.name, pid);
+ }
}
}