# HG changeset patch # User Igor Sysoev # Date 1320091200 -14400 # Node ID 692f4d4d7f10bde683152c07b4404df5fd60bbbe # Parent ea7441793bbab668acbe92b3bd784d722162abbb nginx 1.0.9 *) Change: now the 0x7F-0x1F characters are escaped as \xXX in an access_log. *) Change: now SIGWINCH signal works only in daemon mode. *) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support the following additional values: X-Accel-Limit-Rate, X-Accel-Buffering, X-Accel-Charset. *) Feature: decrease of memory consumption if SSL is used. *) Feature: accept filters are now supported on NetBSD. *) Feature: the "uwsgi_buffering" and "scgi_buffering" directives. Thanks to Peter Smit. *) 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: some UTF-8 characters were processed incorrectly. Thanks to Alexey Kuts. *) Bugfix: the ngx_http_rewrite_module directives specified at "server" level were executed twice if no matching locations were defined. *) Bugfix: a socket leak might occurred if "aio sendfile" was used. *) Bugfix: connections with fast clients might be closed after send_timeout if file AIO was used. *) Bugfix: in the ngx_http_autoindex_module. *) Bugfix: the module ngx_http_mp4_module did not support seeking on 32-bit platforms. *) Bugfix: non-cacheable responses might be cached if "proxy_cache_bypass" directive was used. Thanks to John Ferlito. *) Bugfix: cached responses with an empty body were returned incorrectly; the bug had appeared in 0.8.31. *) Bugfix: 201 responses of the ngx_http_dav_module were incorrect; the bug had appeared in 0.8.32. *) Bugfix: in the "return" directive. *) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and "ssl_prefer_server_ciphers" directives might work incorrectly if SNI was used. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,59 @@ +Changes with nginx 1.0.9 01 Nov 2011 + + *) Change: now the 0x7F-0x1F characters are escaped as \xXX in an + access_log. + + *) Change: now SIGWINCH signal works only in daemon mode. + + *) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support + the following additional values: X-Accel-Limit-Rate, + X-Accel-Buffering, X-Accel-Charset. + + *) Feature: decrease of memory consumption if SSL is used. + + *) Feature: accept filters are now supported on NetBSD. + + *) Feature: the "uwsgi_buffering" and "scgi_buffering" directives. + Thanks to Peter Smit. + + *) 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: some UTF-8 characters were processed incorrectly. + Thanks to Alexey Kuts. + + *) Bugfix: the ngx_http_rewrite_module directives specified at "server" + level were executed twice if no matching locations were defined. + + *) Bugfix: a socket leak might occurred if "aio sendfile" was used. + + *) Bugfix: connections with fast clients might be closed after + send_timeout if file AIO was used. + + *) Bugfix: in the ngx_http_autoindex_module. + + *) Bugfix: the module ngx_http_mp4_module did not support seeking on + 32-bit platforms. + + *) Bugfix: non-cacheable responses might be cached if + "proxy_cache_bypass" directive was used. + Thanks to John Ferlito. + + *) Bugfix: cached responses with an empty body were returned + incorrectly; the bug had appeared in 0.8.31. + + *) Bugfix: 201 responses of the ngx_http_dav_module were incorrect; the + bug had appeared in 0.8.32. + + *) Bugfix: in the "return" directive. + + *) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and + "ssl_prefer_server_ciphers" directives might work incorrectly if SNI + was used. + + Changes with nginx 1.0.8 01 Oct 2011 *) Bugfix: nginx could not be built --with-http_mp4_module and without @@ -35,9 +90,6 @@ Changes with nginx 1.0.7 *) Bugfix: nginx could not be built on MacOSX 10.7. - *) Bugfix: in the "proxy/fastcgi/scgi/uwsgi_ignore_client_abort" - directives. - *) Bugfix: request body might be processed incorrectly if client used pipelining. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,61 @@ +Изменения в nginx 1.0.9 01.11.2011 + + *) Изменение: теперь символы 0x7F-0xFF в access_log записываются в виде + \xXX. + + *) Изменение: SIGWINCH сигнал теперь работает только в режиме демона. + + *) Добавление: директивы "proxy/fastcgi/scgi/uwsgi_ignore_headers" + теперь поддерживают значения X-Accel-Limit-Rate, X-Accel-Buffering и + X-Accel-Charset. + + *) Добавление: уменьшение потребления памяти при использовании SSL. + + *) Добавление: теперь на NetBSD поддерживаются accept фильтры. + + *) Добавление: директивы uwsgi_buffering и scgi_buffering. + Спасибо Peter Smit. + + *) Исправление: на старте или во время переконфигурации происходил + segmentation fault, если директива ssl использовалась на уровне http + и не был указан ssl_certificate. + + *) Исправление: некоторые UTF-8 символы обрабатывались неправильно. + Спасибо Алексею Куцу. + + *) Исправление: директивы модуля ngx_http_rewrite_module, заданные на + уровне server, применялись повторно, если для запроса не находилось + ни одного location'а. + + *) Исправление: при использовании "aio sendfile" могла происходить + утечка сокетов. + + *) Исправление: при использовании файлового AIO соединения с быстрыми + клиентами могли быть закрыты по истечению send_timeout. + + *) Исправление: в модуле ngx_http_autoindex_module. + + *) Исправление: модуль ngx_http_mp4_module не поддерживал перемотку на + 32-битных платформах. + + *) Исправление: при использовании proxy_cache_bypass могли быть + закэшированы некэшируемые ответы. + Спасибо John Ferlito. + + *) Исправление: закэшированные ответы с пустым телом возвращались + некорректно; ошибка появилась в 0.8.31. + + *) Исправление: ответы с кодом 201 модуля ngx_http_dav_module были + некорректны; ошибка появилась в 0.8.32. + + *) Исправление: в директиве return. + + *) Исправление: директивы ssl_verify_client, ssl_verify_depth и + ssl_prefer_server_cipher могли работать некорректно, если + использовался SNI. + + Изменения в nginx 1.0.8 01.10.2011 *) Исправление: nginx не собирался с модулем ngx_http_mp4_module и без @@ -35,9 +92,6 @@ *) Исправление: nginx не собирался на MacOSX 10.7. - *) Исправление: в директивах proxy/fastcgi/scgi/ - uwsgi_ignore_client_abort. - *) Исправление: обработка тела запроса могла быть неверной, если клиент использовал pipelining. 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/install b/auto/install --- a/auto/install +++ b/auto/install @@ -53,7 +53,7 @@ esac case ".$NGX_ERROR_LOG_PATH" in - ./*) + ./* | .) ;; *) @@ -78,7 +78,7 @@ manpage: 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|" \\ + -e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\ < man/nginx.8 > $NGX_OBJS/nginx.8 install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \ @@ -137,7 +137,7 @@ install: $NGX_OBJS${ngx_dirsep}nginx${ng END -if test -n "\$(DESTDIR)$NGX_ERROR_LOG_PATH"; then +if test -n "$NGX_ERROR_LOG_PATH"; then cat << END >> $NGX_MAKEFILE test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' || \ diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -295,6 +295,7 @@ if [ $ngx_found != yes ]; then fi fi + ngx_feature="SO_SETFIB" ngx_feature_name="NGX_HAVE_SETFIB" ngx_feature_run=no @@ -305,6 +306,28 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature +ngx_feature="SO_ACCEPTFILTER" +ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT" +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)" +. auto/feature + + +ngx_feature="TCP_DEFER_ACCEPT" +ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT" +ngx_feature_run=no +ngx_feature_incs="#include + #include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_DEFER_ACCEPT, NULL, 0)" +. auto/feature + + ngx_feature="accept4()" ngx_feature_name="NGX_HAVE_ACCEPT4" ngx_feature_run=no 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.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 1000008 -#define NGINX_VERSION "1.0.8" +#define nginx_version 1000009 +#define NGINX_VERSION "1.0.9" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -580,7 +580,7 @@ ngx_configure_listening_sockets(ngx_cycl { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setsockopt(SO_ACCEPTFILTER, \"%s\") " - " for %V failed, ignored", + "for %V failed, ignored", ls[i].accept_filter, &ls[i].addr_text); continue; } diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -739,7 +739,7 @@ old_shm_zone_done: ngx_temp_pool = ngx_create_pool(128, cycle->log); if (ngx_temp_pool == NULL) { ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, - "can not create ngx_temp_pool"); + "could not create ngx_temp_pool"); exit(1); } diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -369,12 +369,13 @@ ngx_log_create(ngx_cycle_t *cycle, ngx_s char * ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log) { - ngx_uint_t i, n, d; + ngx_uint_t i, n, d, found; ngx_str_t *value; value = cf->args->elts; for (i = 2; i < cf->args->nelts; i++) { + found = 0; for (n = 1; n <= NGX_LOG_DEBUG; n++) { if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) { @@ -387,7 +388,8 @@ ngx_log_set_levels(ngx_conf_t *cf, ngx_l } log->log_level = n; - continue; + found = 1; + break; } } @@ -401,11 +403,13 @@ ngx_log_set_levels(ngx_conf_t *cf, ngx_l } log->log_level |= d; + found = 1; + break; } } - if (log->log_level == 0) { + if (!found) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid log level \"%V\"", &value[i]); return NGX_CONF_ERROR; diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c +++ b/src/core/ngx_palloc.c @@ -68,7 +68,7 @@ ngx_destroy_pool(ngx_pool_t *pool) /* * we could allocate the pool->log from this pool - * so we can not use this log while the free()ing the pool + * so we cannot use this log while free()ing the pool */ for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c --- a/src/core/ngx_parse.c +++ b/src/core/ngx_parse.c @@ -93,7 +93,7 @@ ngx_parse_offset(ngx_str_t *line) ngx_int_t -ngx_parse_time(ngx_str_t *line, ngx_uint_t sec) +ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec) { u_char *p, *last; ngx_int_t value, total, scale; @@ -114,8 +114,8 @@ ngx_parse_time(ngx_str_t *line, ngx_uint valid = 0; value = 0; total = 0; - step = sec ? st_start : st_month; - scale = sec ? 1 : 1000; + step = is_sec ? st_start : st_month; + scale = is_sec ? 1 : 1000; p = line->data; last = p + line->len; @@ -135,81 +135,81 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_year; - max = 68; + max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365); scale = 60 * 60 * 24 * 365; break; case 'M': - if (step > st_year) { + if (step >= st_month) { return NGX_ERROR; } step = st_month; - max = 828; + max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30); scale = 60 * 60 * 24 * 30; break; case 'w': - if (step > st_month) { + if (step >= st_week) { return NGX_ERROR; } step = st_week; - max = 3550; + max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7); scale = 60 * 60 * 24 * 7; break; case 'd': - if (step > st_week) { + if (step >= st_day) { return NGX_ERROR; } step = st_day; - max = 24855; + max = NGX_MAX_INT32_VALUE / (60 * 60 * 24); scale = 60 * 60 * 24; break; case 'h': - if (step > st_day) { + if (step >= st_hour) { return NGX_ERROR; } step = st_hour; - max = 596523; + max = NGX_MAX_INT32_VALUE / (60 * 60); scale = 60 * 60; break; case 'm': if (*p == 's') { - if (sec || step > st_sec) { + if (is_sec || step >= st_msec) { return NGX_ERROR; } p++; step = st_msec; - max = 2147483647; + max = NGX_MAX_INT32_VALUE; scale = 1; break; } - if (step > st_hour) { + if (step >= st_min) { return NGX_ERROR; } step = st_min; - max = 35791394; + max = NGX_MAX_INT32_VALUE / 60; scale = 60; break; case 's': - if (step > st_min) { + if (step >= st_sec) { return NGX_ERROR; } step = st_sec; - max = 2147483647; + max = NGX_MAX_INT32_VALUE; scale = 1; break; case ' ': - if (step > st_min) { + if (step >= st_sec) { return NGX_ERROR; } step = st_last; - max = 2147483647; + max = NGX_MAX_INT32_VALUE; scale = 1; break; @@ -217,7 +217,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } - if (step != st_msec && !sec) { + if (step != st_msec && !is_sec) { scale *= 1000; max /= 1000; } @@ -228,12 +228,12 @@ ngx_parse_time(ngx_str_t *line, ngx_uint total += value * scale; - if ((ngx_uint_t) total > 2147483647) { + if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) { return NGX_ERROR; } value = 0; - scale = sec ? 1 : 1000; + scale = is_sec ? 1 : 1000; while (p < last && *p == ' ') { p++; diff --git a/src/core/ngx_parse.h b/src/core/ngx_parse.h --- a/src/core/ngx_parse.h +++ b/src/core/ngx_parse.h @@ -17,7 +17,7 @@ ssize_t ngx_parse_size(ngx_str_t *line); off_t ngx_parse_offset(ngx_str_t *line); -ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t sec); +ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec); #endif /* _NGX_PARSE_H_INCLUDED_ */ diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -381,7 +381,7 @@ ngx_vslprintf(u_char *buf, u_char *last, /* * (int64_t) cast is required for msvc6: - * it can not convert uint64_t to double + * it cannot convert uint64_t to double */ ui64 = (uint64_t) ((f - (int64_t) ui64) * scale + 0.5); @@ -1211,19 +1211,19 @@ ngx_utf8_decode(u_char **p, size_t n) u = **p; - if (u > 0xf0) { + if (u >= 0xf0) { u &= 0x07; valid = 0xffff; len = 3; - } else if (u > 0xe0) { + } else if (u >= 0xe0) { u &= 0x0f; valid = 0x7ff; len = 2; - } else if (u > 0xc0) { + } else if (u >= 0xc2) { u &= 0x1f; valid = 0x7f; @@ -1380,6 +1380,26 @@ ngx_escape_uri(u_char *dst, u_char *src, 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ }; + /* not ALPHA, DIGIT, "-", ".", "_", "~" */ + + static uint32_t uri_component[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0xfc009fff, /* 1111 1100 0000 0000 1001 1111 1111 1111 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + /* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */ static uint32_t html[] = { @@ -1443,7 +1463,7 @@ ngx_escape_uri(u_char *dst, u_char *src, /* mail_auth is the same as memcached */ static uint32_t *map[] = - { uri, args, html, refresh, memcached, memcached }; + { uri, args, uri_component, html, refresh, memcached, memcached }; escape = map[type]; diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -189,12 +189,13 @@ size_t ngx_utf8_length(u_char *p, size_t u_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len); -#define NGX_ESCAPE_URI 0 -#define NGX_ESCAPE_ARGS 1 -#define NGX_ESCAPE_HTML 2 -#define NGX_ESCAPE_REFRESH 3 -#define NGX_ESCAPE_MEMCACHED 4 -#define NGX_ESCAPE_MAIL_AUTH 5 +#define NGX_ESCAPE_URI 0 +#define NGX_ESCAPE_ARGS 1 +#define NGX_ESCAPE_URI_COMPONENT 2 +#define NGX_ESCAPE_HTML 3 +#define NGX_ESCAPE_REFRESH 4 +#define NGX_ESCAPE_MEMCACHED 5 +#define NGX_ESCAPE_MAIL_AUTH 6 #define NGX_UNESCAPE_URI 1 #define NGX_UNESCAPE_REDIRECT 2 diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -1027,7 +1027,7 @@ ngx_event_use(ngx_conf_t *cf, ngx_comman "when the server runs without a master process " "the \"%V\" event type must be the same as " "in previous configuration - \"%s\" " - "and it can not be changed on the fly, " + "and it cannot be changed on the fly, " "to change it you need to stop server " "and start it again", &value[1], old_ecf->name); 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 @@ -175,6 +175,14 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); } +#ifdef SSL_OP_NO_COMPRESSION + SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); +#endif + +#ifdef SSL_MODE_RELEASE_BUFFERS + SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS); +#endif + SSL_CTX_set_read_ahead(ssl->ctx, 1); SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback); @@ -855,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; @@ -1344,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_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -103,11 +103,11 @@ ngx_event_expire_timers(void) if (ngx_threaded && ngx_trylock(ev->lock) == 0) { /* - * We can not change the timer of the event that is been - * handling by another thread. And we can not easy walk - * the rbtree to find a next expired timer so we exit the loop. - * However it should be rare case when the event that is - * been handling has expired timer. + * We cannot change the timer of the event that is being + * handled by another thread. And we cannot easy walk + * the rbtree to find next expired timer so we exit the loop. + * However, it should be a rare case when the event that is + * being handled has an expired timer. */ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -26,9 +26,9 @@ typedef struct { ngx_str_t name; size_t utf_len; size_t escape; + size_t escape_html; unsigned dir:1; - unsigned colon:1; time_t mtime; off_t size; @@ -138,7 +138,7 @@ ngx_http_autoindex_handler(ngx_http_requ { u_char *last, *filename, scale; off_t length; - size_t len, utf_len, allocated, root; + size_t len, char_len, escape_html, allocated, root; ngx_tm_t tm; ngx_err_t err; ngx_buf_t *b; @@ -338,7 +338,10 @@ ngx_http_autoindex_handler(ngx_http_requ ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, - NGX_ESCAPE_HTML); + NGX_ESCAPE_URI_COMPONENT); + + entry->escape_html = ngx_escape_html(NULL, entry->name.data, + entry->name.len); if (utf8) { entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len); @@ -346,8 +349,6 @@ ngx_http_autoindex_handler(ngx_http_requ entry->utf_len = len; } - entry->colon = (ngx_strchr(entry->name.data, ':') != NULL); - entry->dir = ngx_de_is_dir(&dir); entry->mtime = ngx_de_mtime(&dir); entry->size = ngx_de_size(&dir); @@ -358,10 +359,12 @@ ngx_http_autoindex_handler(ngx_http_requ ngx_close_dir_n " \"%s\" failed", &path); } + escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len); + len = sizeof(title) - 1 - + r->uri.len + + r->uri.len + escape_html + sizeof(header) - 1 - + r->uri.len + + r->uri.len + escape_html + sizeof("") - 1 + sizeof("
../" CRLF) - 1
           + sizeof("

") - 1 @@ -373,7 +376,8 @@ ngx_http_autoindex_handler(ngx_http_requ + entry[i].name.len + entry[i].escape + 1 /* 1 is for "/" */ + sizeof("\">") - 1 - + entry[i].name.len - entry[i].utf_len + entry[i].colon * 2 + + entry[i].name.len - entry[i].utf_len + + entry[i].escape_html + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 + sizeof("") - 1 + sizeof(" 28-Sep-1970 12:00 ") - 1 @@ -393,9 +397,18 @@ ngx_http_autoindex_handler(ngx_http_requ } b->last = ngx_cpymem(b->last, title, sizeof(title) - 1); - b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); - b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); - b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); + + if (escape_html) { + b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len); + b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); + b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len); + + } else { + b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); + b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); + b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); + } + b->last = ngx_cpymem(b->last, "", sizeof("") - 1); b->last = ngx_cpymem(b->last, "
../" CRLF,
@@ -406,14 +419,9 @@ ngx_http_autoindex_handler(ngx_http_requ
     for (i = 0; i < entries.nelts; i++) {
         b->last = ngx_cpymem(b->last, "last++ = '.';
-            *b->last++ = '/';
-        }
-
         if (entry[i].escape) {
             ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
-                           NGX_ESCAPE_HTML);
+                           NGX_ESCAPE_URI_COMPONENT);
 
             b->last += entry[i].name.len + entry[i].escape;
 
@@ -433,20 +441,41 @@ ngx_http_autoindex_handler(ngx_http_requ
 
         if (entry[i].name.len != len) {
             if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
-                utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
+                char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
 
             } else {
-                utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
+                char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
             }
 
+            last = b->last;
             b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
-                                       utf_len, entry[i].name.len + 1);
+                                       char_len, entry[i].name.len + 1);
+
+            if (entry[i].escape_html) {
+                b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,
+                                                     b->last - last);
+            }
+
             last = b->last;
 
         } else {
-            b->last = ngx_cpystrn(b->last, entry[i].name.data,
-                                  NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
-            last = b->last - 3;
+            if (entry[i].escape_html) {
+                if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
+                    char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;
+
+                } else {
+                    char_len = len;
+                }
+
+                b->last = (u_char *) ngx_escape_html(b->last,
+                                                  entry[i].name.data, char_len);
+                last = b->last;
+
+            } else {
+                b->last = ngx_cpystrn(b->last, entry[i].name.data,
+                                      NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
+                last = b->last - 3;
+            }
         }
 
         if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -158,7 +158,7 @@ ngx_http_dav_handler(ngx_http_request_t 
 
         if (r->uri.data[r->uri.len - 1] == '/') {
             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                          "can not PUT to a collection");
+                          "cannot PUT to a collection");
             return NGX_HTTP_CONFLICT;
         }
 
