# HG changeset patch # User Igor Sysoev # Date 1141995112 0 # Node ID 7a16e281c01f1c7ab3b79c64b43ddb754ea7935e # Parent 47f8a854752e7d2382e402556f14a5268883bd40 nginx-0.3.31-RELEASE import *) Change: now nginx passes the malformed proxied backend responses. *) Feature: the "listen" directives support the address in the "*:port" form. *) Feature: the EVFILER_TIMER support in MacOSX 10.4. *) Workaround: for MacOSX 64-bit kernel kqueue millisecond timeout bug. Thanks to Andrei Nigmatulin. *) Bugfix: if there were several "listen" directives listening one various addresses inside one server, then server names like "*.domain.tld" worked for first address only; the bug had appeared in 0.3.18. *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive and the request body was in temporarily file then the request was not transferred. *) Bugfix: perl 5.8.8 compatibility. diff --git a/auto/feature b/auto/feature --- a/auto/feature +++ b/auto/feature @@ -39,29 +39,46 @@ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>& if [ -x $NGX_AUTOTEST ]; then - if [ $ngx_feature_run = yes ]; then + case "$ngx_feature_run" in + + yes) + if $NGX_AUTOTEST 2>&1 > /dev/null; then + echo " found" + ngx_found=yes - if $NGX_AUTOTEST 2>&1 > /dev/null; then - echo " found" - ngx_found=yes + if test -n "$ngx_feature_name"; then + have=$ngx_have_feature . auto/have + fi - if test -n "$ngx_feature_name"; then - have=$ngx_have_feature . auto/have - fi + else + echo " found but is not working" + fi + ;; + + bug) + if $NGX_AUTOTEST 2>&1 > /dev/null; then + echo " not found" - else - echo " found but is not working" - fi + else + echo " found" + ngx_found=yes + + if test -n "$ngx_feature_name"; then + have=$ngx_have_feature . auto/have + fi + fi + ;; - else - echo " found" - ngx_found=yes + *) + echo " found" + ngx_found=yes - if test -n "$ngx_feature_name"; then - have=$ngx_have_feature . auto/have - fi + if test -n "$ngx_feature_name"; then + have=$ngx_have_feature . auto/have + fi + ;; - fi + esac else echo " not found" diff --git a/auto/os/features b/auto/os/features --- a/auto/os/features +++ b/auto/os/features @@ -87,13 +87,88 @@ if test -z "$NGX_KQUEUE_CHECKED"; then ngx_feature_test="struct kevent kev; kev.fflags = NOTE_LOWAT;" . auto/feature + + + ngx_feature="kqueue's EVFILT_TIMER" + ngx_feature_name="NGX_HAVE_TIMER_EVENT" + ngx_feature_run=yes + ngx_feature_incs="#include +#include " + ngx_feature_libs= + ngx_feature_test="int kq; + struct kevent kev; + struct timespec ts; + + if ((kq = kqueue()) == -1) return 1; + + kev.ident = 0; + kev.filter = EVFILT_TIMER; + kev.flags = EV_ADD|EV_ENABLE; + kev.fflags = 0; + kev.data = 1000; + kev.udata = 0; + + ts.tv_sec = 0; + ts.tv_nsec = 0; + + if (kevent(kq, &kev, 1, &kev, 1, &ts) == -1) return 1; + + if (kev.flags & EV_ERROR) return 1;" + + . auto/feature + + + if [ "$NGX_SYSTEM" = "Darwin" ]; then + + ngx_feature="MacOSX 64-bit kqueue millisecond timeout bug" + ngx_feature_name= + ngx_feature_run=bug + ngx_feature_incs="#include +#include " + ngx_feature_libs= + ngx_feature_test="int kq; + struct kevent kev; + struct timespec ts; + struct timeval tv, tv0; + + kq = kqueue(); + + ts.tv_sec = 0; + ts.tv_nsec = 999000000; + + gettimeofday(&tv, 0); + kevent(kq, NULL, 0, &kev, 1, &ts); + gettimeofday(&tv0, 0); + timersub(&tv0, &tv, &tv); + + if (tv.tv_sec * 1000000 + tv.tv_usec < 900000) return 1;" + + . auto/feature + + ngx_macosx_kevent_bug=$ngx_found + fi fi fi -if [ "$NGX_SYSTEM" = "NetBSD" ]; then + +if [ ".$ngx_macosx_kevent_bug" = .yes ]; then + + cat << END >> $NGX_AUTO_CONFIG_H + +#define NGX_MACOSX_KEVENT_BUG_SHIFT << 32 + +END - have=NGX_HAVE_TIMER_EVENT . auto/have - echo " + kqueue's EVFILT_TIMER found" +else + cat << END >> $NGX_AUTO_CONFIG_H + +#define NGX_MACOSX_KEVENT_BUG_SHIFT + +END +fi + + +if [ "$NGX_SYSTEM" = "NetBSD" ]; then # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t" diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -9,6 +9,84 @@ nginx changelog + + + + +теперь nginx передаёт неверные ответы проксированного бэкенда. + + +now nginx passes the malformed proxied backend responses. + + + + + +директивы listen поддерживают адрес в виде "*:порт". + + +the "listen" directives support the address in the "*:port" form. + + + + + +поддержка EVFILER_TIMER в MacOSX 10.4. + + +the EVFILER_TIMER support in MacOSX 10.4. + + + + + +обход ошибки обработки миллисекундных таймаутов kqueue в 64-битном ядре MacOSX. +Спасибо Андрею Нигматулину. + + +for MacOSX 64-bit kernel kqueue millisecond timeout bug. +Thanks Andrei Nigmatulin. + + + + + +если внутри одного сервера описаны несколько директив listen, слушающих на +разных адресах, то имена серверов вида "*.domain.tld" работали только +для первого адреса; +ошибка появилась в 0.3.18. + + +if there were several "listen" directives listening one various addresses +inside one server, then server names like "*.domain.tld" worked for first +address only; +bug appeared in 0.3.18. + + + + + +при использовании протокола HTTPS в директиве proxy_pass не передавались +запросы с телом, записанным во временный файл. + + +if the HTTP protocol was used in the "proxy_pass" directive and +the request body was in temporarily file then the request was not transferred. + + + + + +совместимость с perl 5.8.8. + + +perl 5.8.8 compatibility. + + + + + + @@ -32,10 +110,12 @@ the ngx_http_ssi_filter_module. -nginx не собирался на i386 платформе, если использовался PIC. - - -nginx could not be built on i386 platform, if the PIC was used. +nginx не собирался на i386 платформе, если использовался PIC; +ошибка появилась в 0.3.27. + + +nginx could not be built on i386 platform, if the PIC was used; +bug appeared in 0.3.27. @@ -225,7 +305,7 @@ directive. if the HTTP protocol was used in the "proxy_pass" directive then -the requests with the body did not transferred. +the requests with the body was not transferred. diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.30" +#define NGINX_VER "nginx/0.3.31" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c --- a/src/core/ngx_hash.c +++ b/src/core/ngx_hash.c @@ -741,10 +741,10 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t ngx_uint_t flags) { size_t len; + u_char *reverse; ngx_str_t *name; ngx_uint_t i, k, n, skip; ngx_hash_key_t *hk; - u_char buf[2048]; if (!(flags & NGX_HASH_WILDCARD_KEY)) { @@ -863,14 +863,19 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t * and ".example.com" to "com.example\0" */ + reverse = ngx_palloc(ha->temp_pool, key->len); + if (reverse == NULL) { + return NGX_ERROR; + } + len = 0; n = 0; for (i = key->len - 1; i; i--) { if (key->data[i] == '.') { - ngx_memcpy(&buf[n], &key->data[i + 1], len); + ngx_memcpy(&reverse[n], &key->data[i + 1], len); n += len; - buf[n++] = '.'; + reverse[n++] = '.'; len = 0; continue; } @@ -879,11 +884,22 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t } if (len) { - ngx_memcpy(&buf[n], &key->data[1], len); + ngx_memcpy(&reverse[n], &key->data[1], len); n += len; } - buf[n] = '\0'; + reverse[n] = '\0'; + + + hk = ngx_array_push(&ha->dns_wildcards); + if (hk == NULL) { + return NGX_ERROR; + } + + hk->key.len = key->len - 1; + hk->key.data = reverse; + hk->key_hash = 0; + hk->value = value; /* check conflicts in wildcard hash */ @@ -922,20 +938,8 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t if (name->data == NULL) { return NGX_ERROR; } + ngx_memcpy(name->data, key->data + skip, name->len); - - - ngx_memcpy(key->data, buf, key->len); - key->len--; - - hk = ngx_array_push(&ha->dns_wildcards); - if (hk == NULL) { - return NGX_ERROR; - } - - hk->key = *key; - hk->key_hash = 0; - hk->value = value; } return NGX_OK; diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -490,8 +490,17 @@ ngx_kqueue_process_events(ngx_cycle_t *c tp = NULL; } else { + + /* + * 64-bit MacOSX kernel has the bug: kernel level ts.tv_nsec is + * the int32_t while user level ts.tv_nsec is the long (64-bit), + * so on the big endian PowerPC all nanoseconds are lost. + * NGX_MACOSX_KEVENT_BUG_SHIFT on these machines is "<< 32". + */ + ts.tv_sec = timer / 1000; - ts.tv_nsec = (timer % 1000) * 1000000; + ts.tv_nsec = (long) ((timer % 1000) * 1000000) + NGX_MACOSX_KEVENT_BUG_SHIFT; tp = &ts; } diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -1043,8 +1043,7 @@ ngx_http_fastcgi_process_header(ngx_http /* there was error while a header line parsing */ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - ngx_http_upstream_header_errors[rc - - NGX_HTTP_PARSE_HEADER_ERROR]); + "upstream sent invalid header"); return NGX_HTTP_UPSTREAM_INVALID_HEADER; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -800,9 +800,11 @@ ngx_http_proxy_process_status_line(ngx_h ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent no valid HTTP/1.0 header"); +#if 0 if (u->accel) { return NGX_HTTP_UPSTREAM_INVALID_HEADER; } +#endif r->http_version = NGX_HTTP_VERSION_9; p->status = NGX_HTTP_OK; @@ -961,6 +963,10 @@ ngx_http_proxy_parse_status_line(ngx_htt /* HTTP status code */ case sw_status: + if (ch == ' ') { + break; + } + if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; } @@ -1111,8 +1117,7 @@ ngx_http_proxy_process_header(ngx_http_r /* there was error while a header line parsing */ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - ngx_http_upstream_header_errors[rc - - NGX_HTTP_PARSE_HEADER_ERROR]); + "upstream sent invalid header"); return NGX_HTTP_UPSTREAM_INVALID_HEADER; } diff --git a/src/http/modules/perl/Makefile.PL b/src/http/modules/perl/Makefile.PL --- a/src/http/modules/perl/Makefile.PL +++ b/src/http/modules/perl/Makefile.PL @@ -13,6 +13,7 @@ WriteMakefile( AUTHOR => 'Igor Sysoev', CCFLAGS => "$ENV{NGX_PERL_CFLAGS}", + OPTIMIZE => '-O', INC => "-I ../../../../../src/core " . "-I ../../../../../src/event " . diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -632,7 +632,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt "call_sv: %d", status); } else { - line = POPpx; + line = SvPVx(POPs, n_a); rv->len = n_a; rv->data = ngx_palloc(r->pool, n_a); 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 @@ -563,6 +563,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma virtual_names: + ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t)); + ha.temp_pool = ngx_create_pool(16384, cf->log); if (ha.temp_pool == NULL) { return NGX_CONF_ERROR; @@ -578,6 +580,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma name = in_addr[a].names.elts; for (s = 0; s < in_addr[a].names.nelts; s++) { + ngx_log_error(NGX_LOG_ALERT, cf->log, 0, + "server name \"%V\"", &name[s].name); + ch = name[s].name.data[0]; if (ch == '*' || ch == '.') { @@ -600,6 +605,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma for (s = 0; s < in_addr[a].names.nelts; s++) { + ngx_log_error(NGX_LOG_ALERT, cf->log, 0, + "wildcard server name \"%V\"", &name[s].name); + ch = name[s].name.data[0]; if (ch != '*' && ch != '.') { 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 @@ -2243,6 +2243,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx ls->conf.rcvbuf = -1; ls->conf.sndbuf = -1; + if (inet_upstream.host.len == 1 && inet_upstream.host.data[0] == '*') { + inet_upstream.host.len = 0; + } + if (inet_upstream.host.len) { inet_upstream.host.data[inet_upstream.host.len] = '\0'; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -37,7 +37,6 @@ #define NGX_HTTP_PARSE_INVALID_REQUEST 11 #define NGX_HTTP_PARSE_INVALID_09_METHOD 12 -#define NGX_HTTP_PARSE_HEADER_ERROR 13 #define NGX_HTTP_PARSE_INVALID_HEADER 13 #define NGX_HTTP_ZERO_IN_URI 1 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 @@ -259,12 +259,6 @@ static ngx_http_variable_t ngx_http_ups }; -char *ngx_http_upstream_header_errors[] = { - "upstream sent invalid header", - "upstream sent too long header line" -}; - - void ngx_http_upstream_init(ngx_http_request_t *r) { @@ -624,6 +618,7 @@ ngx_http_upstream_ssl_init_connection(ng } c->sendfile = 0; + u->output.sendfile = 0; peer = &u->peer.peers->peer[u->peer.cur_peer]; 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 @@ -199,7 +199,5 @@ void ngx_http_upstream_init(ngx_http_req extern ngx_module_t ngx_http_upstream_module; -extern char *ngx_http_upstream_header_errors[]; - #endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */ diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c --- a/src/imap/ngx_imap_core_module.c +++ b/src/imap/ngx_imap_core_module.c @@ -442,6 +442,10 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx return NGX_CONF_ERROR; } + if (inet_upstream.host.len == 1 && inet_upstream.host.data[0] == '*') { + inet_upstream.host.len = 0; + } + if (inet_upstream.host.len) { inet_upstream.host.data[inet_upstream.host.len] = '\0';