summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-01-15 17:49:33 +0000
committerJonathan Kolb <jon@b0g.us>2007-01-15 17:49:33 +0000
commita234c0f48129854613e4fd0029876150a1ea2956 (patch)
treebeec90e2c13934a6c308ce65cec1997e12cb0a31
parent426223037017c6000f42bc041342171d1f666c6c (diff)
downloadnginx-0.5.7.tar.gz
Changes with nginx 0.5.7 15 Jan 2007v0.5.7
*) Feature: the ssl_session_cache storage optimization. *) Bugfixes in the "ssl_session_cache" and "limit_zone" directives. *) Bugfix: the segmentation fault was occurred on start or while reconfiguration if the "ssl_session_cache" or "limit_zone" directives were used on 64-bit platforms. *) Bugfix: a segmentation fault occurred if the "add_before_body" or "add_after_body" directives were used and there was no "Content-Type" header line in response. *) Bugfix: the OpenSSL library was always built with the threads support. Thanks to Den Ivanov. *) Bugfix: the PCRE-6.5+ library and the icc compiler compatibility.
-rw-r--r--CHANGES21
-rw-r--r--CHANGES.ru21
-rw-r--r--auto/cc/gcc2
-rw-r--r--auto/lib/openssl/make7
-rw-r--r--auto/lib/pcre/conf24
-rw-r--r--conf/mime.types1
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_crc32.c6
-rw-r--r--src/core/ngx_cycle.c5
-rw-r--r--src/core/ngx_rbtree.c6
-rw-r--r--src/core/ngx_rbtree.h9
-rw-r--r--src/core/ngx_shmtx.h6
-rw-r--r--src/core/ngx_slab.c19
-rw-r--r--src/core/ngx_string.c25
-rw-r--r--src/core/ngx_string.h1
-rw-r--r--src/event/modules/ngx_aio_module.c58
-rw-r--r--src/event/modules/ngx_aio_module.h20
-rw-r--r--src/event/ngx_event_openssl.c226
-rw-r--r--src/event/ngx_event_openssl.h28
-rw-r--r--src/event/ngx_event_pipe.c6
-rw-r--r--src/event/ngx_event_timer.c5
-rw-r--r--src/http/modules/ngx_http_addition_filter_module.c5
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c6
-rw-r--r--src/http/modules/ngx_http_limit_zone_module.c103
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_upstream_ip_hash_module.c16
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c2
-rw-r--r--src/http/ngx_http_core_module.c3
-rw-r--r--src/http/ngx_http_upstream.c2
-rw-r--r--src/imap/ngx_imap_handler.c2
-rw-r--r--src/os/unix/ngx_gcc_atomic_amd64.h14
-rw-r--r--src/os/unix/ngx_gcc_atomic_x86.h27
33 files changed, 449 insertions, 233 deletions
diff --git a/CHANGES b/CHANGES
index 564bbc5f5..f8cdd5a55 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,25 @@
+Changes with nginx 0.5.7 15 Jan 2007
+
+ *) Feature: the ssl_session_cache storage optimization.
+
+ *) Bugfixes in the "ssl_session_cache" and "limit_zone" directives.
+
+ *) Bugfix: the segmentation fault was occurred on start or while
+ reconfiguration if the "ssl_session_cache" or "limit_zone"
+ directives were used on 64-bit platforms.
+
+ *) Bugfix: a segmentation fault occurred if the "add_before_body" or
+ "add_after_body" directives were used and there was no
+ "Content-Type" header line in response.
+
+ *) Bugfix: the OpenSSL library was always built with the threads
+ support.
+ Thanks to Den Ivanov.
+
+ *) Bugfix: the PCRE-6.5+ library and the icc compiler compatibility.
+
+
Changes with nginx 0.5.6 09 Jan 2007
*) Change: now the ngx_http_index_module ignores all methods except the
diff --git a/CHANGES.ru b/CHANGES.ru
index 18e7b842d..519ea9520 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,25 @@
+Изменения в nginx 0.5.7 15.01.2007
+
+ *) Добавление: оптимизация использования памяти в ssl_session_cache.
+
+ *) Исправление ошибок в директивах ssl_session_cache и limit_zone.
+
+ *) Исправление: на старте или во время переконфигурации происходил
+ segmentation fault, если директивы ssl_session_cache или limit_zone
+ использовались на 64-битных платформах.
+
+ *) Исправление: при использовании директив add_before_body или
+ add_after_body происходил segmentation fault, если в заголовке
+ ответа нет строки "Content-Type".
+
+ *) Исправление: библиотека OpenSSL всегда собирался с поддержкой
+ потоков.
+ Спасибо Дену Иванову.
+
+ *) Исправление: совместимость библиотеки PCRE-6.5+ и компилятора icc.
+
+
Изменения в nginx 0.5.6 09.01.2007
*) Изменение: теперь модуль ngx_http_index_module игнорирует все
diff --git a/auto/cc/gcc b/auto/cc/gcc
index e377fced8..8ac76fb98 100644
--- a/auto/cc/gcc
+++ b/auto/cc/gcc
@@ -147,7 +147,7 @@ fi
# warnings
# -W requires at least -O
-CFLAGS="$CFLAGS ${NGX_GCC_OPT:-O} -W"
+CFLAGS="$CFLAGS ${NGX_GCC_OPT:--O} -W"
CFLAGS="$CFLAGS -Wall -Wpointer-arith"
#CFLAGS="$CFLAGS -Wconversion"
diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make
index 31e15dc4d..7da0d8dc1 100644
--- a/auto/lib/openssl/make
+++ b/auto/lib/openssl/make
@@ -8,9 +8,10 @@ else
NGX_OPENSSL_CONFIG="./config"
fi
-if test -n "$USE_THREADS"; then
- NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG threads"
-fi
+case $USE_THREADS in
+ NO) NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG no-threads" ;;
+ *) NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG threads" ;;
+esac
case "$NGX_PLATFORM" in
*)
diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
index 045e6c855..a1143814d 100644
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -25,14 +25,24 @@ if [ $PCRE != NONE ]; then
echo $ngx_n "checking for PCRE library ...$ngx_c"
- ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
- | sed -e 's/^.*=\(.*\)$/\1/'`
+ if [ -e $PCRE/pcre.h ]; then
+ ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
+ | sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
+
+ else
+ ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
+ | sed -e 's/^.*=\(.*\)$/\1/'`
+ fi
echo " $ngx_pcre_ver major version found"
# to allow -ipo optimization we link with the *.o but not library
case "$ngx_pcre_ver" in
+ 4|5)
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
+ ;;
+
6)
CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
@@ -44,8 +54,16 @@ if [ $PCRE != NONE ]; then
;;
*)
- CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
+ CORE_LIBS="$CORE_LIBS $PCRE/pcre_newline.o"
;;
+
esac
;;
diff --git a/conf/mime.types b/conf/mime.types
index 904f255bb..f1714338b 100644
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -6,6 +6,7 @@ types {
image/gif gif;
image/jpeg jpeg jpg;
application/x-javascript js;
+ application/atom+xml atom;
text/mathml mml;
text/plain txt;
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 0e97499f6..523bcb7fa 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.5.6"
+#define NGINX_VERSION "0.5.7"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_crc32.c b/src/core/ngx_crc32.c
index 4ad8ff3a4..64b02ac7a 100644
--- a/src/core/ngx_crc32.c
+++ b/src/core/ngx_crc32.c
@@ -13,11 +13,11 @@
* described at http://www.w3.org/TR/PNG/
*
* The 256 element lookup table takes 1024 bytes, and it may be completely
- * cached after processing about 30-60 bytes. So for short messages
+ * cached after processing about 30-60 bytes of data. So for short data
* we use the 16 element lookup table that takes only 64 bytes and align it
* to CPU cache line size. Of course, the small table adds code inside
- * CRC32 cycle, but cache misses overhead is bigger than overhead of
- * the additional code. For example, ngx_crc32_short() of 16 byte message
+ * CRC32 loop, but the cache misses overhead is bigger than overhead of
+ * the additional code. For example, ngx_crc32_short() of 16 bytes of data
* takes half as much CPU clocks than ngx_crc32_long().
*/
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index eac6a5c48..89109b389 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -373,6 +373,11 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
goto failed;
}
+ if (shm_zone[i].init == NULL) {
+ /* unused shared zone */
+ continue;
+ }
+
shm_zone[i].shm.log = cycle->log;
opart = &old_cycle->shared_memory.part;
diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c
index a9d630520..0a5753cdf 100644
--- a/src/core/ngx_rbtree.c
+++ b/src/core/ngx_rbtree.c
@@ -13,12 +13,6 @@
* the "Introduction to Algorithms" by Cormen, Leiserson and Rivest.
*/
-#define ngx_rbt_red(node) ((node)->color = 1)
-#define ngx_rbt_black(node) ((node)->color = 0)
-#define ngx_rbt_is_red(node) ((node)->color)
-#define ngx_rbt_is_black(node) (!ngx_rbt_is_red(node))
-#define ngx_rbt_copy_color(n1, n2) (n1->color = n2->color)
-
static ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_node_t **root,
ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node);
diff --git a/src/core/ngx_rbtree.h b/src/core/ngx_rbtree.h
index 16524ffc8..d7250f8ac 100644
--- a/src/core/ngx_rbtree.h
+++ b/src/core/ngx_rbtree.h
@@ -50,9 +50,16 @@ void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
+#define ngx_rbt_red(node) ((node)->color = 1)
+#define ngx_rbt_black(node) ((node)->color = 0)
+#define ngx_rbt_is_red(node) ((node)->color)
+#define ngx_rbt_is_black(node) (!ngx_rbt_is_red(node))
+#define ngx_rbt_copy_color(n1, n2) (n1->color = n2->color)
+
+
/* a sentinel must be black */
-#define ngx_rbtree_sentinel_init(node) node->color = 0
+#define ngx_rbtree_sentinel_init(node) ngx_rbt_black(node)
static ngx_inline ngx_rbtree_node_t *
diff --git a/src/core/ngx_shmtx.h b/src/core/ngx_shmtx.h
index 1361125de..7d4c09e3d 100644
--- a/src/core/ngx_shmtx.h
+++ b/src/core/ngx_shmtx.h
@@ -30,11 +30,7 @@ ngx_int_t ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name);
static ngx_inline ngx_uint_t
ngx_shmtx_trylock(ngx_shmtx_t *mtx)
{
- if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
- return 1;
- }
-
- return 0;
+ return (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid));
}
#define ngx_shmtx_lock(mtx) ngx_spinlock((mtx)->lock, ngx_pid, 1024)
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
index b09d2e44b..daf563913 100644
--- a/src/core/ngx_slab.c
+++ b/src/core/ngx_slab.c
@@ -128,7 +128,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
pool->pages->prev = (uintptr_t) &pool->free;
pool->start = (u_char *)
- ngx_align((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
+ ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
ngx_pagesize);
m = pages - (pool->end - pool->start) / ngx_pagesize;
@@ -295,7 +295,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
n = 1 << n;
- n = (1 << n) - 1;
+ n = ((uintptr_t) 1 << n) - 1;
mask = n << NGX_SLAB_MAP_SHIFT;
do {
@@ -421,8 +421,8 @@ void
ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
{
size_t size;
- uintptr_t slab, *bitmap;
- ngx_uint_t n, m, type, slot, shift, map;
+ uintptr_t slab, m, *bitmap;
+ ngx_uint_t n, type, slot, shift, map;
ngx_slab_page_t *slots, *page;
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
@@ -450,7 +450,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
}
n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;
- m = 1 << (n & (sizeof(uintptr_t) * 8 - 1));
+ m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));
n /= (sizeof(uintptr_t) * 8);
bitmap = (uintptr_t *) ((uintptr_t) p & ~(ngx_pagesize - 1));
@@ -476,7 +476,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
n = 1;
}
- if (bitmap[0] & ~((1 << n) - 1)) {
+ if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {
goto done;
}
@@ -497,7 +497,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
case NGX_SLAB_EXACT:
- m = 1 << (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);
+ m = (uintptr_t) 1 <<
+ (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);
size = ngx_slab_exact_size;
if ((uintptr_t) p & (size - 1)) {
@@ -539,8 +540,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
goto wrong_chunk;
}
- m = 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)
- + NGX_SLAB_MAP_SHIFT);
+ m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)
+ + NGX_SLAB_MAP_SHIFT);
if (slab & m) {
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index ad2c9d8c8..e12edbd74 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -487,6 +487,31 @@ ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n)
ngx_int_t
+ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2)
+{
+ size_t n;
+ ngx_int_t m, z;
+
+ if (n1 <= n2) {
+ n = n1;
+ z = -1;
+
+ } else {
+ n = n2;
+ z = 1;
+ }
+
+ m = ngx_memcmp(s1, s2, n);
+
+ if (m || n1 == n2) {
+ return m;
+ }
+
+ return z;
+}
+
+
+ngx_int_t
ngx_atoi(u_char *line, size_t n)
{
ngx_int_t value;
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 10f87ae93..670063915 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -130,6 +130,7 @@ u_char *ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args);
ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n);
ngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n);
+ngx_int_t ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2);
ngx_int_t ngx_atoi(u_char *line, size_t n);
ssize_t ngx_atosz(u_char *line, size_t n);
diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c
index fb3c8c85e..1022643e8 100644
--- a/src/event/modules/ngx_aio_module.c
+++ b/src/event/modules/ngx_aio_module.c
@@ -166,61 +166,3 @@ ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
}
#endif /* NGX_HAVE_KQUEUE */
-
-
-#if 0
-
-/* 1 */
-int ngx_posix_aio_process_events(ngx_log_t *log)
-{
- listen via SIGIO;
- aio_* via SIGxxx;
-
- sigsuspend()/sigwaitinfo()/sigtimedwait();
-}
-
-/* 2 */
-int ngx_posix_aio_process_events(ngx_log_t *log)
-{
- unmask signal
-
- listen via SIGIO;
-
- /* BUG: SIGIO can be delivered before aio_*() */
-
- aio_suspend()/aiowait()/aio_waitcomplete() with timeout
-
- mask signal
-
- if (ngx_socket_errno == NGX_EINTR)
- look listen
- select()/accept() nb listen sockets
- else
- aio
-}
-
-/* 3 */
-int ngx_posix_aio_process_events(ngx_log_t *log)
-{
-#if 0
- unmask signal
-
- /* BUG: AIO signal can be delivered before select() */
-
- select(listen);
-
- mask signal
-#endif
-
- pselect(listen, mask);
-
- if (ngx_socket_errno == NGX_EINTR)
- look ready array
-}
-
-void aio_sig_handler(int signo, siginfo_t *siginfo, void *context)
-{
- push siginfo->si_value.sival_ptr
-}
-
-#endif
diff --git a/src/event/modules/ngx_aio_module.h b/src/event/modules/ngx_aio_module.h
deleted file mode 100644
index 185a9dfb6..000000000
--- a/src/event/modules/ngx_aio_module.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#ifndef _NGX_AIO_MODULE_H_INCLUDED_
-#define _NGX_AIO_MODULE_H_INCLUDED_
-
-
-#include <ngx_types.h>
-#include <ngx_log.h>
-#include <ngx_event.h>
-
-
-int ngx_aio_init(int max_connections, ngx_log_t *log);
-int ngx_aio_process_events(ngx_log_t *log);
-
-
-#endif /* _NGX_AIO_MODULE_H_INCLUDED_ */
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index dff23ae31..71d014ff0 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -32,6 +32,8 @@ static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
ngx_slab_pool_t *shpool, ngx_uint_t n);
+static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf);
@@ -1160,10 +1162,10 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
}
-
- SSL_CTX_set_timeout(ssl->ctx, timeout);
}
+ SSL_CTX_set_timeout(ssl->ctx, timeout);
+
if (shm_zone) {
shm_zone->init = ngx_ssl_session_cache_init;
@@ -1223,7 +1225,7 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
cache->session_rbtree->root = sentinel;
cache->session_rbtree->sentinel = sentinel;
- cache->session_rbtree->insert = ngx_rbtree_insert_value;
+ cache->session_rbtree->insert = ngx_ssl_session_rbtree_insert_value;
shm_zone->data = cache;
@@ -1232,6 +1234,18 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
/*
+ * The length of the session id is 16 bytes for SSLv2 sessions and
+ * between 1 and 32 bytes for SSLv3/TLSv1, typically 32 bytes.
+ * It seems that the typical length of the external ASN1 representation
+ * of a session is 118 or 119 bytes for SSLv3/TSLv1.
+ *
+ * Thus on 32-bit platforms we allocate separately an rbtree node,
+ * a session id, and an ASN1 representation, they take accordingly
+ * 64, 32, and 128 bytes.
+ *
+ * On 64-bit platforms we allocate separately an rbtree node + session_id,
+ * and an ASN1 representation, they take accordingly 128 and 128 bytes.
+ *
* OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
* so they are outside the code locked by shared pool mutex
*/
@@ -1240,7 +1254,7 @@ static int
ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
{
int len;
- u_char *p, *id;
+ u_char *p, *id, *cached_sess;
uint32_t hash;
SSL_CTX *ssl_ctx;
ngx_time_t *tp;
@@ -1248,7 +1262,6 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
ngx_connection_t *c;
ngx_slab_pool_t *shpool;
ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_cached_sess_t *cached_sess;
ngx_ssl_session_cache_t *cache;
u_char buf[NGX_SSL_MAX_SESSION_SIZE];
@@ -1276,8 +1289,7 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
/* drop one or two expired sessions */
ngx_ssl_expire_sessions(cache, shpool, 1);
- cached_sess = ngx_slab_alloc_locked(shpool,
- offsetof(ngx_ssl_cached_sess_t, asn1) + len);
+ cached_sess = ngx_slab_alloc_locked(shpool, len);
if (cached_sess == NULL) {
@@ -1285,26 +1297,33 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
ngx_ssl_expire_sessions(cache, shpool, 0);
- cached_sess = ngx_slab_alloc_locked(shpool,
- offsetof(ngx_ssl_cached_sess_t, asn1) + len);
+ cached_sess = ngx_slab_alloc_locked(shpool, len);
if (cached_sess == NULL) {
- id = NULL;
+ sess_id = NULL;
goto failed;
}
}
- id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
- if (id == NULL) {
+ sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
+ if (sess_id == NULL) {
goto failed;
}
- sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
- if (sess_id == NULL) {
+#if (NGX_PTR_SIZE == 8)
+
+ id = sess_id->sess_id;
+
+#else
+
+ id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
+ if (id == NULL) {
goto failed;
}
- ngx_memcpy(&cached_sess->asn1[0], buf, len);
+#endif
+
+ ngx_memcpy(cached_sess, buf, len);
ngx_memcpy(id, sess->session_id, sess->session_id_length);
@@ -1314,21 +1333,20 @@ 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;
- tp = ngx_timeofday();
+ sess_id->expire = tp->sec + SSL_CTX_get_timeout(ssl_ctx);
- cached_sess->expire = tp->sec + SSL_CTX_get_timeout(ssl_ctx);
- cached_sess->sess_id = sess_id;
-
- cached_sess->next = cache->session_cache_head.next;
- cached_sess->next->prev = cached_sess;
- cached_sess->prev = &cache->session_cache_head;
- cache->session_cache_head.next = cached_sess;
+ 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_rbtree_insert(cache->session_rbtree, &sess_id->node);
@@ -1342,8 +1360,8 @@ failed:
ngx_slab_free_locked(shpool, cached_sess);
}
- if (id) {
- ngx_slab_free_locked(shpool, id);
+ if (sess_id) {
+ ngx_slab_free_locked(shpool, sess_id);
}
ngx_shmtx_unlock(&shpool->mutex);
@@ -1364,6 +1382,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
#endif
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;
@@ -1371,13 +1390,12 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
ngx_rbtree_node_t *node, *sentinel;
ngx_ssl_session_t *sess;
ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_cached_sess_t *cached_sess;
ngx_ssl_session_cache_t *cache;
u_char buf[NGX_SSL_MAX_SESSION_SIZE];
c = ngx_ssl_get_connection(ssl_conn);
- hash = ngx_crc32_short(id, len);
+ hash = ngx_crc32_short(id, (size_t) len);
*copy = 0;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
@@ -1413,17 +1431,19 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
continue;
}
- if (hash == node->key && (u_char) len == node->data) {
- sess_id = (ngx_ssl_sess_id_t *) node;
+ /* hash == node->key */
- if (ngx_strncmp(id, sess_id->id, len) == 0) {
+ do {
+ sess_id = (ngx_ssl_sess_id_t *) node;
- cached_sess = sess_id->session;
+ rc = ngx_memn2cmp(id, sess_id->id,
+ (size_t) len, (size_t) node->data);
+ if (rc == 0) {
tp = ngx_timeofday();
- if (cached_sess->expire > tp->sec) {
- ngx_memcpy(buf, &cached_sess->asn1[0], sess_id->len);
+ if (sess_id->expire > tp->sec) {
+ ngx_memcpy(buf, sess_id->session, sess_id->len);
ngx_shmtx_unlock(&shpool->mutex);
@@ -1433,24 +1453,31 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
return sess;
}
- cached_sess->next->prev = cached_sess->prev;
- cached_sess->prev->next = cached_sess->next;
+ sess_id->next->prev = sess_id->prev;
+ sess_id->prev->next = sess_id->next;
ngx_rbtree_delete(cache->session_rbtree, node);
- ngx_slab_free_locked(shpool, cached_sess);
+ ngx_slab_free_locked(shpool, sess_id->session);
+#if (NGX_PTR_SIZE == 4)
ngx_slab_free_locked(shpool, sess_id->id);
+#endif
ngx_slab_free_locked(shpool, sess_id);
sess = NULL;
- break;
+ goto done;
}
- }
- node = node->right;
+ node = (rc < 0) ? node->left : node->right;
+
+ } while (node != sentinel && hash == node->key);
+
+ break;
}
+done:
+
ngx_shmtx_unlock(&shpool->mutex);
return sess;
@@ -1460,13 +1487,14 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
static void
ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
{
- u_char *id, len;
+ size_t len;
+ u_char *id;
uint32_t hash;
+ ngx_int_t rc;
ngx_shm_zone_t *shm_zone;
ngx_slab_pool_t *shpool;
ngx_rbtree_node_t *node, *sentinel;
ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_cached_sess_t *cached_sess;
ngx_ssl_session_cache_t *cache;
shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);
@@ -1474,12 +1502,12 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
cache = shm_zone->data;
id = sess->session_id;
- len = (u_char) sess->session_id_length;
+ len = (size_t) sess->session_id_length;
- hash = ngx_crc32_short(id, (size_t) len);
+ hash = ngx_crc32_short(id, len);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
- "http ssl remove session: %08XD:%d", hash, len);
+ "http ssl remove session: %08XD:%uz", hash, len);
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
@@ -1500,29 +1528,37 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
continue;
}
- if (hash == node->key && len == node->data) {
- sess_id = (ngx_ssl_sess_id_t *) node;
+ /* hash == node->key */
- if (ngx_strncmp(id, sess_id->id, (size_t) len) == 0) {
+ do {
+ sess_id = (ngx_ssl_sess_id_t *) node;
- cached_sess = sess_id->session;
+ rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
- cached_sess->next->prev = cached_sess->prev;
- cached_sess->prev->next = cached_sess->next;
+ 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_slab_free_locked(shpool, cached_sess);
+ ngx_slab_free_locked(shpool, sess_id->session);
+#if (NGX_PTR_SIZE == 4)
ngx_slab_free_locked(shpool, sess_id->id);
+#endif
ngx_slab_free_locked(shpool, sess_id);
- break;
+ goto done;
}
- }
- node = node->right;
+ node = (rc < 0) ? node->left : node->right;
+
+ } while (node != sentinel && hash == node->key);
+
+ break;
}
+done:
+
ngx_shmtx_unlock(&shpool->mutex);
}
@@ -1531,41 +1567,101 @@ 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;
- ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_cached_sess_t *sess;
+ ngx_time_t *tp;
+ ngx_ssl_sess_id_t *sess_id;
tp = ngx_timeofday();
while (n < 3) {
- sess = cache->session_cache_tail.prev;
+ sess_id = cache->session_cache_tail.prev;
- if (sess == &cache->session_cache_head) {
+ if (sess_id == &cache->session_cache_head) {
return;
}
- if (n++ != 0 && sess->expire > tp->sec) {
+ if (n++ != 0 && sess_id->expire > tp->sec) {
break;
}
- sess->next->prev = sess->prev;
- sess->prev->next = sess->next;
-
- sess_id = sess->sess_id;
+ sess_id->next->prev = sess_id->prev;
+ sess_id->prev->next = sess_id->next;
ngx_rbtree_delete(cache->session_rbtree, &sess_id->node);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
"expire session: %08Xi", sess_id->node.key);
- ngx_slab_free_locked(shpool, sess);
+ ngx_slab_free_locked(shpool, sess_id->session);
+#if (NGX_PTR_SIZE == 4)
ngx_slab_free_locked(shpool, sess_id->id);
+#endif
ngx_slab_free_locked(shpool, sess_id);
}
}
+static void
+ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
+{
+ ngx_ssl_sess_id_t *sess_id, *sess_id_temp;
+
+ for ( ;; ) {
+
+ if (node->key < temp->key) {
+
+ if (temp->left == sentinel) {
+ temp->left = node;
+ break;
+ }
+
+ temp = temp->left;
+
+ } else if (node->key > temp->key) {
+
+ if (temp->right == sentinel) {
+ temp->right = node;
+ break;
+ }
+
+ temp = temp->right;
+
+ } else { /* node->key == temp->key */
+
+ sess_id = (ngx_ssl_sess_id_t *) node;
+ sess_id_temp = (ngx_ssl_sess_id_t *) temp;
+
+ if (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
+ (size_t) node->data, (size_t) temp->data)
+ < 0)
+ {
+ if (temp->left == sentinel) {
+ temp->left = node;
+ break;
+ }
+
+ temp = temp->left;
+
+ } else {
+
+ if (temp->right == sentinel) {
+ temp->right = node;
+ break;
+ }
+
+ temp = temp->right;
+ }
+ }
+ }
+
+ node->parent = temp;
+ node->left = sentinel;
+ node->right = sentinel;
+ ngx_rbt_red(node);
+}
+
+
void
ngx_ssl_cleanup_ctx(void *data)
{
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 078b2bab0..9e8ce1733 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -55,33 +55,29 @@ typedef struct {
#define NGX_SSL_NO_BUILTIN_SCACHE -3
-typedef struct ngx_ssl_cached_sess_s ngx_ssl_cached_sess_t;
+#define NGX_SSL_MAX_SESSION_SIZE (4096)
+typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;
-#define NGX_SSL_MAX_SESSION_SIZE (4096 - offsetof(ngx_ssl_cached_sess_t, asn1))
-
-
-typedef struct {
+struct ngx_ssl_sess_id_s {
ngx_rbtree_node_t node;
u_char *id;
size_t len;
- ngx_ssl_cached_sess_t *session;
-} ngx_ssl_sess_id_t;
-
-
-struct ngx_ssl_cached_sess_s {
- ngx_ssl_cached_sess_t *prev;
- ngx_ssl_cached_sess_t *next;
+ u_char *session;
+ ngx_ssl_sess_id_t *prev;
+ ngx_ssl_sess_id_t *next;
time_t expire;
- ngx_ssl_sess_id_t *sess_id;
- u_char asn1[1];
+#if (NGX_PTR_SIZE == 8)
+ void *stub;
+ u_char sess_id[32];
+#endif
};
typedef struct {
ngx_rbtree_t *session_rbtree;
- ngx_ssl_cached_sess_t session_cache_head;
- ngx_ssl_cached_sess_t session_cache_tail;
+ ngx_ssl_sess_id_t session_cache_head;
+ ngx_ssl_sess_id_t session_cache_tail;
} ngx_ssl_session_cache_t;
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 59b89b0f9..0239bd105 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -531,6 +531,12 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
} else if (!p->cachable && p->in) {
cl = p->in;
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "pipe write buf ls:%d %p %z",
+ cl->buf->last_shadow,
+ cl->buf->pos,
+ cl->buf->last - cl->buf->pos);
+
if (cl->buf->recycled
&& cl->buf->last_shadow
&& bsize + cl->buf->last - cl->buf->pos > p->busy_size)
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index ababb819a..589de6d41 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -17,6 +17,11 @@ ngx_mutex_t *ngx_event_timer_mutex;
ngx_thread_volatile ngx_rbtree_t ngx_event_timer_rbtree;
static ngx_rbtree_node_t ngx_event_timer_sentinel;
+/*
+ * the event timer rbtree may contain the duplicate keys, however,
+ * it should not be a problem, because we use the rbtree to find
+ * a minimum timer value only
+ */
ngx_int_t
ngx_event_timer_init(ngx_log_t *log)
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index c05aefde4..5025f5649 100644
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -87,7 +87,10 @@ ngx_http_addition_header_filter(ngx_http_request_t *r)
ngx_http_addition_ctx_t *ctx;
ngx_http_addition_conf_t *conf;
- if (r->headers_out.status != NGX_HTTP_OK || r != r->main) {
+ if (r->headers_out.status != NGX_HTTP_OK
+ || r != r->main
+ || r->headers_out.content_type.data == NULL)
+ {
return ngx_http_next_header_filter(r);
}
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index ab214770e..3791b3e14 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -1310,6 +1310,9 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num);
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "input buf %p %z", b->pos, b->last - b->pos);
+
if (f->pos + f->length < f->last) {
@@ -1350,6 +1353,9 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
b->shadow = buf;
b->last_shadow = 1;
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "input buf last %p %z", b->pos, b->last - b->pos);
+
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c
index 396cb7fd3..416a4ebf4 100644
--- a/src/http/modules/ngx_http_limit_zone_module.c
+++ b/src/http/modules/ngx_http_limit_zone_module.c
@@ -104,6 +104,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
{
size_t len, n;
uint32_t hash;
+ ngx_int_t rc;
ngx_slab_pool_t *shpool;
ngx_rbtree_node_t *node, *sentinel;
ngx_pool_cleanup_t *cln;
@@ -131,10 +132,22 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- r->limit_zone_set = 1;
-
len = vv->len;
+ if (len == 0) {
+ return NGX_DECLINED;
+ }
+
+ if (len > 255) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "the value of the \"%V\" variable "
+ "is more than 255 bytes: \"%V\"",
+ &ctx->var, vv);
+ return NGX_DECLINED;
+ }
+
+ r->main->limit_zone_set = 1;
+
hash = ngx_crc32_short(vv->data, len);
cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_limit_zone_cleanup_t));
@@ -161,12 +174,14 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
continue;
}
- if (hash == node->key ){
+ /* hash == node->key */
+
+ do {
lz = (ngx_http_limit_zone_node_t *) &node->color;
- if (len == (size_t) lz->len
- && ngx_strncmp(lz->data, vv->data, len) == 0)
- {
+ rc = ngx_memn2cmp(lz->data, vv->data, (size_t) lz->len, len);
+
+ if (rc == 0) {
if ((ngx_uint_t) lz->conn < lzcf->conn) {
lz->conn++;
goto done;
@@ -176,7 +191,12 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
return NGX_HTTP_SERVICE_UNAVAILABLE;
}
- }
+
+ node = (rc < 0) ? node->left : node->right;
+
+ } while (node != sentinel && hash == node->key);
+
+ break;
}
n = offsetof(ngx_rbtree_node_t, color)
@@ -216,6 +236,65 @@ done:
static void
+ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp,
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
+{
+ ngx_http_limit_zone_node_t *lzn, *lznt;
+
+ for ( ;; ) {
+
+ if (node->key < temp->key) {
+
+ if (temp->left == sentinel) {
+ temp->left = node;
+ break;
+ }
+
+ temp = temp->left;
+
+ } else if (node->key > temp->key) {
+
+ if (temp->right == sentinel) {
+ temp->right = node;
+ break;
+ }
+
+ temp = temp->right;
+
+ } else { /* node->key == temp->key */
+
+ lzn = (ngx_http_limit_zone_node_t *) &node->color;
+ lznt = (ngx_http_limit_zone_node_t *) &temp->color;
+
+ if (ngx_memn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0) {
+
+ if (temp->left == sentinel) {
+ temp->left = node;
+ break;
+ }
+
+ temp = temp->left;
+
+ } else {
+
+ if (temp->right == sentinel) {
+ temp->right = node;
+ break;
+ }
+
+ temp = temp->right;
+ }
+ }
+ }
+
+ node->parent = temp;
+ node->left = sentinel;
+ node->right = sentinel;
+ ngx_rbt_red(node);
+}
+
+
+static void
ngx_http_limit_zone_cleanup(void *data)
{
ngx_http_limit_zone_cleanup_t *lzcln = data;
@@ -260,7 +339,7 @@ ngx_http_limit_zone_init_zone(ngx_shm_zone_t *shm_zone, void *data)
if (octx) {
if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "limit_zone \"%V\" use the \"%V\" variable "
+ "limit_zone \"%V\" uses the \"%V\" variable "
"while previously it used the \"%V\" variable",
&shm_zone->name, &ctx->var, &octx->var);
return NGX_ERROR;
@@ -287,7 +366,7 @@ ngx_http_limit_zone_init_zone(ngx_shm_zone_t *shm_zone, void *data)
ctx->rbtree->root = sentinel;
ctx->rbtree->sentinel = sentinel;
- ctx->rbtree->insert = ngx_rbtree_insert_value;
+ ctx->rbtree->insert = ngx_http_limit_zone_rbtree_insert_value;
return NGX_OK;
}
@@ -419,6 +498,12 @@ ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
+ if (n > 65535) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "connection limit must be less 65536");
+ return NGX_CONF_ERROR;
+ }
+
lzcf->conn = n;
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 1ee34db00..c8e11bf20 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -2381,7 +2381,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
noregex = 0;
flags = NGX_HTTP_SSI_ADD_ZERO;
last--;
- p++;
+ p++;
} else {
noregex = 1;
diff --git a/src/http/modules/ngx_http_upstream_ip_hash_module.c b/src/http/modules/ngx_http_upstream_ip_hash_module.c
index 1de019e05..e0cf8afc1 100644
--- a/src/http/modules/ngx_http_upstream_ip_hash_module.c
+++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c
@@ -171,14 +171,14 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
if (!peer->down) {
- if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
- break;
- }
-
- if (now - peer->accessed > peer->fail_timeout) {
- peer->fails = 0;
- break;
- }
+ if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
+ break;
+ }
+
+ if (now - peer->accessed > peer->fail_timeout) {
+ peer->fails = 0;
+ break;
+ }
} else {
iphp->rrp.tried[n] |= m;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 48018053c..bf7a8eba6 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.5.6';
+our $VERSION = '0.5.7';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 29296b6a2..a33a9f7ee 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -199,7 +199,7 @@ ngx_http_perl_handle_request(ngx_http_request_t *r)
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));
if (ctx == NULL) {
ngx_http_finalize_request(r, NGX_ERROR);
- return;
+ return;
}
ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 34149c49f..2bff24560 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -935,7 +935,8 @@ ngx_http_core_find_location(ngx_http_request_t *r,
if (clcfp[i]->auto_redirect
&& r->uri.len == clcfp[i]->name.len - 1
&& ngx_strncmp(r->uri.data, clcfp[i]->name.data,
- clcfp[i]->name.len - 1) == 0)
+ clcfp[i]->name.len - 1)
+ == 0)
{
/* the locations are lexicographically sorted */
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 00fa4575e..f9d2482ea 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1356,7 +1356,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
rc = ngx_http_send_header(r);
- if (rc == NGX_ERROR || rc > NGX_OK || r->post_action) {
+ if (rc == NGX_ERROR || rc > NGX_OK || r->post_action || r->header_only) {
ngx_http_upstream_finalize_request(r, u, rc);
return;
}
diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c
index 1a3147ece..6ee6b331a 100644
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -1191,7 +1191,7 @@ ngx_imap_do_auth(ngx_imap_session_t *s)
s->state = 0;
if (s->connection->read->timer_set) {
- ngx_del_timer(s->connection->read);
+ ngx_del_timer(s->connection->read);
}
s->login_attempt++;
diff --git a/src/os/unix/ngx_gcc_atomic_amd64.h b/src/os/unix/ngx_gcc_atomic_amd64.h
index 289cd614e..1008a6017 100644
--- a/src/os/unix/ngx_gcc_atomic_amd64.h
+++ b/src/os/unix/ngx_gcc_atomic_amd64.h
@@ -24,8 +24,11 @@
*
*
* The "r" is any register, %rax (%r0) - %r16.
- * The "=a" and "a" are the %rax register. Although we can return result
- * in any register, we use %rax because it is used in cmpxchgq anyway.
+ * The "=a" and "a" are the %rax register.
+ * Although we can return result in any register, we use "a" because it is
+ * used in cmpxchgq anyway. The result is actually in %al but not in $rax,
+ * however as the code is inlined gcc can test %al as well as %rax.
+ *
* The "cc" means that flags were changed.
*/
@@ -33,14 +36,13 @@ static ngx_inline ngx_atomic_uint_t
ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
ngx_atomic_uint_t set)
{
- ngx_atomic_uint_t res;
+ u_char res;
__asm__ volatile (
NGX_SMP_LOCK
" cmpxchgq %3, %1; "
- " setz %b0; "
- " movzbq %b0, %0; "
+ " sete %0; "
: "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
@@ -68,7 +70,7 @@ ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
NGX_SMP_LOCK
" xaddq %0, %1; "
- : "+q" (add) : "m" (*value) : "cc", "memory");
+ : "+r" (add) : "m" (*value) : "cc", "memory");
return add;
}
diff --git a/src/os/unix/ngx_gcc_atomic_x86.h b/src/os/unix/ngx_gcc_atomic_x86.h
index 1e1582580..27c353d0d 100644
--- a/src/os/unix/ngx_gcc_atomic_x86.h
+++ b/src/os/unix/ngx_gcc_atomic_x86.h
@@ -23,9 +23,13 @@
* }
*
*
- * The "q" is any of the %eax, %ebx, %ecx, or %edx registers.
- * The "=a" and "a" are the %eax register. Although we can return result
- * in any register, we use %eax because it is used in cmpxchgl anyway.
+ * The "r" means the general register.
+ * The "=a" and "a" are the %eax register.
+ * Although we can return result in any register, we use "a" because it is
+ * used in cmpxchgl anyway. The result is actually in %al but not in %eax,
+ * however, as the code is inlined gcc can test %al as well as %eax,
+ * and icc adds "movzbl %al, %eax" by itself.
+ *
* The "cc" means that flags were changed.
*/
@@ -33,16 +37,15 @@ static ngx_inline ngx_atomic_uint_t
ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
ngx_atomic_uint_t set)
{
- ngx_atomic_uint_t res;
+ u_char res;
__asm__ volatile (
NGX_SMP_LOCK
" cmpxchgl %3, %1; "
- " setz %b0; "
- " movzbl %b0, %0; "
+ " sete %0; "
- : "=a" (res) : "m" (*lock), "a" (old), "q" (set) : "cc", "memory");
+ : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
return res;
}
@@ -56,7 +59,7 @@ ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
* r = temp;
*
*
- * The "+q" is any of the %eax, %ebx, %ecx, or %edx registers.
+ * The "+r" means the general register.
* The "cc" means that flags were changed.
*/
@@ -80,7 +83,7 @@ ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
NGX_SMP_LOCK
" xaddl %0, %1; "
- : "+q" (add) : "m" (*value) : "cc", "memory");
+ : "+r" (add) : "m" (*value) : "cc", "memory");
return add;
}
@@ -89,9 +92,9 @@ ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
#else
/*
- * gcc 2.7 does not support "+q", so we have to use the fixed %eax ("=a" and
- * "a") and this adds two superfluous instructions in the end of code,
- * something like this: "mov %eax, %edx / mov %edx, %eax".
+ * gcc 2.7 does not support "+r", so we have to use the fixed
+ * %eax ("=a" and "a") and this adds two superfluous instructions in the end
+ * of code, something like this: "mov %eax, %edx / mov %edx, %eax".
*/
static ngx_inline ngx_atomic_int_t