diff --git a/src/http/modules/ngx_http_empty_gif_module.c b/src/http/modules/ngx_http_empty_gif_module.c
--- a/src/http/modules/ngx_http_empty_gif_module.c
+++ b/src/http/modules/ngx_http_empty_gif_module.c
@@ -111,19 +111,12 @@ static ngx_str_t  ngx_http_gif_type = ng
 static ngx_int_t
 ngx_http_empty_gif_handler(ngx_http_request_t *r)
 {
-    ngx_int_t                 rc;
     ngx_http_complex_value_t  cv;
 
     if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_HTTP_NOT_ALLOWED;
     }
 
-    rc = ngx_http_discard_request_body(r);
-
-    if (rc != NGX_OK) {
-        return rc;
-    }
-
     ngx_memzero(&cv, sizeof(ngx_http_complex_value_t));
 
     cv.value.len = sizeof(ngx_empty_gif);
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
@@ -507,7 +507,7 @@ ngx_http_headers_expires(ngx_conf_t *cf,
         minus = 0;
 
         if (hcf->expires == NGX_HTTP_EXPIRES_MODIFIED) {
-            return "daily time can not be used with \"modified\" parameter";
+            return "daily time cannot be used with \"modified\" parameter";
         }
 
         hcf->expires = NGX_HTTP_EXPIRES_DAILY;
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -690,12 +690,12 @@ ngx_http_log_escape(u_char *dst, u_char 
         0x10000000, /* 0001 0000 0000 0000  0000 0000 0000 0000 */
 
                     /*  ~}| {zyx wvut srqp  onml kjih gfed cba` */
-        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+        0x80000000, /* 1000 0000 0000 0000  0000 0000 0000 0000 */
 
-        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
-        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
-        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
-        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
 
@@ -960,7 +960,7 @@ buffer:
 
         if (log->script) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "buffered logs can not have variables in name");
+                               "buffered logs cannot have variables in name");
             return NGX_CONF_ERROR;
         }
 
