# HG changeset patch # User Igor Sysoev # Date 1196629200 -10800 # Node ID 583decdb82a458bd5dd2e11c8accbb6ca30c6bd6 # Parent 4a470d9e2ea5af2901962c73fba2318880735d5e nginx 0.6.21 *) Change: if variable values used in a "proxy_pass" directive contain IP-addresses only, then a "resolver" directive is not mandatory. resolver *) Bugfix: a segmentation fault might occur in worker process if a "proxy_pass" directive with URI-part was used; bug appeared in 0.6.19. *) Bugfix: if resolver was used on platform that does not support kqueue, then nginx issued an alert "name is out of response". Thanks to Andrei Nigmatulin. *) Bugfix: if the $server_protocol was used in FastCGI parameters and a request line length was near to the "client_header_buffer_size" directive value, then nginx issued an alert "fastcgi: the request record is too big". *) Bugfix: if a plain text HTTP/0.9 version request was made to HTTPS server, then nginx returned usual response. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,27 @@ +Changes with nginx 0.6.21 03 Dec 2007 + + *) Change: if variable values used in a "proxy_pass" directive contain + IP-addresses only, then a "resolver" directive is not mandatory. + resolver + + *) Bugfix: a segmentation fault might occur in worker process if a + "proxy_pass" directive with URI-part was used; bug appeared in + 0.6.19. + + *) Bugfix: if resolver was used on platform that does not support + kqueue, then nginx issued an alert "name is out of response". + Thanks to Andrei Nigmatulin. + + *) Bugfix: if the $server_protocol was used in FastCGI parameters and a + request line length was near to the "client_header_buffer_size" + directive value, then nginx issued an alert "fastcgi: the request + record is too big". + + *) Bugfix: if a plain text HTTP/0.9 version request was made to HTTPS + server, then nginx returned usual response. + + Changes with nginx 0.6.20 28 Nov 2007 *) Bugfix: a segmentation fault might occur in worker process if a @@ -372,185 +395,6 @@ Changes with nginx 0.6.0 support the "www.example.*" wildcards. -Changes with nginx 0.5.33 07 Nov 2007 - - *) Change: now by default the "echo" SSI command uses entity encoding. - - *) Feature: the "encoding" parameter in the "echo" SSI command. - - *) Change: mail proxy was split on three modules: pop3, imap and smtp. - - *) Feature: the --without-mail_pop3_module, --without-mail_imap_module, - and --without-mail_smtp_module configuration parameters. - - *) Feature: the "smtp_greeting_delay" and "smtp_client_buffer" - directives of the ngx_mail_smtp_module. - - *) Feature: the "server_name" and "valid_referers" directives support - regular expressions. - - *) Feature: the "server_name", "map", and "valid_referers" directives - support the "www.example.*" wildcards. - - *) Bugfix: sub_filter did not work with empty substitution. - - *) Bugfix: in sub_filter parsing. - - *) Bugfix: a worker process may got caught in an endless loop, if the - memcached was used. - - *) Bugfix: nginx supported low case only "close" and "keep-alive" - values in the "Connection" request header line; bug appeared in - 0.5.32. - - *) Bugfix: nginx could not start on Solaris if the shared PCRE library - located in non-standard place was used. - - -Changes with nginx 0.5.32 24 Sep 2007 - - *) Change: now nginx tries to set the "worker_priority", - "worker_rlimit_nofile", "worker_rlimit_core", and - "worker_rlimit_sigpending" without super-user privileges. - - *) Change: now nginx escapes space and "%" in request to a mail proxy - authentication server. - - *) Change: now nginx escapes "%" in $memcached_key variable. - - *) Change: the special make target "upgrade1" was defined for online - upgrade of 0.1.x versions. - - *) Feature: the "add_header Last-Modified ..." directive changes the - "Last-Modified" response header line. - - *) Feature: the mail proxy supports AUTHENTICATE in IMAP mode. - Thanks to Maxim Dounin. - - *) Feature: the mail proxy supports STARTTLS in SMTP mode. - Thanks to Maxim Dounin. - - *) Bugfix: nginx did not close directory file on HEAD request if - autoindex was used. - Thanks to Arkadiusz Patyk. - - *) Bugfix: the "proxy_hide_header" and "fastcgi_hide_header" directives - did not hide response header lines whose name was longer than 32 - characters. - Thanks to Manlio Perillo. - - *) Bugfix: active connection counter always increased if mail proxy was - used. - - *) Bugfix: if backend returned response header only using non-buffered - proxy, then nginx closed backend connection on timeout. - - *) Bugfix: nginx did not support several "Connection" request header - lines. - - *) Bugfix: a charset set by the "charset" directive was not appended to - the "Content-Type" header set by $r->send_http_header(). - - *) Bugfix: a segmentation fault might occur in worker process if - /dev/poll method was used. - - *) Bugfix: nginx did not work on FreeBSD/sparc64. - - *) Bugfix: a segmentation fault occurred in worker process if invalid - address was set in the "auth_http" directive. - - *) Bugfix: now nginx uses default listen backlog value 511 on all - platforms except FreeBSD. - Thanks to Jiang Hong. - - *) Bugfix: now Solaris sendfilev() is not used to transfer the client - request body to FastCGI-server via the unix domain socket. - - *) Bugfix: if the same host without specified port was used as backend - for HTTP and HTTPS, then nginx used only one port - 80 or 443. - - *) Bugfix: the "proxy_ignore_client_abort" and - "fastcgi_ignore_client_abort" directives did not work; bug appeared - in 0.5.13. - - -Changes with nginx 0.5.31 15 Aug 2007 - - *) Feature: named locations. - - *) Feature: the "proxy_store" and "fastcgi_store" directives. - - *) Feature: the "proxy_store_access" and "fastcgi_store_access" - directives. - - -Changes with nginx 0.5.30 30 Jul 2007 - - *) Feature: the $args variable can be set with the "set" directive. - - *) Feature: the $is_args variable. - - *) Bugfix: if a client has closed connection to mail proxy then nginx - might not close connection to backend. - - *) Bugfix: now nginx escapes space in $memcached_key variable. - - *) Bugfix: a segmentation fault might occur in worker process when the - HTTPS protocol was used in the "proxy_pass" directive. - - *) Bugfix: the perl $$ variable value in ngx_http_perl_module was equal - to the master process identification number. - - *) Bugfix: fix building on Solaris/amd64 by Sun Studio 11 and early - versions; bug appeared in 0.5.29. - - -Changes with nginx 0.5.29 23 Jul 2007 - - *) Feature: $nginx_version variable. - Thanks to Nick S. Grechukh. - - *) Bugfix: if the FastCGI header was split in records, then nginx - passed garbage in the header to a client. - - *) Bugfix: Sun Studio compatibility on Solaris/amd64 and - Solaris/sparc64. - Thanks to Jiang Hong and Andrei Nigmatulin. - - *) Bugfix: of minor potential bugs. - Thanks to Coverity's Scan. - - -Changes with nginx 0.5.28 17 Jul 2007 - - *) Security: the "msie_refresh" directive allowed XSS. - Thanks to Maxim Boguk. - - *) Bugfix: a segmentation fault might occur in worker process if the - "auth_http_header" directive was used. - Thanks to Maxim Dounin. - - *) Bugfix: a segmentation fault occurred in worker process if the - CRAM-MD5 authentication method was used, but it was not enabled. - - *) Bugfix: a segmentation fault might occur in worker process if the - eventport method was used. - - -Changes with nginx 0.5.27 09 Jul 2007 - - *) Bugfix: if remote SSI subrequest was used, then posterior local file - subrequest might transferred to client in wrong order. - - *) Bugfix: large SSI inclusions buffered in temporary files were - truncated. - - -Changes with nginx 0.5.26 17 Jun 2007 - - *) Bugfix: in SSI parsing. - - Changes with nginx 0.5.25 11 Jun 2007 *) Bugfix: nginx could not be built with the diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,27 @@ +Изменения в nginx 0.6.21 03.12.2007 + + *) Изменение: если в значениях переменных директивы proxy_pass + используются только IP-адреса, то указывать resolver не нужно. + + *) Исправление: при использовании директивы proxy_pass c URI-частью в + рабочем процессе мог произойти segmentation fault; ошибка появилась + в 0.6.19. + + *) Исправление: если resolver использовался на платформах, не + поддерживающих метод kqueue, то nginx выдавал alert "name is out of + response". + Спасибо Андрею Нигматулину. + + *) Исправление: При использовании переменной $server_protocol в + FastCGI-параметрах и запросе, длина которого была близка к значению + директивы client_header_buffer_size, nginx выдавал alert "fastcgi: + the request record is too big". + + *) Исправление: при обычном запросе версии HTTP/0.9 к HTTPS серверу + nginx возвращал обычный ответ. + + Изменения в nginx 0.6.20 28.11.2007 *) Исправление: при использовании директивы proxy_pass c URI-частью в @@ -382,193 +405,6 @@ поддерживают маски вида "www.example.*". -Изменения в nginx 0.5.33 07.11.2007 - - *) Изменение: теперь по умолчанию команда SSI echo использует - кодирование entity. - - *) Добавление: параметр encoding в команде SSI echo. - - *) Изменение: почтовый прокси-сервер разделён на три модуля: pop3, imap - и smtp. - - *) Добавление: параметры конфигурации --without-mail_pop3_module, - --without-mail_imap_module и --without-mail_smtp_module. - - *) Добавление: директивы smtp_greeting_delay и smtp_client_buffer - модуля ngx_mail_smtp_module. - - *) Добавление: директивы server_name и valid_referers поддерживают - регулярные выражения. - - *) Добавление: директивы "server_name", "map", and "valid_referers" - поддерживают маски вида "www.example.*". - - *) Исправление: sub_filter не работал с пустой строкой замены. - - *) Исправление: в парсинге sub_filter. - - *) Исправление: рабочий процесс мог зациклиться при использовании - memcached. - - *) Исправление: nginx распознавал параметры "close" и "keep-alive" в - строке "Connection" в заголовке запроса только, если они были в - нижнем регистре; ошибка появилась в 0.5.32. - - *) Исправление: при использовании разделяемой библиотеки PCRE, - расположенной в нестандартном месте, nginx не запускался на Solaris. - - -Изменения в nginx 0.5.32 24.09.2007 - - *) Изменение: теперь nginx пытается установить директивы - worker_priority, worker_rlimit_nofile, worker_rlimit_core, - worker_rlimit_sigpending без привилегий root'а. - - *) Изменение: теперь nginx экранирует символы пробела и "%" при - передаче запроса серверу аутентификации почтового прокси-сервера. - - *) Изменение: теперь nginx экранирует символ "%" в переменной - $memcached_key. - - *) Изменение: для обновления на лету версий 0.1.x создан специальный - сценарий make upgrade1. - - *) Добавление: директива "add_header Last-Modified ..." меняет строку - "Last-Modified" в заголовке ответа. - - *) Добавление: почтовый прокси-сервер поддерживает AUTHENTICATE в - режиме IMAP. - Спасибо Максиму Дунину. - - *) Добавление: почтовый прокси-сервер поддерживает STARTTLS в режиме - SMTP. - Спасибо Максиму Дунину. - - *) Исправление: nginx не закрывал файл каталога для запроса HEAD, если - использовался autoindex - Спасибо Arkadiusz Patyk. - - *) Исправление: директивы proxy_hide_header и fastcgi_hide_header не - скрывали строки заголовка ответа с именем больше 32 символов. - Спасибо Manlio Perillo. - - *) Исправление: счётчик активных соединений всегда рос при - использовании почтового прокси-сервера. - - *) Исправление: если бэкенд возвращал только заголовок ответа при - небуферизированном проксировании, то nginx закрывал соединение с - бэкендом по таймауту. - - *) Исправление: nginx не поддерживал несколько строк "Connection" в - заголовке запроса. - - *) Исправление: В строку заголовка ответа "Content-Type", указанную в - методе $r->send_http_header(), не добавлялась кодировка, указанная в - директиве charset. - - *) Исправление: при использовании метода /dev/poll в рабочем процессе - мог произойти segmentation fault. - - *) Исправление: nginx не работал на FreeBSD/sparc64. - - *) Исправление: если в директиве auth_http был задан неправильный - адрес, то в рабочем процессе происходил segmentation fault. - - *) Исправление: теперь по умолчанию nginx использует значение 511 для - listen backlog на всех платформах, кроме FreeBSD. - Спасибо Jiang Hong. - - *) Исправление: sendfilev() в Solaris теперь не используется при - передаче тела запроса FastCGI-серверу через unix domain сокет. - - *) Исправление: при использовании одного хоста в качестве бэкендов для - протоколов HTTP и HTTPS без явного указания портов, nginx - использовал только один порт - 80 или 443. - - *) Исправление: директивы proxy_ignore_client_abort и - fastcgi_ignore_client_abort не работали; ошибка появилась в 0.5.13. - - -Изменения в nginx 0.5.31 15.08.2007 - - *) Добавление: именованные location'ы. - - *) Добавление: директивы proxy_store и fastcgi_store. - - *) Добавление: директивы proxy_store_access и fastcgi_store_access. - - -Изменения в nginx 0.5.30 30.07.2007 - - *) Добавление: переменную $args можно устанавливать с помощью set. - - *) Добавление: переменная $is_args. - - *) Исправление: если клиент в почтовом прокси-сервере закрывал - соединение, то nginx мог не закрывать соединение с бэкендом. - - *) Исправление: теперь nginx экранирует пробел в переменной - $memcached_key. - - *) Исправление: при использовании протокола HTTPS в директиве - proxy_pass в рабочем процессе мог произойти segmentation fault. - - *) Исправление: значение perl'овой переменной $$ модуля - ngx_http_perl_module было равно номеру главного процесса. - - *) Исправление: nginx не собирался на Solaris/amd64 Sun Studio 11 и - более ранними версиями; ошибка появилась в 0.5.29. - - -Изменения в nginx 0.5.29 23.07.2007 - - *) Добавление: переменная $nginx_version. - Спасибо Николаю Гречуху. - - *) Исправление: если заголовок ответа был разделён в FastCGI-записях, - то nginx передавал клиенту мусор в таких заголовках. - - *) Исправление: совместимость с Sun Studio на Solaris/amd64 и - Solaris/sparc64. - Спасибо Jiang Hong и Андрею Нигматулину. - - *) Исправление: незначительных потенциальных ошибок. - Спасибо Coverity's Scan. - - -Изменения в nginx 0.5.28 17.07.2007 - - *) Безопасность: при использовании директивы msie_refresh был возможен - XSS. - Спасибо Максиму Богуку. - - *) Исправление: при использовании директивы auth_http_header в рабочем - процессе мог произойти segmentation fault. - Спасибо Максиму Дунину. - - *) Исправление: если использовался метод аутентификации CRAM-MD5, но он - не был разрешён, то в рабочем процессе происходил segmentation fault. - - *) Исправление: в рабочем процессе мог произойти segmentation fault, - если использовался метод eventport. - - -Изменения в nginx 0.5.27 09.07.2007 - - *) Исправление: при использовании удалённого подзапроса в SSI - последующий подзапрос локального файла мог отдаваться клиенту в - неверном порядке. - - *) Исправление: большие включения в SSI, сохранённые во временные - файлы, передавались не полностью. - - -Изменения в nginx 0.5.26 17.06.2007 - - *) Исправление: в парсинге SSI. - - Изменения в nginx 0.5.25 11.06.2007 *) Исправление: nginx не собирался с параметром diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -164,6 +164,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_socket.c \ src/os/unix/ngx_recv.c \ src/os/unix/ngx_readv_chain.c \ + src/os/unix/ngx_udp_recv.c \ src/os/unix/ngx_send.c \ src/os/unix/ngx_writev_chain.c \ src/os/unix/ngx_channel.c \ @@ -229,6 +230,7 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/win32/ngx_socket.c \ src/os/win32/ngx_wsarecv.c \ src/os/win32/ngx_wsarecv_chain.c \ + src/os/win32/ngx_udp_wsarecv.c \ src/os/win32/ngx_wsasend_chain.c \ src/os/win32/ngx_win32_init.c \ src/os/win32/ngx_user.c \ 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_VERSION "0.6.20" +#define NGINX_VERSION "0.6.21" #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 @@ -417,6 +417,9 @@ ngx_parse_url(ngx_pool_t *pool, ngx_url_ return NGX_ERROR; } + u->port_text.len = port_len; + u->port_text.data = port_start; + } else { port = ngx_atoi(p, len); diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h --- a/src/core/ngx_inet.h +++ b/src/core/ngx_inet.h @@ -35,6 +35,7 @@ typedef struct { ngx_str_t url; ngx_str_t host; + ngx_str_t port_text; ngx_str_t uri; in_port_t port; diff --git a/src/core/ngx_queue.h b/src/core/ngx_queue.h --- a/src/core/ngx_queue.h +++ b/src/core/ngx_queue.h @@ -20,6 +20,11 @@ struct ngx_queue_s { }; +#define ngx_queue_init(q) \ + (q)->prev = q; \ + (q)->next = q; + + #define ngx_queue_empty(h) \ (h == (h)->prev) diff --git a/src/core/ngx_rbtree.h b/src/core/ngx_rbtree.h --- a/src/core/ngx_rbtree.h +++ b/src/core/ngx_rbtree.h @@ -40,6 +40,13 @@ struct ngx_rbtree_s { }; +#define ngx_rbtree_init(tree, s, i) \ + ngx_rbtree_sentinel_init(s); \ + (tree)->root = s; \ + (tree)->sentinel = s; \ + (tree)->insert = i + + void ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree, ngx_rbtree_node_t *node); void ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree, 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 @@ -99,47 +99,28 @@ ngx_resolver_create(ngx_peer_addr_t *add return NULL; } - uc = ngx_calloc(sizeof(ngx_udp_connection_t), log); - if (uc == NULL) { - return NULL; - } - r->event = ngx_calloc(sizeof(ngx_event_t), log); if (r->event == NULL) { return NULL; } - ngx_rbtree_sentinel_init(&r->name_sentinel); - - r->name_rbtree.root = &r->name_sentinel; - r->name_rbtree.sentinel = &r->name_sentinel; - r->name_rbtree.insert = ngx_resolver_rbtree_insert_value; - - ngx_rbtree_sentinel_init(&r->addr_sentinel); - - r->addr_rbtree.root = &r->addr_sentinel; - r->addr_rbtree.sentinel = &r->addr_sentinel; - r->addr_rbtree.insert = ngx_rbtree_insert_value; - - r->name_resend_queue.prev = &r->name_resend_queue; - r->name_resend_queue.next = &r->name_resend_queue; - - r->addr_resend_queue.prev = &r->addr_resend_queue; - r->addr_resend_queue.next = &r->addr_resend_queue; - - r->name_expire_queue.prev = &r->name_expire_queue; - r->name_expire_queue.next = &r->name_expire_queue; - - r->addr_expire_queue.prev = &r->addr_expire_queue; - r->addr_expire_queue.next = &r->addr_expire_queue; + ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, + ngx_resolver_rbtree_insert_value); + + ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel, + ngx_rbtree_insert_value); + + ngx_queue_init(&r->name_resend_queue); + ngx_queue_init(&r->addr_resend_queue); + + ngx_queue_init(&r->name_expire_queue); + ngx_queue_init(&r->addr_expire_queue); r->event->handler = ngx_resolver_resend_handler; r->event->data = r; r->event->log = log; r->ident = -1; - r->udp_connection = uc; - r->resend_timeout = 5; r->expire = 30; r->valid = 300; @@ -147,10 +128,19 @@ ngx_resolver_create(ngx_peer_addr_t *add r->log = log; r->log_level = NGX_LOG_ALERT; - uc->sockaddr = addr->sockaddr; - uc->socklen = addr->socklen; - uc->server = addr->name; - uc->log = log; + if (addr) { + uc = ngx_calloc(sizeof(ngx_udp_connection_t), log); + if (uc == NULL) { + return NULL; + } + + r->udp_connection = uc; + + uc->sockaddr = addr->sockaddr; + uc->socklen = addr->socklen; + uc->server = addr->name; + uc->log = log; + } return r; } @@ -177,6 +167,10 @@ ngx_resolve_start(ngx_resolver_t *r, ngx } } + if (r->udp_connection == NULL) { + return NGX_NO_RESOLVER; + } + ctx = ngx_resolver_calloc(r, sizeof(ngx_resolver_ctx_t)); if (ctx) { @@ -748,7 +742,7 @@ ngx_resolver_resend_handler(ngx_event_t /* lock addr mutex */ atimer = ngx_resolver_resend(r, &r->addr_rbtree, &r->addr_resend_queue); - + /* unlock addr mutex */ if (ntimer == 0) { @@ -832,9 +826,9 @@ ngx_resolver_read_response(ngx_event_t * c = rev->data; do { - n = ngx_recv(c, buf, NGX_RESOLVER_UDP_SIZE); - - if (n == -1) { + n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE); + + if (n < 0) { return; } 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 @@ -26,6 +26,9 @@ #define NGX_RESOLVE_TIMEDOUT NGX_ETIMEDOUT +#define NGX_NO_RESOLVER (void *) -1 + + typedef struct { ngx_connection_t *connection; struct sockaddr *sockaddr; diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c --- a/src/event/modules/ngx_aio_module.c +++ b/src/event/modules/ngx_aio_module.c @@ -28,6 +28,7 @@ static ngx_int_t ngx_aio_process_events( ngx_os_io_t ngx_os_aio = { ngx_aio_read, ngx_aio_read_chain, + NULL, ngx_aio_write, ngx_aio_write_chain, 0 diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -429,6 +429,7 @@ extern ngx_os_io_t ngx_io; #define ngx_recv ngx_io.recv #define ngx_recv_chain ngx_io.recv_chain +#define ngx_udp_recv ngx_io.udp_recv #define ngx_send ngx_io.send #define ngx_send_chain ngx_io.send_chain 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 @@ -553,7 +553,7 @@ ngx_http_fastcgi_create_request(ngx_http if (len > 65535) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "fastcgi: the request record is too big"); + "fastcgi request record is too big: %uz", len); return NGX_ERROR; } 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 @@ -675,7 +675,8 @@ ngx_http_proxy_create_request(ngx_http_r r->uri.len - loc_len, NGX_ESCAPE_URI); } - len += r->uri.len - loc_len + escape + sizeof("?") - 1 + r->args.len; + len += ctx->vars.uri.len + r->uri.len - loc_len + escape + + sizeof("?") - 1 + r->args.len; } ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes); @@ -2323,7 +2324,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_ sc.variables = n; sc.complete_lengths = 1; sc.complete_values = 1; - + if (ngx_http_script_compile(&sc) != NGX_OK) { return NGX_CONF_ERROR; } @@ -2645,8 +2646,6 @@ static ngx_int_t ngx_http_proxy_set_vars(ngx_pool_t *pool, ngx_url_t *u, ngx_http_proxy_vars_t *v) { - u_char *p; - if (!u->unix_socket) { if (u->no_port || u->port == u->default_port) { v->host_header = u->host; @@ -2661,16 +2660,9 @@ ngx_http_proxy_set_vars(ngx_pool_t *pool } } else { - p = ngx_palloc(pool, u->host.len + sizeof(":65536") - 1); - if (p == NULL) { - return NGX_ERROR; - } - - v->host_header.len = ngx_sprintf(p, "%V:%d", &u->host, u->port) - p; - v->host_header.data = p; - - v->port.len = v->host_header.len - u->host.len - 1; - v->port.data = p + u->host.len + 1; + v->host_header.len = u->host.len + 1 + u->port_text.len; + v->host_header.data = u->host.data; + v->port = u->port_text; } } else { 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 @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.6.20'; +our $VERSION = '0.6.21'; 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 @@ -69,7 +69,7 @@ static char *ngx_http_core_keepalive(ngx void *conf); static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char * ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, +static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); @@ -2594,6 +2594,13 @@ ngx_http_core_merge_loc_conf(ngx_conf_t if (conf->resolver == NULL) { conf->resolver = prev->resolver; + + if (conf->resolver == NULL) { + conf->resolver = ngx_resolver_create(NULL, cf->cycle->new_log); + if (conf->resolver == NULL) { + return NGX_OK; + } + } } ngx_conf_merge_path_value(conf->client_body_temp_path, @@ -3393,6 +3400,8 @@ 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; 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 @@ -1154,6 +1154,10 @@ ngx_http_alloc_large_header_buffer(ngx_h r->args_start = new + (r->args_start - old); } + if (r->http_protocol.data) { + r->http_protocol.data = new + (r->http_protocol.data - old); + } + } else { r->header_name_start = new; r->header_name_end = new + (r->header_name_end - old); @@ -1335,13 +1339,6 @@ ngx_http_process_request_header(ngx_http return NGX_ERROR; } - if (r->plain_http) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent plain HTTP request to HTTPS port"); - ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); - return NGX_ERROR; - } - if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) { if (r->headers_in.keep_alive) { r->headers_in.keep_alive_n = @@ -1409,6 +1406,13 @@ ngx_http_process_request(ngx_http_reques c = r->connection; + if (r->plain_http) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent plain HTTP request to HTTPS port"); + ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); + return; + } + #if (NGX_HTTP_SSL) if (c->ssl) { 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 @@ -307,7 +307,7 @@ static ngx_str_t ngx_http_error_pages[] ngx_string(ngx_http_error_495_page), /* 495, https certificate error */ ngx_string(ngx_http_error_496_page), /* 496, https no certificate */ ngx_string(ngx_http_error_497_page), /* 497, http to https */ - ngx_string(ngx_http_error_404_page), /* 498, invalid host name */ + ngx_string(ngx_http_error_404_page), /* 498, canceled */ ngx_null_string, /* 499, client has closed connection */ ngx_string(ngx_http_error_500_page), 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 @@ -398,13 +398,6 @@ ngx_http_upstream_init(ngx_http_request_ } } - if (clcf->resolver == NULL) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no resolver defined to resolve %V", host); - ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); - return; - } - temp.name = *host; ctx = ngx_resolve_start(clcf->resolver, &temp); @@ -413,6 +406,14 @@ ngx_http_upstream_init(ngx_http_request_ return; } + if (ctx == NGX_NO_RESOLVER) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "no resolver defined to resolve %V", host); + + ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); + return; + } + ctx->name = *host; ctx->type = NGX_RESOLVE_A; ctx->handler = ngx_http_upstream_resolve_handler; diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -102,7 +102,7 @@ typedef enum { ngx_pop3_auth_login_password, ngx_pop3_auth_plain, ngx_pop3_auth_cram_md5 -} ngx_po3_state_e; +} ngx_pop3_state_e; typedef enum { 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 @@ -30,6 +30,7 @@ ngx_uint_t ngx_freebsd_use_tcp_nopush; static ngx_os_io_t ngx_freebsd_io = { ngx_unix_recv, ngx_readv_chain, + ngx_udp_unix_recv, ngx_unix_send, #if (NGX_HAVE_SENDFILE) ngx_freebsd_sendfile_chain, diff --git a/src/os/unix/ngx_linux_init.c b/src/os/unix/ngx_linux_init.c --- a/src/os/unix/ngx_linux_init.c +++ b/src/os/unix/ngx_linux_init.c @@ -17,6 +17,7 @@ int ngx_linux_rtsig_max; static ngx_os_io_t ngx_linux_io = { ngx_unix_recv, ngx_readv_chain, + ngx_udp_unix_recv, ngx_unix_send, #if (NGX_HAVE_SENDFILE) ngx_linux_sendfile_chain, 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 @@ -25,6 +25,7 @@ typedef ngx_chain_t *(*ngx_send_chain_pt typedef struct { ngx_recv_pt recv; ngx_recv_chain_pt recv_chain; + ngx_recv_pt udp_recv; ngx_send_pt send; ngx_send_chain_pt send_chain; ngx_uint_t flags; @@ -41,6 +42,7 @@ ngx_int_t ngx_daemon(ngx_log_t *log); ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size); ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry); +ssize_t ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size); ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size); ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -21,6 +21,7 @@ struct rlimit rlmt; ngx_os_io_t ngx_os_io = { ngx_unix_recv, ngx_readv_chain, + ngx_udp_unix_recv, NULL, ngx_writev_chain, 0 diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -11,7 +11,8 @@ #if (NGX_HAVE_KQUEUE) -ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) +ssize_t +ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; @@ -77,12 +78,6 @@ ssize_t ngx_unix_recv(ngx_connection_t * * even if kqueue reported about available data */ -#if 0 - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "recv() returned 0 while kevent() reported " - "%d available bytes", rev->available); -#endif - rev->eof = 1; rev->available = 0; } @@ -126,7 +121,8 @@ ssize_t ngx_unix_recv(ngx_connection_t * #else /* ! NGX_HAVE_KQUEUE */ -ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) +ssize_t +ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; diff --git a/src/os/unix/ngx_send.c b/src/os/unix/ngx_send.c --- a/src/os/unix/ngx_send.c +++ b/src/os/unix/ngx_send.c @@ -9,7 +9,8 @@ #include -ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size) +ssize_t +ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; diff --git a/src/os/unix/ngx_solaris_init.c b/src/os/unix/ngx_solaris_init.c --- a/src/os/unix/ngx_solaris_init.c +++ b/src/os/unix/ngx_solaris_init.c @@ -16,6 +16,7 @@ char ngx_solaris_version[50]; static ngx_os_io_t ngx_solaris_io = { ngx_unix_recv, ngx_readv_chain, + ngx_udp_unix_recv, ngx_unix_send, #if (NGX_HAVE_SENDFILE) ngx_solaris_sendfilev_chain, diff --git a/src/os/unix/ngx_udp_recv.c b/src/os/unix/ngx_udp_recv.c new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_udp_recv.c @@ -0,0 +1,114 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include +#include +#include + + +#if (NGX_HAVE_KQUEUE) + +ssize_t +ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) +{ + ssize_t n; + ngx_err_t err; + ngx_event_t *rev; + + rev = c->read; + + do { + n = recv(c->fd, buf, size, 0); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "recv: fd:%d %d of %d", c->fd, n, size); + + if (n >= 0) { + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { + rev->available -= n; + + /* + * rev->available may be negative here because some additional + * bytes may be received between kevent() and recv() + */ + + if (rev->available <= 0) { + rev->ready = 0; + rev->available = 0; + } + } + + return n; + } + + err = ngx_socket_errno; + + if (err == NGX_EAGAIN || err == NGX_EINTR) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "recv() not ready"); + n = NGX_AGAIN; + + } else { + n = ngx_connection_error(c, err, "recv() failed"); + break; + } + + } while (err == NGX_EINTR); + + rev->ready = 0; + + if (n == NGX_ERROR){ + rev->error = 1; + } + + return n; +} + +#else /* ! NGX_HAVE_KQUEUE */ + +ssize_t +ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) +{ + ssize_t n; + ngx_err_t err; + ngx_event_t *rev; + + rev = c->read; + + do { + n = recv(c->fd, buf, size, 0); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "recv: fd:%d %d of %d", c->fd, n, size); + + if (n >= 0) { + return n; + } + + err = ngx_socket_errno; + + if (err == NGX_EAGAIN || err == NGX_EINTR) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "recv() not ready"); + n = NGX_AGAIN; + + } else { + n = ngx_connection_error(c, err, "recv() failed"); + break; + } + + } while (err == NGX_EINTR); + + rev->ready = 0; + + if (n == NGX_ERROR){ + rev->error = 1; + } + + return n; +} + +#endif /* NGX_HAVE_KQUEUE */