# HG changeset patch # User Igor Sysoev # Date 1320004800 -14400 # Node ID 615b5ea36fc09dcff88e2be40da47a59bb7275c6 # Parent e461dead01e99c038464445d97d18d2f3350ae0b nginx 1.1.7 *) Feature: support of several resolvers in the "resolver" directive. Thanks to Kirill A. Korinskiy. *) Bugfix: a segmentation fault occurred on start or while reconfiguration if the "ssl" directive was used at http level and there was no "ssl_certificate" defined. *) Bugfix: reduced memory consumption while proxying of big files if they were buffered to disk. *) Bugfix: a segmentation fault might occur in a worker process if "proxy_http_version 1.1" directive was used. *) Bugfix: in the "expires @time" directive. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,22 @@ +Changes with nginx 1.1.7 31 Oct 2011 + + *) Feature: support of several resolvers in the "resolver" directive. + Thanks to Kirill A. Korinskiy. + + *) Bugfix: a segmentation fault occurred on start or while + reconfiguration if the "ssl" directive was used at http level and + there was no "ssl_certificate" defined. + + *) Bugfix: reduced memory consumption while proxying of big files if + they were buffered to disk. + + *) Bugfix: a segmentation fault might occur in a worker process if + "proxy_http_version 1.1" directive was used. + + *) Bugfix: in the "expires @time" directive. + + Changes with nginx 1.1.6 17 Oct 2011 *) Change in internal API: now module context data are cleared while diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,22 @@ +Изменения в nginx 1.1.7 31.10.2011 + + *) Добавление: поддержка нескольких DNS серверов в директиве "resolver". + Спасибо Кириллу Коринскому. + + *) Исправление: на старте или во время переконфигурации происходил + segmentation fault, если директива ssl использовалась на уровне http + и не был указан ssl_certificate. + + *) Исправление: уменьшено потребление памяти при проксировании больших + файлов, если они буферизировались на диск. + + *) Исправление: в рабочем процессе мог произойти segmentation fault, + если использовалась директива "proxy_http_version 1.1". + + *) Исправление: в директиве "expires @time". + + Изменения в nginx 1.1.6 17.10.2011 *) Изменение во внутреннем API: теперь при внутреннем редиректе в diff --git a/README b/README --- a/README +++ b/README @@ -1,4 +1,3 @@ -The Russian documentation is available at http://sysoev.ru/nginx/ -The English documentation is available at http://nginx.net +Documentation is available at http://nginx.org diff --git a/auto/cc/name b/auto/cc/name --- a/auto/cc/name +++ b/auto/cc/name @@ -25,6 +25,13 @@ fi if [ "$CC" = cl ]; then if `$NGX_WINE $CC -v 2>&1 \ + | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16' \ + >/dev/null 2>&1`; then + + NGX_CC_NAME=msvc10 + echo " + using Microsoft Visual C++ 10 compiler" + + else if `$NGX_WINE $CC -v 2>&1 \ | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14' \ >/dev/null 2>&1`; then @@ -43,6 +50,7 @@ if [ "$CC" = cl ]; then echo " + using Microsoft Visual C++ compiler" fi fi + fi else if [ "$CC" = wcl386 ]; then diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -306,21 +306,21 @@ if [ $help = yes ]; then cat << END - --help this message + --help print this message - --prefix=PATH set the installation prefix - --sbin-path=PATH set path to the nginx binary file - --conf-path=PATH set path to the nginx.conf file - --error-log-path=PATH set path to the error log - --pid-path=PATH set path to nginx.pid file - --lock-path=PATH set path to nginx.lock file + --prefix=PATH set installation prefix + --sbin-path=PATH set nginx binary pathname + --conf-path=PATH set nginx.conf pathname + --error-log-path=PATH set error log pathname + --pid-path=PATH set nginx.pid pathname + --lock-path=PATH set nginx.lock pathname - --user=USER set non-privilege user - for the worker processes - --group=GROUP set non-privilege group - for the worker processes + --user=USER set non-privileged user for + worker processes + --group=GROUP set non-privileged group for + worker processes - --builddir=DIR set the build directory + --builddir=DIR set build directory --with-rtsig_module enable rtsig module --with-select_module enable select module @@ -328,8 +328,8 @@ cat << END --with-poll_module enable poll module --without-poll_module disable poll module - --with-file-aio enable file aio support - --with-ipv6 enable ipv6 support + --with-file-aio enable file AIO support + --with-ipv6 enable IPv6 support --with-http_ssl_module enable ngx_http_ssl_module --with-http_realip_module enable ngx_http_realip_module @@ -372,17 +372,20 @@ cat << END disable ngx_http_upstream_ip_hash_module --with-http_perl_module enable ngx_http_perl_module - --with-perl_modules_path=PATH set path to the perl modules - --with-perl=PATH set path to the perl binary + --with-perl_modules_path=PATH set Perl modules path + --with-perl=PATH set perl binary pathname - --http-log-path=PATH set path to the http access log - --http-client-body-temp-path=PATH set path to the http client request body - temporary files - --http-proxy-temp-path=PATH set path to the http proxy temporary files - --http-fastcgi-temp-path=PATH set path to the http fastcgi temporary - files - --http-uwsgi-temp-path=PATH set path to the http uwsgi temporary files - --http-scgi-temp-path=PATH set path to the http scgi temporary files + --http-log-path=PATH set http access log pathname + --http-client-body-temp-path=PATH set path to store + http client request body temporary files + --http-proxy-temp-path=PATH set path to store + http proxy temporary files + --http-fastcgi-temp-path=PATH set path to store + http fastcgi temporary files + --http-uwsgi-temp-path=PATH set path to store + http uwsgi temporary files + --http-scgi-temp-path=PATH set path to store + http scgi temporary files --without-http disable HTTP server --without-http-cache disable HTTP cache @@ -398,40 +401,40 @@ cat << END --add-module=PATH enable an external module - --with-cc=PATH set path to C compiler - --with-cpp=PATH set path to C preprocessor - --with-cc-opt=OPTIONS set additional options for C compiler - --with-ld-opt=OPTIONS set additional options for linker - --with-cpu-opt=CPU build for specified CPU, the valid values: + --with-cc=PATH set C compiler pathname + --with-cpp=PATH set C preprocessor pathname + --with-cc-opt=OPTIONS set additional C compiler options + --with-ld-opt=OPTIONS set additional linker options + --with-cpu-opt=CPU build for the specified CPU, valid values: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, sparc32, sparc64, ppc64 --without-pcre disable PCRE library usage --with-pcre force PCRE library usage --with-pcre=DIR set path to PCRE library sources - --with-pcre-opt=OPTIONS set additional options for PCRE building + --with-pcre-opt=OPTIONS set additional build options for PCRE --with-md5=DIR set path to md5 library sources - --with-md5-opt=OPTIONS set additional options for md5 building + --with-md5-opt=OPTIONS set additional build options for md5 --with-md5-asm use md5 assembler sources --with-sha1=DIR set path to sha1 library sources - --with-sha1-opt=OPTIONS set additional options for sha1 building + --with-sha1-opt=OPTIONS set additional build options for sha1 --with-sha1-asm use sha1 assembler sources --with-zlib=DIR set path to zlib library sources - --with-zlib-opt=OPTIONS set additional options for zlib building + --with-zlib-opt=OPTIONS set additional build options for zlib --with-zlib-asm=CPU use zlib assembler sources optimized - for specified CPU, the valid values: + for the specified CPU, valid values: pentium, pentiumpro --with-libatomic force libatomic_ops library usage --with-libatomic=DIR set path to libatomic_ops library sources --with-openssl=DIR set path to OpenSSL library sources - --with-openssl-opt=OPTIONS set additional options for OpenSSL building + --with-openssl-opt=OPTIONS set additional build options for OpenSSL - --with-debug enable the debugging logging + --with-debug enable debug logging END diff --git a/conf/mime.types b/conf/mime.types --- a/conf/mime.types +++ b/conf/mime.types @@ -62,6 +62,7 @@ types { audio/midi mid midi kar; audio/mpeg mp3; audio/ogg ogg; + audio/x-m4a m4a; audio/x-realaudio ra; video/3gpp 3gpp 3gp; @@ -69,6 +70,7 @@ types { video/mpeg mpeg mpg; video/quicktime mov; video/x-flv flv; + video/x-m4v m4v; video/x-mng mng; video/x-ms-asf asx asf; video/x-ms-wmv wmv; diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -203,6 +203,8 @@ main(int argc, char *const *argv) ngx_cycle_t *cycle, init_cycle; ngx_core_conf_t *ccf; + ngx_debug_init(); + if (ngx_strerror_init() != NGX_OK) { return 1; } @@ -260,10 +262,6 @@ main(int argc, char *const *argv) } } -#if (NGX_FREEBSD) - ngx_debug_init(); -#endif - /* TODO */ ngx_max_sockets = -1; ngx_time_init(); diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1001006 -#define NGINX_VERSION "1.1.6" +#define nginx_version 1001007 +#define NGINX_VERSION "1.1.7" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -671,7 +671,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx n = ngx_atoi(port, len); - if (n < 1 || n > 65536) { + if (n < 1 || n > 65535) { u->err = "invalid port"; return NGX_ERROR; } @@ -695,7 +695,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx if (n != NGX_ERROR) { - if (n < 1 || n > 65536) { + if (n < 1 || n > 65535) { u->err = "invalid port"; return NGX_ERROR; } @@ -835,7 +835,7 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ng n = ngx_atoi(port, len); - if (n < 1 || n > 65536) { + if (n < 1 || n > 65535) { u->err = "invalid port"; return NGX_ERROR; } diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -91,8 +91,10 @@ static u_char *ngx_resolver_log_error(ng ngx_resolver_t * -ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr) +ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) { + ngx_url_t u; + ngx_uint_t i; ngx_resolver_t *r; ngx_pool_cleanup_t *cln; ngx_udp_connection_t *uc; @@ -109,6 +111,15 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_ return NULL; } + if (n) { + if (ngx_array_init(&r->udp_connections, cf->pool, n, + sizeof(ngx_udp_connection_t)) + != NGX_OK) + { + return NULL; + } + } + cln->data = r; r->event = ngx_calloc(sizeof(ngx_event_t), cf->log); @@ -140,17 +151,27 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_ r->log = &cf->cycle->new_log; r->log_level = NGX_LOG_ERR; - if (addr) { - uc = ngx_calloc(sizeof(ngx_udp_connection_t), cf->log); + for (i = 0; i < n; i++) { + ngx_memzero(&u, sizeof(ngx_url_t)); + + u.host = names[i]; + u.port = 53; + + if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); + return NULL; + } + + uc = ngx_array_push(&r->udp_connections); if (uc == NULL) { return NULL; } - r->udp_connection = uc; - - uc->sockaddr = addr->sockaddr; - uc->socklen = addr->socklen; - uc->server = addr->name; + ngx_memzero(uc, sizeof(ngx_udp_connection_t)); + + uc->sockaddr = u.addrs->sockaddr; + uc->socklen = u.addrs->socklen; + uc->server = u.addrs->name; uc->log = cf->cycle->new_log; uc->log.handler = ngx_resolver_log_error; @@ -167,6 +188,9 @@ ngx_resolver_cleanup(void *data) { ngx_resolver_t *r = data; + ngx_uint_t i; + ngx_udp_connection_t *uc; + if (r) { ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "cleanup resolver"); @@ -179,12 +203,13 @@ ngx_resolver_cleanup(void *data) ngx_free(r->event); } - if (r->udp_connection) { - if (r->udp_connection->connection) { - ngx_close_connection(r->udp_connection->connection); + + uc = r->udp_connections.elts; + + for (i = 0; i < r->udp_connections.nelts; i++) { + if (uc[i].connection) { + ngx_close_connection(uc[i].connection); } - - ngx_free(r->udp_connection); } ngx_free(r); @@ -242,7 +267,7 @@ ngx_resolve_start(ngx_resolver_t *r, ngx } } - if (r->udp_connection == NULL) { + if (r->udp_connections.nelts == 0) { return NGX_NO_RESOLVER; } @@ -826,7 +851,12 @@ ngx_resolver_send_query(ngx_resolver_t * ssize_t n; ngx_udp_connection_t *uc; - uc = r->udp_connection; + uc = r->udp_connections.elts; + + uc = &uc[r->last_connection++]; + if (r->last_connection == r->udp_connections.nelts) { + r->last_connection = 0; + } if (uc->connection == NULL) { if (ngx_udp_connect(uc) != NGX_OK) { diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h --- a/src/core/ngx_resolver.h +++ b/src/core/ngx_resolver.h @@ -77,16 +77,16 @@ typedef struct { typedef struct { /* has to be pointer because of "incomplete type" */ ngx_event_t *event; - - /* TODO: DNS peers balancer */ - /* STUB */ - ngx_udp_connection_t *udp_connection; - + void *dummy; ngx_log_t *log; /* ident must be after 3 pointers */ ngx_int_t ident; + /* simple round robin DNS peers balancer */ + ngx_array_t udp_connections; + ngx_uint_t last_connection; + ngx_rbtree_t name_rbtree; ngx_rbtree_node_t name_sentinel; @@ -123,8 +123,6 @@ struct ngx_resolver_ctx_s { in_addr_t *addrs; in_addr_t addr; - /* TODO: DNS peers balancer ctx */ - ngx_resolver_handler_pt handler; void *data; ngx_msec_t timeout; @@ -135,7 +133,8 @@ struct ngx_resolver_ctx_s { }; -ngx_resolver_t *ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr); +ngx_resolver_t *ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, + ngx_uint_t n); ngx_resolver_ctx_t *ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp); ngx_int_t ngx_resolve_name(ngx_resolver_ctx_t *ctx); diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c --- a/src/core/ngx_slab.c +++ b/src/core/ngx_slab.c @@ -42,14 +42,14 @@ #if (NGX_DEBUG_MALLOC) -#define ngx_slab_junk(p, size) ngx_memset(p, 0xD0, size) +#define ngx_slab_junk(p, size) ngx_memset(p, 0xA5, size) #else -#if (NGX_FREEBSD) +#if (NGX_HAVE_DEBUG_MALLOC) #define ngx_slab_junk(p, size) \ - if (ngx_freebsd_debug_malloc) ngx_memset(p, 0xD0, size) + if (ngx_debug_malloc) ngx_memset(p, 0xA5, size) #else diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -863,6 +863,13 @@ ngx_ssl_handle_recv(ngx_connection_t *c, ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled"); + while (ERR_peek_error()) { + ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0, + "ignoring stale global SSL error"); + } + + ERR_clear_error(); + c->ssl->no_wait_shutdown = 1; c->ssl->no_send_shutdown = 1; @@ -1352,19 +1359,37 @@ ngx_ssl_connection_error(ngx_connection_ n = ERR_GET_REASON(ERR_peek_error()); /* handshake failures */ - if (n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */ + if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */ + || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */ || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ + || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */ + || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */ || n == SSL_R_LENGTH_MISMATCH /* 159 */ || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ + || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ +#ifdef SSL_R_PARSE_TLSEXT + || n == SSL_R_PARSE_TLSEXT /* 227 */ +#endif || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ || n == SSL_R_UNEXPECTED_RECORD /* 245 */ || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */ || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */ || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */ || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */ +#ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG + || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG /* 335 */ + || n == SSL_R_RENEGOTIATION_ENCODING_ERR /* 336 */ + || n == SSL_R_RENEGOTIATION_MISMATCH /* 337 */ +#endif +#ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED + || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED /* 338 */ +#endif +#ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING + || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */ +#endif || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -15,8 +15,6 @@ static ngx_int_t ngx_event_pipe_write_to static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p); static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); -static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, - ngx_buf_t *buf); static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p); @@ -576,17 +574,13 @@ ngx_event_pipe_write_to_downstream(ngx_e if (p->out) { cl = p->out; - if (cl->buf->recycled - && bsize + cl->buf->last - cl->buf->pos > p->busy_size) - { - flush = 1; - break; + if (cl->buf->recycled) { + ngx_log_error(NGX_LOG_ALERT, p->log, 0, + "recycled buffer in pipe out chain"); } p->out = p->out->next; - ngx_event_pipe_free_shadow_raw_buf(&p->free_raw_bufs, cl->buf); - } else if (!p->cacheable && p->in) { cl = p->in; @@ -596,24 +590,13 @@ ngx_event_pipe_write_to_downstream(ngx_e 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) - { - if (!prev_last_shadow) { - p->in = p->in->next; - - cl->next = NULL; - - if (out) { - *ll = cl; - } else { - out = cl; - } + if (cl->buf->recycled && prev_last_shadow) { + if (bsize + cl->buf->end - cl->buf->start > p->busy_size) { + flush = 1; + break; } - flush = 1; - break; + bsize += cl->buf->end - cl->buf->start; } prev_last_shadow = cl->buf->last_shadow; @@ -624,10 +607,6 @@ ngx_event_pipe_write_to_downstream(ngx_e break; } - if (cl->buf->recycled) { - bsize += cl->buf->last - cl->buf->pos; - } - cl->next = NULL; if (out) { @@ -701,9 +680,10 @@ ngx_event_pipe_write_to_downstream(ngx_e static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p) { - ssize_t size, bsize; + ssize_t size, bsize, n; ngx_buf_t *b; - ngx_chain_t *cl, *tl, *next, *out, **ll, **last_free, fl; + ngx_uint_t prev_last_shadow; + ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl; if (p->buf_to_file) { fl.buf = p->buf_to_file; @@ -719,6 +699,7 @@ ngx_event_pipe_write_chain_to_temp_file( size = 0; cl = out; ll = NULL; + prev_last_shadow = 1; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe offset: %O", p->temp_file->offset); @@ -726,16 +707,21 @@ ngx_event_pipe_write_chain_to_temp_file( do { bsize = cl->buf->last - cl->buf->pos; - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf %p, pos %p, size: %z", - cl->buf->start, cl->buf->pos, bsize); + ngx_log_debug4(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe buf ls:%d %p, pos %p, size: %z", + cl->buf->last_shadow, cl->buf->start, + cl->buf->pos, bsize); - if ((size + bsize > p->temp_file_write_size) - || (p->temp_file->offset + size + bsize > p->max_temp_file_size)) + if (prev_last_shadow + && ((size + bsize > p->temp_file_write_size) + || (p->temp_file->offset + size + bsize + > p->max_temp_file_size))) { break; } + prev_last_shadow = cl->buf->last_shadow; + size += bsize; ll = &cl->next; cl = cl->next; @@ -762,10 +748,63 @@ ngx_event_pipe_write_chain_to_temp_file( p->last_in = &p->in; } - if (ngx_write_chain_to_temp_file(p->temp_file, out) == NGX_ERROR) { + n = ngx_write_chain_to_temp_file(p->temp_file, out); + + if (n == NGX_ERROR) { return NGX_ABORT; } + if (p->buf_to_file) { + p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos; + n -= p->buf_to_file->last - p->buf_to_file->pos; + p->buf_to_file = NULL; + out = out->next; + } + + if (n > 0) { + /* update previous buffer or add new buffer */ + + if (p->out) { + for (cl = p->out; cl->next; cl = cl->next) { /* void */ } + + b = cl->buf; + + if (b->file_last == p->temp_file->offset) { + p->temp_file->offset += n; + b->file_last = p->temp_file->offset; + goto free; + } + + last_out = &cl->next; + + } else { + last_out = &p->out; + } + + cl = ngx_chain_get_free_buf(p->pool, &p->free); + if (cl == NULL) { + return NGX_ABORT; + } + + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->tag = p->tag; + + b->file = &p->temp_file->file; + b->file_pos = p->temp_file->offset; + p->temp_file->offset += n; + b->file_last = p->temp_file->offset; + + b->in_file = 1; + b->temp_file = 1; + + *last_out = cl; + } + +free: + for (last_free = &p->free_raw_bufs; *last_free != NULL; last_free = &(*last_free)->next) @@ -773,31 +812,13 @@ ngx_event_pipe_write_chain_to_temp_file( /* void */ } - if (p->buf_to_file) { - p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos; - p->buf_to_file = NULL; - out = out->next; - } - for (cl = out; cl; cl = next) { next = cl->next; - cl->next = NULL; + + cl->next = p->free; + p->free = cl; b = cl->buf; - b->file = &p->temp_file->file; - b->file_pos = p->temp_file->offset; - p->temp_file->offset += b->last - b->pos; - b->file_last = p->temp_file->offset; - - b->in_file = 1; - b->temp_file = 1; - - if (p->out) { - *p->last_out = cl; - } else { - p->out = cl; - } - p->last_out = &cl->next; if (b->last_shadow) { @@ -913,35 +934,6 @@ ngx_event_pipe_remove_shadow_links(ngx_b } -static ngx_inline void -ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, ngx_buf_t *buf) -{ - ngx_buf_t *s; - ngx_chain_t *cl, **ll; - - if (buf->shadow == NULL) { - return; - } - - for (s = buf->shadow; !s->last_shadow; s = s->shadow) { /* void */ } - - ll = free; - - for (cl = *free; cl; cl = cl->next) { - if (cl->buf == s) { - *ll = cl->next; - break; - } - - if (cl->buf->shadow) { - break; - } - - ll = &cl->next; - } -} - - ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b) { diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h --- a/src/event/ngx_event_pipe.h +++ b/src/event/ngx_event_pipe.h @@ -30,8 +30,6 @@ struct ngx_event_pipe_s { ngx_chain_t **last_in; ngx_chain_t *out; - ngx_chain_t **last_out; - ngx_chain_t *free; ngx_chain_t *busy; diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -253,7 +253,7 @@ ngx_http_set_expires(ngx_http_request_t return NGX_ERROR; } - if (conf->expires_time == 0) { + if (conf->expires_time == 0 && conf->expires != NGX_HTTP_EXPIRES_DAILY) { ngx_memcpy(expires->value.data, ngx_cached_http_time.data, ngx_cached_http_time.len + 1); ngx_str_set(&cc->value, "max-age=0"); @@ -262,16 +262,16 @@ ngx_http_set_expires(ngx_http_request_t now = ngx_time(); - if (conf->expires == NGX_HTTP_EXPIRES_ACCESS - || r->headers_out.last_modified_time == -1) + if (conf->expires == NGX_HTTP_EXPIRES_DAILY) { + expires_time = ngx_next_time(conf->expires_time); + max_age = expires_time - now; + + } else if (conf->expires == NGX_HTTP_EXPIRES_ACCESS + || r->headers_out.last_modified_time == -1) { expires_time = now + conf->expires_time; max_age = conf->expires_time; - } else if (conf->expires == NGX_HTTP_EXPIRES_DAILY) { - expires_time = ngx_next_time(conf->expires_time); - max_age = expires_time - now; - } else { expires_time = r->headers_out.last_modified_time + conf->expires_time; max_age = expires_time - now; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -346,7 +346,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_pool_cleanup_t *cln; - ngx_conf_merge_value(conf->enable, prev->enable, 0); + if (conf->enable == NGX_CONF_UNSET) { + if (prev->enable == NGX_CONF_UNSET) { + conf->enable = 0; + + } else { + conf->enable = prev->enable; + conf->file = prev->file; + conf->line = prev->line; + } + } ngx_conf_merge_value(conf->session_timeout, prev->session_timeout, 300); diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- 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.6'; +our $VERSION = '1.1.7'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -718,7 +718,7 @@ static ngx_command_t ngx_http_core_comm NULL }, { ngx_string("resolver"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_core_resolver, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -3535,7 +3535,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t * to inherit it in all servers */ - prev->resolver = ngx_resolver_create(cf, NULL); + prev->resolver = ngx_resolver_create(cf, NULL, 0); if (prev->resolver == NULL) { return NGX_CONF_ERROR; } @@ -4540,7 +4540,6 @@ ngx_http_core_resolver(ngx_conf_t *cf, n { ngx_http_core_loc_conf_t *clcf = conf; - ngx_url_t u; ngx_str_t *value; if (clcf->resolver) { @@ -4549,21 +4548,11 @@ ngx_http_core_resolver(ngx_conf_t *cf, n value = cf->args->elts; - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.host = value[1]; - u.port = 53; - - if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); + clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); + if (clcf->resolver == NULL) { return NGX_CONF_ERROR; } - clcf->resolver = ngx_resolver_create(cf, &u.addrs[0]); - if (clcf->resolver == NULL) { - return NGX_OK; - } - return NGX_CONF_OK; } diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -783,7 +783,7 @@ ngx_mail_auth_http_process_headers(ngx_m sin->sin_family = AF_INET; port = ngx_atoi(ctx->port.data, ctx->port.len); - if (port == NGX_ERROR || port < 1 || port > 65536) { + if (port == NGX_ERROR || port < 1 || port > 65535) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "auth http server %V sent invalid server " "port:\"%V\"", diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -69,7 +69,7 @@ static ngx_command_t ngx_mail_core_comm NULL }, { ngx_string("resolver"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, ngx_mail_core_resolver, NGX_MAIL_SRV_CONF_OFFSET, 0, @@ -493,7 +493,6 @@ ngx_mail_core_resolver(ngx_conf_t *cf, n { ngx_mail_core_srv_conf_t *cscf = conf; - ngx_url_t u; ngx_str_t *value; value = cf->args->elts; @@ -507,21 +506,11 @@ ngx_mail_core_resolver(ngx_conf_t *cf, n return NGX_CONF_OK; } - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.host = value[1]; - u.port = 53; - - if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); + cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); + if (cscf->resolver == NULL) { return NGX_CONF_ERROR; } - cscf->resolver = ngx_resolver_create(cf, &u.addrs[0]); - if (cscf->resolver == NULL) { - return NGX_CONF_OK; - } - return NGX_CONF_OK; } diff --git a/src/os/unix/ngx_darwin.h b/src/os/unix/ngx_darwin.h --- a/src/os/unix/ngx_darwin.h +++ b/src/os/unix/ngx_darwin.h @@ -8,6 +8,7 @@ #define _NGX_DARWIN_H_INCLUDED_ +void ngx_debug_init(void); ngx_chain_t *ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); @@ -15,5 +16,7 @@ extern int ngx_darwin_kern_osrelda extern int ngx_darwin_hw_ncpu; extern u_long ngx_darwin_net_inet_tcp_sendspace; +extern ngx_uint_t ngx_debug_malloc; + #endif /* _NGX_DARWIN_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_darwin_config.h b/src/os/unix/ngx_darwin_config.h --- a/src/os/unix/ngx_darwin_config.h +++ b/src/os/unix/ngx_darwin_config.h @@ -87,6 +87,7 @@ #define NGX_HAVE_OS_SPECIFIC_INIT 1 +#define NGX_HAVE_DEBUG_MALLOC 1 extern char **environ; diff --git a/src/os/unix/ngx_darwin_init.c b/src/os/unix/ngx_darwin_init.c --- a/src/os/unix/ngx_darwin_init.c +++ b/src/os/unix/ngx_darwin_init.c @@ -14,6 +14,8 @@ int ngx_darwin_hw_ncpu; int ngx_darwin_kern_ipc_somaxconn; u_long ngx_darwin_net_inet_tcp_sendspace; +ngx_uint_t ngx_debug_malloc; + static ngx_os_io_t ngx_darwin_io = { ngx_unix_recv, @@ -55,10 +57,37 @@ sysctl_t sysctls[] = { }; +void +ngx_debug_init() +{ +#if (NGX_DEBUG_MALLOC) + + /* + * MacOSX 10.6, 10.7: MallocScribble fills freed memory with 0x55 + * and fills allocated memory with 0xAA. + * MacOSX 10.4, 10.5: MallocScribble fills freed memory with 0x55, + * MallocPreScribble fills allocated memory with 0xAA. + * MacOSX 10.3: MallocScribble fills freed memory with 0x55, + * and no way to fill allocated memory. + */ + + setenv("MallocScribble", "1", 0); + + ngx_debug_malloc = 1; + +#else + + if (getenv("MallocScribble")) { + ngx_debug_malloc = 1; + } + +#endif +} + + ngx_int_t ngx_os_specific_init(ngx_log_t *log) { - int somaxconn; size_t size; ngx_err_t err; ngx_uint_t i; @@ -125,12 +154,9 @@ ngx_os_specific_init(ngx_log_t *log) ngx_ncpu = ngx_darwin_hw_ncpu; - somaxconn = 32676; - - if (ngx_darwin_kern_ipc_somaxconn > somaxconn) { + if (ngx_darwin_kern_ipc_somaxconn > 32767) { ngx_log_error(NGX_LOG_ALERT, log, 0, - "sysctl kern.ipc.somaxconn must be no more than %d", - somaxconn); + "sysctl kern.ipc.somaxconn must be less than 32768"); return NGX_ERROR; } diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -153,7 +153,7 @@ ngx_write_chain_to_file(ngx_file_t *file { u_char *prev; size_t size; - ssize_t n; + ssize_t total, n; ngx_array_t vec; struct iovec *iov, iovs[NGX_IOVS]; @@ -165,6 +165,8 @@ ngx_write_chain_to_file(ngx_file_t *file offset); } + total = 0; + vec.elts = iovs; vec.size = sizeof(struct iovec); vec.nalloc = NGX_IOVS; @@ -202,8 +204,15 @@ ngx_write_chain_to_file(ngx_file_t *file if (vec.nelts == 1) { iov = vec.elts; - return ngx_write_file(file, (u_char *) iov[0].iov_base, - iov[0].iov_len, offset); + + n = ngx_write_file(file, (u_char *) iov[0].iov_base, + iov[0].iov_len, offset); + + if (n == NGX_ERROR) { + return n; + } + + return total + n; } if (file->sys_offset != offset) { @@ -233,10 +242,11 @@ ngx_write_chain_to_file(ngx_file_t *file file->sys_offset += n; file->offset += n; + total += n; } while (cl); - return n; + return total; } diff --git a/src/os/unix/ngx_freebsd.h b/src/os/unix/ngx_freebsd.h --- a/src/os/unix/ngx_freebsd.h +++ b/src/os/unix/ngx_freebsd.h @@ -8,6 +8,7 @@ #define _NGX_FREEBSD_H_INCLUDED_ +void ngx_debug_init(void); ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); @@ -17,7 +18,7 @@ extern u_long ngx_freebsd_net_inet_ extern ngx_uint_t ngx_freebsd_sendfile_nbytes_bug; extern ngx_uint_t ngx_freebsd_use_tcp_nopush; -extern ngx_uint_t ngx_freebsd_debug_malloc; +extern ngx_uint_t ngx_debug_malloc; #endif /* _NGX_FREEBSD_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -109,6 +109,7 @@ pid_t rfork_thread(int flags, void *stac #define NGX_HAVE_OS_SPECIFIC_INIT 1 +#define NGX_HAVE_DEBUG_MALLOC 1 extern char **environ; diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -22,7 +22,8 @@ int ngx_freebsd_machdep_hlt_logical_ ngx_uint_t ngx_freebsd_sendfile_nbytes_bug; ngx_uint_t ngx_freebsd_use_tcp_nopush; -ngx_uint_t ngx_freebsd_debug_malloc; + +ngx_uint_t ngx_debug_malloc; static ngx_os_io_t ngx_freebsd_io = { @@ -80,7 +81,7 @@ ngx_debug_init() malloc_options = "J"; #endif - ngx_freebsd_debug_malloc = 1; + ngx_debug_malloc = 1; #else char *mo; @@ -88,7 +89,7 @@ ngx_debug_init() mo = getenv("MALLOC_OPTIONS"); if (mo && ngx_strchr(mo, 'J')) { - ngx_freebsd_debug_malloc = 1; + ngx_debug_malloc = 1; } #endif } @@ -97,7 +98,7 @@ ngx_debug_init() ngx_int_t ngx_os_specific_init(ngx_log_t *log) { - int version, somaxconn; + int version; size_t size; ngx_err_t err; ngx_uint_t i; @@ -209,12 +210,9 @@ ngx_os_specific_init(ngx_log_t *log) ngx_ncpu = ngx_freebsd_hw_ncpu; } - somaxconn = version < 600008 ? 32676 : 65535; - - if (ngx_freebsd_kern_ipc_somaxconn > somaxconn) { + if (version < 600008 && ngx_freebsd_kern_ipc_somaxconn > 32767) { ngx_log_error(NGX_LOG_ALERT, log, 0, - "sysctl kern.ipc.somaxconn must be no more than %d", - somaxconn); + "sysctl kern.ipc.somaxconn must be less than 32768"); return NGX_ERROR; } diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -108,6 +108,7 @@ typedef struct iocb ngx_aiocb_t; #define NGX_HAVE_OS_SPECIFIC_INIT 1 +#define ngx_debug_init() extern char **environ; diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -31,7 +31,6 @@ typedef struct { } ngx_os_io_t; -void ngx_debug_init(void); ngx_int_t ngx_os_init(ngx_log_t *log); void ngx_os_status(ngx_log_t *log); ngx_int_t ngx_os_specific_init(ngx_log_t *log); diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_posix_config.h @@ -125,6 +125,8 @@ typedef struct aiocb ngx_aiocb_t; #define NGX_LISTEN_BACKLOG 511 +#define ngx_debug_init() + #if (__FreeBSD__) && (__FreeBSD_version < 400017) diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -98,6 +98,7 @@ #define NGX_HAVE_OS_SPECIFIC_INIT 1 +#define ngx_debug_init() extern char **environ;