@@ -1055,25 +1055,6 @@ ngx_http_log_compile_format(ngx_conf_t *
 
     for ( /* void */ ; s < args->nelts; s++) {
 
-        for (i = 0; i < value[s].len; i++) {
-            if (value[s].data[i] != '%') {
-                continue;
-            }
-
-            ch = value[s].data[i + 1];
-
-            if ((ch >= 'A' && ch <= 'Z')
-                 || (ch >= 'a' && ch <= 'z')
-                 || ch == '{')
-            {
-                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                     "the parameters in the \"%%name\" form are not supported, "
-                     "use the \"$variable\" instead");
-
-                return NGX_CONF_ERROR;
-            }
-        }
-
         i = 0;
 
         while (i < value[s].len) {
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -1882,7 +1882,7 @@ ngx_http_mp4_update_stts_atom(ngx_http_m
     }
 
     entries = trak->time_to_sample_entries;
-    start_time = mp4->start * trak->timescale / 1000;
+    start_time = (uint64_t) mp4->start * trak->timescale / 1000;
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
                    "time-to-sample start_time:%uL", start_time);
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -309,7 +309,7 @@ ngx_http_referer_merge_conf(ngx_conf_t *
     hash.key = ngx_hash_key_lc;
     hash.max_size = conf->referer_hash_max_size;
     hash.bucket_size = conf->referer_hash_bucket_size;
-    hash.name = "referers_hash";
+    hash.name = "referer_hash";
     hash.pool = cf->pool;
 
     if (conf->keys->keys.nelts) {
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -135,10 +135,22 @@ ngx_module_t  ngx_http_rewrite_module = 
 static ngx_int_t
 ngx_http_rewrite_handler(ngx_http_request_t *r)
 {
+    ngx_int_t                     index;
     ngx_http_script_code_pt       code;
     ngx_http_script_engine_t     *e;
+    ngx_http_core_srv_conf_t     *cscf;
+    ngx_http_core_main_conf_t    *cmcf;
     ngx_http_rewrite_loc_conf_t  *rlcf;
 
+    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+    index = cmcf->phase_engine.location_rewrite_index;
+
+    if (r->phase_handler == index && r->loc_conf == cscf->ctx->loc_conf) {
+        /* skipping location rewrite phase for server null location */
+        return NGX_DECLINED;
+    }
+
     rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module);
 
     if (rlcf->codes == NULL) {
@@ -167,8 +179,8 @@ ngx_http_rewrite_handler(ngx_http_reques
         code(e);
     }
 
-    if (e->status == NGX_DECLINED) {
-        return NGX_DECLINED;
+    if (e->status < NGX_HTTP_BAD_REQUEST) {
+        return e->status;
     }
 
     if (r->err_status == 0) {
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -96,6 +96,13 @@ static ngx_command_t ngx_http_scgi_comma
       offsetof(ngx_http_scgi_loc_conf_t, upstream.store_access),
       NULL },
 
+    { ngx_string("scgi_buffering"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_scgi_loc_conf_t, upstream.buffering),
+      NULL },
+
     { ngx_string("scgi_ignore_client_abort"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -412,7 +419,7 @@ ngx_http_scgi_handler(ngx_http_request_t
     u->abort_request = ngx_http_scgi_abort_request;
     u->finalize_request = ngx_http_scgi_finalize_request;
 
-    u->buffering = 1;
+    u->buffering = scf->upstream.buffering;
 
     u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
     if (u->pipe == NULL) {
@@ -1038,6 +1045,8 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t
     /* "scgi_cyclic_temp_file" is disabled */
     conf->upstream.cyclic_temp_file = 0;
 
+    conf->upstream.change_buffering = 1;
+
     ngx_str_set(&conf->upstream.module, "scgi");
 
     return conf;
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/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -139,6 +139,8 @@ ngx_http_static_handler(ngx_http_request
 
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
 
+        ngx_http_clear_location(r);
+
         r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
         if (r->headers_out.location == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -123,6 +123,13 @@ static ngx_command_t ngx_http_uwsgi_comm
       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.store_access),
       NULL },
 
+    { ngx_string("uwsgi_buffering"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffering),
+      NULL },
+
     { ngx_string("uwsgi_ignore_client_abort"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -445,7 +452,7 @@ ngx_http_uwsgi_handler(ngx_http_request_
     u->abort_request = ngx_http_uwsgi_abort_request;
     u->finalize_request = ngx_http_uwsgi_finalize_request;
 
-    u->buffering = 1;
+    u->buffering = uwcf->upstream.buffering;
 
     u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
     if (u->pipe == NULL) {
@@ -1091,6 +1098,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_
     /* "uwsgi_cyclic_temp_file" is disabled */
     conf->upstream.cyclic_temp_file = 0;
 
+    conf->upstream.change_buffering = 1;
+
     ngx_str_set(&conf->upstream.module, "uwsgi");
 
     return conf;
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.0.8';
+our $VERSION = '1.0.9';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -474,6 +474,13 @@ header_out(r, key, value)
         r->headers_out.content_length = header;
     }
 
+    if (header->key.len == sizeof("Content-Encoding") - 1
+        && ngx_strncasecmp(header->key.data, "Content-Encoding",
+                           sizeof("Content-Encoding") - 1) == 0)
+    {
+        r->headers_out.content_encoding = header;
+    }
+
 
 void
 filename(r)
@@ -836,7 +843,7 @@ variable(r, name, value = NULL)
     var.len = len;
     var.data = lowcase;
 
-    #if (NGX_LOG_DEBUG)
+    #if (NGX_DEBUG)
 
     if (value) {
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1226,7 +1226,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
 #endif
 
     /*
-     * we can not compare whole sockaddr struct's as kernel
+     * we cannot compare whole sockaddr struct's as kernel
      * may fill some fields in inherited sockaddr struct's
      */
 
@@ -1281,7 +1281,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
 
             if (addr[i].opt.set) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                        "a duplicate listen options for %s", addr[i].opt.addr);
+                        "duplicate listen options for %s", addr[i].opt.addr);
                 return NGX_ERROR;
             }
 
@@ -1747,10 +1747,12 @@ ngx_http_add_listening(ngx_conf_t *cf, n
 
 #if (NGX_WIN32)
     {
-    ngx_iocp_conf_t  *iocpcf;
-
-    iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
-    if (iocpcf->acceptex_read) {
+    ngx_iocp_conf_t  *iocpcf = NULL;
+
+    if (ngx_get_conf(cf->cycle->conf_ctx, ngx_events_module)) {
+        iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
+    }
+    if (iocpcf && iocpcf->acceptex_read) {
         ls->post_accept_buffer_size = cscf->client_header_buffer_size;
     }
     }
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -158,6 +158,11 @@ ngx_http_copy_filter(ngx_http_request_t 
             ngx_file_t            *file;
             ngx_http_ephemeral_t  *e;
 
+            if (r->aio) {
+                c->busy_sendfile = NULL;
+                return rc;
+            }
+
             file = c->busy_sendfile->file;
             offset = c->busy_sendfile->file_pos;
 
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
@@ -402,7 +402,7 @@ static ngx_command_t  ngx_http_core_comm
 
     { ngx_string("sendfile"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-                        |NGX_CONF_TAKE1,
+                        |NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_core_loc_conf_t, sendfile),
@@ -639,7 +639,7 @@ static ngx_command_t  ngx_http_core_comm
       NULL },
 
     { ngx_string("chunked_transfer_encoding"),
-      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_FLAG,
       ngx_conf_set_flag_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
@@ -983,6 +983,8 @@ ngx_http_core_find_config_phase(ngx_http
     }
 
     if (rc == NGX_DONE) {
+        ngx_http_clear_location(r);
+
         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
         if (r->headers_out.location == NULL) {
             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -1259,7 +1261,7 @@ ngx_http_core_try_files_phase(ngx_http_r
         tf++;
 
         ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "try to use %s: \"%s\" \"%s\"",
+                       "trying to use %s: \"%s\" \"%s\"",
                        test_dir ? "dir" : "file", name, path.data);
 
         if (tf->lengths == NULL && tf->name.len == 0) {
@@ -1784,19 +1786,20 @@ ngx_http_send_response(ngx_http_request_
     ngx_buf_t    *b;
     ngx_chain_t   out;
 
+    if (ngx_http_discard_request_body(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     r->headers_out.status = status;
 
-    if (status == NGX_HTTP_NO_CONTENT) {
-        r->header_only = 1;
-        return ngx_http_send_header(r);
-    }
-
     if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
     if (status >= NGX_HTTP_MOVED_PERMANENTLY && status <= NGX_HTTP_SEE_OTHER) {
 
+        ngx_http_clear_location(r);
+
         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
         if (r->headers_out.location == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -1897,7 +1900,7 @@ ngx_http_map_uri_to_path(ngx_http_reques
 
     if (alias && !r->valid_location) {
         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "\"alias\" could not be used in location \"%V\" "
+                      "\"alias\" cannot be used in location \"%V\" "
                       "where URI was rewritten", &clcf->name);
         return NULL;
     }
@@ -2468,7 +2471,7 @@ ngx_http_internal_redirect(ngx_http_requ
     if (r->uri_changes == 0) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "rewrite or internal redirection cycle "
-                      "while internal redirect to \"%V\"", uri);
+                      "while internally redirecting to \"%V\"", uri);
 
         r->main->count++;
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -2862,7 +2865,7 @@ ngx_http_core_location(ngx_conf_t *cf, n
 
         if (pclcf->exact_match) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "location \"%V\" could not be inside "
+                               "location \"%V\" cannot be inside "
                                "the exact location \"%V\"",
                                &clcf->name, &pclcf->name);
             return NGX_CONF_ERROR;
@@ -2870,7 +2873,7 @@ ngx_http_core_location(ngx_conf_t *cf, n
 
         if (pclcf->named) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "location \"%V\" could not be inside "
+                               "location \"%V\" cannot be inside "
                                "the named location \"%V\"",
                                &clcf->name, &pclcf->name);
             return NGX_CONF_ERROR;
@@ -2878,8 +2881,8 @@ ngx_http_core_location(ngx_conf_t *cf, n
 
         if (clcf->named) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "named location \"%V\" must be "
-                               "on server level only",
+                               "named location \"%V\" can be "
+                               "on the server level only",
                                &clcf->name);
             return NGX_CONF_ERROR;
         }
@@ -2948,7 +2951,7 @@ ngx_http_core_regex_location(ngx_conf_t 
 #else
 
     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                       "the using of the regex \"%V\" requires PCRE library",
+                       "using regex \"%V\" requires PCRE library",
                        regex);
     return NGX_ERROR;
 
@@ -2995,6 +2998,12 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_c
     value = cf->args->elts;
 
     if (ngx_strcmp(value[0].data, "include") == 0) {
+        if (cf->args->nelts != 2) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "invalid number of arguments"
+                               " in \"include\" directive");
+            return NGX_CONF_ERROR;
+        }
         file = value[1];
 
         if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
@@ -3024,11 +3033,11 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_c
                 type[n].value = content_type;
 
                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
-                                   "duplicate extention \"%V\", "
+                                   "duplicate extension \"%V\", "
                                    "content type: \"%V\", "
-                                   "old content type: \"%V\"",
+                                   "previous content type: \"%V\"",
                                    &value[i], content_type, old);
-                continue;
+                goto next;
             }
         }
 
@@ -3041,6 +3050,9 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_c
         type->key = value[i];
         type->key_hash = hash;
         type->value = content_type;
+
+    next:
+        continue;
     }
 
     return NGX_CONF_OK;
@@ -3178,7 +3190,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t 
     if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "the \"large_client_header_buffers\" size must be "
-                           "equal to or bigger than \"connection_pool_size\"");
+                           "equal to or greater than \"connection_pool_size\"");
         return NGX_CONF_ERROR;
     }
 
@@ -3191,7 +3203,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t 
                               prev->underscores_in_headers, 0);
 
     if (conf->server_names.nelts == 0) {
-        /* the array has 4 empty preallocated elements, so push can not fail */
+        /* the array has 4 empty preallocated elements, so push cannot fail */
         sn = ngx_array_push(&conf->server_names);
 #if (NGX_PCRE)
         sn->regex = NULL;
@@ -3374,7 +3386,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
                                              ngx_cacheline_size);
 
     /*
-     * the special handling the "types" directive in the "http" section
+     * the special handling of the "types" directive in the "http" section
      * to inherit the http's conf->types_hash to all servers
      */
 
@@ -3401,7 +3413,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
     }
 
     if (conf->types == NULL) {
-        conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
+        conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
         if (conf->types == NULL) {
             return NGX_CONF_ERROR;
         }
@@ -3426,7 +3438,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
         types_hash.key = ngx_hash_key_lc;
         types_hash.max_size = conf->types_hash_max_size;
         types_hash.bucket_size = conf->types_hash_bucket_size;
-        types_hash.name = "mime_types_hash";
+        types_hash.name = "types_hash";
         types_hash.pool = cf->pool;
         types_hash.temp_pool = NULL;
 
@@ -3468,9 +3480,10 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
                               NGX_HTTP_IMS_EXACT);
     ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
-                              0x7fffffff);
+                              NGX_MAX_INT32_VALUE);
     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
-                              prev->client_body_in_file_only, 0);
+                              prev->client_body_in_file_only,
+                              NGX_HTTP_REQUEST_BODY_FILE_OFF);
     ngx_conf_merge_value(conf->client_body_in_single_buffer,
                               prev->client_body_in_single_buffer, 0);
     ngx_conf_merge_value(conf->internal, prev->internal, 0);
@@ -3478,11 +3491,11 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
     ngx_conf_merge_size_value(conf->sendfile_max_chunk,
                               prev->sendfile_max_chunk, 0);
 #if (NGX_HAVE_FILE_AIO)
-    ngx_conf_merge_value(conf->aio, prev->aio, 0);
+    ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
 #endif
     ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
     ngx_conf_merge_off_value(conf->directio, prev->directio,
-                              NGX_MAX_OFF_T_VALUE);
+                              NGX_OPEN_FILE_DIRECTIO_OFF);
     ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
                               512);
     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
@@ -3779,7 +3792,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
             continue;
 #else
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "bind ipv6only is not supported "
+                               "ipv6only is not supported "
                                "on this platform");
             return NGX_CONF_ERROR;
 #endif
@@ -3798,7 +3811,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
         }
 
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "the invalid \"%V\" parameter", &value[n]);
+                           "invalid parameter \"%V\"", &value[n]);
         return NGX_CONF_ERROR;
     }
 
@@ -3836,17 +3849,10 @@ ngx_http_core_server_name(ngx_conf_t *cf
 
         if (ngx_strchr(value[i].data, '/')) {
             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
-                               "server name \"%V\" has strange symbols",
+                               "server name \"%V\" has suspicious symbols",
                                &value[i]);
         }
 
-        if (value[i].len == 1 && ch == '*') {
-            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "\"server_name *\" is unsupported, use "
-                               "\"server_name_in_redirect off\" instead");
-            return NGX_CONF_ERROR;
-        }
-
         sn = ngx_array_push(&cscf->server_names);
         if (sn == NULL) {
             return NGX_CONF_ERROR;
@@ -3907,7 +3913,7 @@ ngx_http_core_server_name(ngx_conf_t *cf
         }
 #else
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "the using of the regex \"%V\" "
+                           "using regex \"%V\" "
                            "requires PCRE library", &value[i]);
 
         return NGX_CONF_ERROR;
@@ -3939,7 +3945,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c
         } else {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "\"%V\" directive is duplicate, "
-                               "\"%s\" directive is specified before",
+                               "\"%s\" directive was specified earlier",
                                &cmd->name, clcf->alias ? "alias" : "root");
         }
 
@@ -3948,8 +3954,8 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c
 
     if (clcf->named && alias) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "the \"alias\" directive may not be used "
-                           "inside named location");
+                           "the \"alias\" directive cannot be used "
+                           "inside the named location");
 
         return NGX_CONF_ERROR;
     }
@@ -3960,7 +3966,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c
         || ngx_strstr(value[1].data, "${document_root}"))
     {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "the $document_root variable may not be used "
+                           "the $document_root variable cannot be used "
                            "in the \"%V\" directive",
                            &cmd->name);
 
@@ -3971,7 +3977,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c
         || ngx_strstr(value[1].data, "${realpath_root}"))
     {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "the $realpath_root variable may not be used "
+                           "the $realpath_root variable cannot be used "
                            "in the \"%V\" directive",
                            &cmd->name);
 
@@ -4430,7 +4436,7 @@ ngx_http_core_open_file_cache(ngx_conf_t
 
     if (max == 0) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                           "\"open_file_cache\" must have \"max\" parameter");
+                           "\"open_file_cache\" must have the \"max\" parameter");
         return NGX_CONF_ERROR;
     }
 
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -529,5 +529,12 @@ extern ngx_str_t  ngx_http_core_get_meth
         r->headers_out.last_modified = NULL;                                  \
     }
 
+#define ngx_http_clear_location(r)                                            \
+                                                                              \
+    if (r->headers_out.location) {                                            \
+        r->headers_out.location->hash = 0;                                    \
+        r->headers_out.location = NULL;                                       \
+    }
+
 
 #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -854,6 +854,10 @@ ngx_http_cache_send(ngx_http_request_t *
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http file cache send: %s", c->file.name.data);
 
+    if (r != r->main && c->length - c->body_start == 0) {
+        return ngx_http_send_header(r);
+    }
+
     /* we need to allocate all before the header would be sent */
 
     b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
@@ -866,8 +870,6 @@ ngx_http_cache_send(ngx_http_request_t *
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    r->header_only = (c->length - c->body_start) == 0;
-
     rc = ngx_http_send_header(r);
 
     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
@@ -877,7 +879,7 @@ ngx_http_cache_send(ngx_http_request_t *
     b->file_pos = c->body_start;
     b->file_last = c->length;
 
-    b->in_file = 1;
+    b->in_file = (c->length - c->body_start) ? 1: 0;
     b->last_buf = (r == r->main) ? 1: 0;
     b->last_in_chain = 1;
 
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -673,6 +673,24 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *
 
     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_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));
+
+#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));
+#endif
+
+    SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
+
     return SSL_TLSEXT_ERR_OK;
 }
 
@@ -2230,17 +2248,17 @@ ngx_http_writer(ngx_http_request_t *r)
             return;
         }
 
-    } else {
-        if (wev->delayed || r->aio) {
-            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
-                           "http writer delayed");
-
-            if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
-                ngx_http_close_request(r, 0);
-            }
-
-            return;
+    }
+
+    if (wev->delayed || r->aio) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
+                       "http writer delayed");
+
+        if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+            ngx_http_close_request(r, 0);
         }
+
+        return;
     }
 
     rc = ngx_http_output_filter(r, NULL);
@@ -2256,7 +2274,7 @@ ngx_http_writer(ngx_http_request_t *r)
 
     if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
 
-        if (!wev->ready && !wev->delayed) {
+        if (!wev->delayed) {
             ngx_add_timer(wev, clcf->send_timeout);
         }
 
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1106,6 +1106,8 @@ ngx_http_script_regex_end_code(ngx_http_
                           "rewritten redirect: \"%V\"", &e->buf);
         }
 
+        ngx_http_clear_location(r);
+
         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
         if (r->headers_out.location == NULL) {
             e->ip = ngx_http_script_exit;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -375,7 +375,7 @@ ngx_http_special_response_handler(ngx_ht
         }
     }
 
-    if (r->lingering_close == 1) {
+    if (r->lingering_close) {
         switch (error) {
             case NGX_HTTP_BAD_REQUEST:
             case NGX_HTTP_TO_HTTPS:
@@ -421,7 +421,6 @@ ngx_http_special_response_handler(ngx_ht
     if (error == NGX_HTTP_CREATED) {
         /* 201 */
         err = 0;
-        r->header_only = 1;
 
     } else if (error == NGX_HTTP_NO_CONTENT) {
         /* 204 */
@@ -583,6 +582,8 @@ ngx_http_send_error_page(ngx_http_reques
     ngx_str_set(&location->key, "Location");
     location->value = uri;
 
+    ngx_http_clear_location(r);
+
     r->headers_out.location = location;
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -636,7 +637,7 @@ ngx_http_send_special_response(ngx_http_
         r->headers_out.content_type_lowcase = NULL;
 
     } else {
-        r->headers_out.content_length_n = -1;
+        r->headers_out.content_length_n = 0;
     }
 
     if (r->headers_out.content_length) {
@@ -654,7 +655,7 @@ ngx_http_send_special_response(ngx_http_
     }
 
     if (ngx_http_error_pages[err].len == 0) {
-        return NGX_OK;
+        return ngx_http_send_special(r, NGX_HTTP_LAST);
     }
 
     b = ngx_calloc_buf(r->pool);
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -360,6 +360,9 @@ ngx_conf_bitmask_t  ngx_http_upstream_ca
 ngx_conf_bitmask_t  ngx_http_upstream_ignore_headers_masks[] = {
     { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT },
     { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES },
+    { ngx_string("X-Accel-Limit-Rate"), NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE },
+    { ngx_string("X-Accel-Buffering"), NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING },
+    { ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET },
     { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
     { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
     { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
@@ -672,6 +675,8 @@ ngx_http_upstream_cache(ngx_http_request
             return NGX_DECLINED;
         }
 
+        u->cacheable = 1;
+
         switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
 
         case NGX_ERROR:
@@ -685,8 +690,6 @@ ngx_http_upstream_cache(ngx_http_request
             break;
         }
 
-        u->cacheable = 1;
-
         c = r->cache;
 
         c->min_uses = u->conf->cache_min_uses;
@@ -987,7 +990,7 @@ ngx_http_upstream_check_broken_connectio
 
         if (!u->cacheable && u->peer.connection) {
             ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
-                          "kevent() reported that client closed prematurely "
+                          "kevent() reported that client prematurely closed "
                           "connection, so upstream connection is closed too");
             ngx_http_upstream_finalize_request(r, u,
                                                NGX_HTTP_CLIENT_CLOSED_REQUEST);
@@ -995,8 +998,8 @@ ngx_http_upstream_check_broken_connectio
         }
 
         ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
-                      "kevent() reported that client closed "
-                      "prematurely connection");
+                      "kevent() reported that client prematurely closed "
+                      "connection");
 
         if (u->peer.connection == NULL) {
             ngx_http_upstream_finalize_request(r, u,
@@ -1050,7 +1053,7 @@ ngx_http_upstream_check_broken_connectio
 
     if (!u->cacheable && u->peer.connection) {
         ngx_log_error(NGX_LOG_INFO, ev->log, err,
-                      "client closed prematurely connection, "
+                      "client prematurely closed connection, "
                       "so upstream connection is closed too");
         ngx_http_upstream_finalize_request(r, u,
                                            NGX_HTTP_CLIENT_CLOSED_REQUEST);
@@ -1058,7 +1061,7 @@ ngx_http_upstream_check_broken_connectio
     }
 
     ngx_log_error(NGX_LOG_INFO, ev->log, err,
-                  "client closed prematurely connection");
+                  "client prematurely closed connection");
 
     if (u->peer.connection == NULL) {
         ngx_http_upstream_finalize_request(r, u,
@@ -2154,8 +2157,6 @@ ngx_http_upstream_send_response(ngx_http
                 ngx_http_upstream_finalize_request(r, u, 0);
                 return;
             }
-
-            u->cacheable = 1;
         }
 
         break;
@@ -3027,7 +3028,12 @@ ngx_http_upstream_finalize_request(ngx_h
 
     r->connection->log->action = "sending to client";
 
-    if (rc == 0) {
+    if (rc == 0
+#if (NGX_HTTP_CACHE)
+        && !r->cached
+#endif
+       )
+    {
         rc = ngx_http_send_special(r, NGX_HTTP_LAST);
     }
 
@@ -3265,9 +3271,15 @@ static ngx_int_t
 ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    ngx_int_t  n;
-
-    r->upstream->headers_in.x_accel_limit_rate = h;
+    ngx_int_t             n;
+    ngx_http_upstream_t  *u;
+
+    u = r->upstream;
+    u->headers_in.x_accel_limit_rate = h;
+
+    if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE) {
+        return NGX_OK;
+    }
 
     n = ngx_atoi(h->value.data, h->value.len);
 
@@ -3283,16 +3295,23 @@ static ngx_int_t
 ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    u_char  c0, c1, c2;
-
-    if (r->upstream->conf->change_buffering) {
+    u_char                c0, c1, c2;
+    ngx_http_upstream_t  *u;
+
+    u = r->upstream;
+
+    if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING) {
+        return NGX_OK;
+    }
+
+    if (u->conf->change_buffering) {
 
         if (h->value.len == 2) {
             c0 = ngx_tolower(h->value.data[0]);
             c1 = ngx_tolower(h->value.data[1]);
 
             if (c0 == 'n' && c1 == 'o') {
-                r->upstream->buffering = 0;
+                u->buffering = 0;
             }
 
         } else if (h->value.len == 3) {
@@ -3301,7 +3320,7 @@ ngx_http_upstream_process_buffering(ngx_
             c2 = ngx_tolower(h->value.data[2]);
 
             if (c0 == 'y' && c1 == 'e' && c2 == 's') {
-                r->upstream->buffering = 1;
+                u->buffering = 1;
             }
         }
     }
@@ -3314,6 +3333,10 @@ static ngx_int_t
 ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
+    if (r->upstream->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) {
+        return NGX_OK;
+    }
+
     r->headers_out.override_charset = &h->value;
 
     return NGX_OK;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -44,6 +44,9 @@
 #define NGX_HTTP_UPSTREAM_IGN_EXPIRES        0x00000008
 #define NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL  0x00000010
 #define NGX_HTTP_UPSTREAM_IGN_SET_COOKIE     0x00000020
+#define NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE  0x00000040
+#define NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING   0x00000080
+#define NGX_HTTP_UPSTREAM_IGN_XA_CHARSET     0x00000100
 
 
 typedef struct {
diff --git a/src/os/unix/ngx_errno.c b/src/os/unix/ngx_errno.c
--- a/src/os/unix/ngx_errno.c
+++ b/src/os/unix/ngx_errno.c
@@ -12,7 +12,7 @@
  * The strerror() messages are copied because:
  *
  * 1) strerror() and strerror_r() functions are not Async-Signal-Safe,
- *    therefore, they can not be used in signal handlers;
+ *    therefore, they cannot be used in signal handlers;
  *
  * 2) a direct sys_errlist[] array may be used instead of these functions,
  *    but Linux linker warns about its usage:
diff --git a/src/os/unix/ngx_file_aio_read.c b/src/os/unix/ngx_file_aio_read.c
--- a/src/os/unix/ngx_file_aio_read.c
+++ b/src/os/unix/ngx_file_aio_read.c
@@ -23,7 +23,7 @@
  *    kqueue EVFILT_AIO filter is level triggered only: an event repeats
  *    until aio_return() will be called;
  *
- *    aio_cancel() can not cancel file AIO: it returns AIO_NOTCANCELED always.
+ *    aio_cancel() cannot cancel file AIO: it returns AIO_NOTCANCELED always.
  */
 
 
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
@@ -92,11 +92,6 @@ typedef struct aiocb  ngx_aiocb_t;
 #define NGX_LISTEN_BACKLOG        -1
 
 
-#if (defined SO_ACCEPTFILTER && !defined NGX_HAVE_DEFERRED_ACCEPT)
-#define NGX_HAVE_DEFERRED_ACCEPT  1
-#endif
-
-
 #if (__FreeBSD_version < 430000 || __FreeBSD_version < 500012)
 
 pid_t rfork_thread(int flags, void *stack, int (*func)(void *arg), void *arg);
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -11,7 +11,7 @@
 
 /*
  * Although FreeBSD sendfile() allows to pass a header and a trailer,
- * it can not send a header with a part of the file in one packet until
+ * it cannot send a header with a part of the file in one packet until
  * FreeBSD 5.3.  Besides, over the fast ethernet connection sendfile()
  * may send the partially filled packets, i.e. the 8 file pages may be sent
  * as the 11 full 1460-bytes packets, then one incomplete 324-bytes packet,
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
@@ -96,11 +96,6 @@ typedef struct iocb  ngx_aiocb_t;
 #define NGX_LISTEN_BACKLOG        511
 
 
-#if defined TCP_DEFER_ACCEPT && !defined NGX_HAVE_DEFERRED_ACCEPT
-#define NGX_HAVE_DEFERRED_ACCEPT  1
-#endif
-
-
 #ifndef NGX_HAVE_SO_SNDLOWAT
 /* setsockopt(SO_SNDLOWAT) returns ENOPROTOOPT */
 #define NGX_HAVE_SO_SNDLOWAT         0
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -339,8 +339,10 @@ ngx_signal_handler(int signo)
             break;
 
         case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
-            ngx_noaccept = 1;
-            action = ", stop accepting connections";
+            if (ngx_daemonized) {
+                ngx_noaccept = 1;
+                action = ", stop accepting connections";
+            }
             break;
 
         case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
@@ -392,6 +394,9 @@ ngx_signal_handler(int signo)
         switch (signo) {
 
         case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
+            if (!ngx_daemonized) {
+                break;
+            }
             ngx_debug_quit = 1;
         case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
             ngx_quit = 1;
@@ -536,7 +541,7 @@ ngx_process_get_status(void)
         if (WEXITSTATUS(status) == 2 && ngx_processes[i].respawn) {
             ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
                           "%s %P exited with fatal code %d "
-                          "and can not be respawn",
+                          "and cannot be respawned",
                           process, pid, WEXITSTATUS(status));
             ngx_processes[i].respawn = 0;
         }
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -620,7 +620,8 @@ ngx_reap_children(ngx_cycle_t *cycle)
                     == NGX_INVALID_PID)
                 {
                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                                  "can not respawn %s", ngx_processes[i].name);
+                                  "could not respawn %s",
+                                  ngx_processes[i].name);
                     continue;
                 }