# HG changeset patch # User Igor Sysoev # Date 1106600400 -10800 # Node ID da8c190bdabaf10b77066f6e0fc0a8f67ba7a70f # Parent 1b17dd8244381c918b51aab7bedc1d3dced7bce8 nginx 0.1.16 *) Bugfix: if the response were transferred by chunks, then on the HEAD request the final chunk was issued. *) Bugfix: the "Connection: keep-alive" header were issued, even if the keepalive_timeout directive forbade the keep-alive use. *) Bugfix: the errors in the ngx_http_fastcgi_module caused the segmentation faults. *) Bugfix: the compressed response encrypted by SSL may not transferred complete. *) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK options, are not used for the unix domain sockets. *) Feature: the rewrite directive supports the arguments rewriting. *) Bugfix: the response code 400 was returned for the POST request with the "Content-Length: 0" header; bug appeared in 0.1.14. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,26 @@ + +Changes with nginx 0.1.16 25 Jan 2005 + + *) Bugfix: if the response were transferred by chunks, then on the HEAD + request the final chunk was issued. + + *) Bugfix: the "Connection: keep-alive" header were issued, even if the + keepalive_timeout derective forbade the keep-alive use. + + *) Bugfix: the errors in the ngx_http_fastcgi_module caused the + segmentation faults. + + *) Bugfix: the compressed response encrypted by SSL may not transferred + complete. + + *) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK + options, are not used for the unix domain sockets. + + *) Feature: the rewrite directive supports the agruments rewriting. + + *) Bugfix: the response code 400 was returend for the POST request with + the "Content-Length: 0" header; bug appeared in 0.1.14. + Changes with nginx 0.1.15 19 Jan 2005 @@ -13,16 +36,17 @@ Changes with nginx 0.1.15 *) Bugfix: the FastCGI's parameter REQUEST_URI is now passed with the arguments and in the original state. - *) Bugfix: the ngx_http_rewrite_module module was required to be built to - use the regular expressions in locations. + *) Bugfix: the ngx_http_rewrite_module module was required to be built + to use the regular expressions in locations. *) Bugfix: the directive "proxy_preserve_host on" adds port 80 to the - "Host" headers, if upstream listen on port 80; bug appeared in 0.1.14. + "Host" headers, if upstream listen on port 80; bug appeared in + 0.1.14. *) Bugfix: the same pathes in autoconfiguration paramters - --http-client-body-temp-path=PATH and --http-proxy-temp-path=PATH, or - --http-client-body-temp-path=PATH nad --http-fastcgi-temp-path=PATH - caused segmentation fault. + --http-client-body-temp-path=PATH and --http-proxy-temp-path=PATH, + or --http-client-body-temp-path=PATH nad + --http-fastcgi-temp-path=PATH caused segmentation fault. Changes with nginx 0.1.14 18 Jan 2005 @@ -35,10 +59,10 @@ Changes with nginx 0.1.14 request body is specified by directive client_body_temp_path, by default it is /client_body_temp. - *) Feature: the ngx_http_fastcgi_module and the directives: fastcgi_pass, - fastcgi_root, fastcgi_index, fastcgi_params, fastcgi_connect_timeout, - fastcgi_send_timeout, fastcgi_read_timeout, fastcgi_send_lowat, - fastcgi_header_buffer_size, fastcgi_buffers, + *) Feature: the ngx_http_fastcgi_module and the directives: + fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params, + fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout, + fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size, fastcgi_temp_path, fastcgi_max_temp_file_size, fastcgi_temp_file_write_size, fastcgi_next_upstream, and fastcgi_x_powered_by. @@ -51,7 +75,8 @@ Changes with nginx 0.1.14 *) Change: the %3F symbol in the URI was considered as the argument string start. - *) Feature: the unix domain sockets support in the ngx_http_proxy_module. + *) Feature: the unix domain sockets support in the + ngx_http_proxy_module. *) Feature: the ssl_engine and ssl_ciphers directives. Thanks to Sergey Skvortsov for SSL-accelerator. @@ -65,7 +90,8 @@ Changes with nginx 0.1.13 *) Bugfix: the *.domain.tld names in the server_name directive did not work. - *) Bugfix: the %request_length log parameter logged the incorrect length. + *) Bugfix: the %request_length log parameter logged the incorrect + length. Changes with nginx 0.1.12 06 Dec 2004 @@ -100,9 +126,9 @@ Changes with nginx 0.1.11 *) Bugfix: the files bigger than 4G could not be transferred using sendfile. - *) Bugfix: if the backend was resolved to several backends and there was - an error while the response waiting then process may got caught in an - endless loop. + *) Bugfix: if the backend was resolved to several backends and there + was an error while the response waiting then process may got caught + in an endless loop. *) Bugfix: the worker process may exit with the "unknown cycle" message when the /dev/poll method was used. @@ -113,28 +139,29 @@ Changes with nginx 0.1.11 *) Bugfix: the send_lowat directive did not work on Linux. - *) Bugfix: the segmentation fault occurred if there was no events section - in configuration. + *) Bugfix: the segmentation fault occurred if there was no events + section in configuration. *) Bugfix: nginx could not be built on OpenBSD. - *) Bugfix: the double slashes in "://" in the URI were converted to ":/". + *) Bugfix: the double slashes in "://" in the URI were converted to + ":/". Changes with nginx 0.1.10 26 Nov 2004 - *) Bugfix: if the request without arguments contains "//", "/./", "/../" - or "%XX" then the lost character in the request line was lost; bug - appeared in 0.1.9. + *) Bugfix: if the request without arguments contains "//", "/./", + "/../" or "%XX" then the lost character in the request line was + lost; bug appeared in 0.1.9. - *) Bugfix: the fix in 0.1.9 for the files bigger than 2G on Linux did not - work. + *) Bugfix: the fix in 0.1.9 for the files bigger than 2G on Linux did + not work. Changes with nginx 0.1.9 25 Nov 2004 - *) Bugfix: the proxied request was sent without arguments if the request - contains "//", "/./", "/../" or "%XX". + *) Bugfix: the proxied request was sent without arguments if the + request contains "//", "/./", "/../" or "%XX". *) Bugfix: the large compressed responses may be transferred not completely. @@ -142,8 +169,8 @@ Changes with nginx 0.1.9 *) Bugfix: the files bigger than 2G was not transferred on Linux that does not support sendfile64(). - *) Bugfix: while the build configuration on Linux the --with-poll_module - parameter was required; bug appeared in 0.1.8. + *) Bugfix: while the build configuration on Linux the + --with-poll_module parameter was required; bug appeared in 0.1.8. Changes with nginx 0.1.8 20 Nov 2004 @@ -158,8 +185,8 @@ Changes with nginx 0.1.8 Changes with nginx 0.1.7 12 Nov 2004 - *) Bugfix: on FreeBSD the segmentation fault may occur if the size of the - transferred file was changed; bug appeared in 0.1.5. + *) Bugfix: on FreeBSD the segmentation fault may occur if the size of + the transferred file was changed; bug appeared in 0.1.5. Changes with nginx 0.1.6 11 Nov 2004 @@ -170,14 +197,16 @@ Changes with nginx 0.1.6 Changes with nginx 0.1.5 11 Nov 2004 - *) Bugfix: on Solaris and Linux there may be too many "recvmsg() returned - not enough data" alerts. + *) Bugfix: on Solaris and Linux there may be too many "recvmsg() + returned not enough data" alerts. - *) Bugfix: there were the "writev() failed (22: Invalid argument)" errors - on Solaris in proxy mode without sendfile. On other platforms that do - not support sendfile at all the process got caught in an endless loop. + *) Bugfix: there were the "writev() failed (22: Invalid argument)" + errors on Solaris in proxy mode without sendfile. On other platforms + that do not support sendfile at all the process got caught in an + endless loop. - *) Bugfix: segmentation fault on Solaris in proxy mode and using sendfile. + *) Bugfix: segmentation fault on Solaris in proxy mode and using + sendfile. *) Bugfix: segmentation fault on Solaris. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,3 +1,27 @@ + +Изменения в nginx 0.1.16 25.01.2005 + + *) Исправление: если ответ передавался chunk'ами, то при запросе HEAD + выдавался завершающий chunk. + + *) Исправление: заголовок "Connection: keep-alive" выдавался, даже если + директива keepalive_timeout запрещала использование keep-alive. + + *) Исправление: ошибки в модуле ngx_http_fastcgi_module вызывали + segmentation fault. + + *) Исправление: при использовании SSL сжатый ответ мог передаваться не + до конца. + + *) Исправление: опции TCP_NODELAY, TCP_NOPSUH и TCP_CORK, специфичные + для TCP сокетов, не используются для unix domain сокетов. + + *) Добавление: директива rewrite поддерживает перезаписывание + аргументов. + + *) Исправление: на запрос POST с заголовком "Content-Length: 0" + возвращался ответ 400; ошибка появилась в 0.1.14. + Изменения в nginx 0.1.15 19.01.2005 @@ -20,10 +44,10 @@ директивы "proxy_preserve_host on" в заголовке "Host" указывался также порт 80; ошибка появилась в 0.1.14. - *) Исправление: если задать одинаковые пути в параметрах автоконфигурации - --http-client-body-temp-path=PATH и --http-proxy-temp-path=PATH или - --http-client-body-temp-path=PATH и --http-fastcgi-temp-path=PATH, то - происходил segmentation fault. + *) Исправление: если задать одинаковые пути в параметрах + автоконфигурации --http-client-body-temp-path=PATH и + --http-proxy-temp-path=PATH или --http-client-body-temp-path=PATH и + --http-fastcgi-temp-path=PATH, то происходил segmentation fault. Изменения в nginx 0.1.14 18.01.2005 @@ -32,19 +56,20 @@ --http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH и --http-fastcgi-temp-path=PATH - *) Изменение: имя каталога с временными файлами, содержащие тело запроса - клиента, задаётся директивой client_body_temp_path, по умолчанию - /client_body_temp. + *) Изменение: имя каталога с временными файлами, содержащие тело + запроса клиента, задаётся директивой client_body_temp_path, по + умолчанию /client_body_temp. *) Добавление: модуль ngx_http_fastcgi_module и директивы fastcgi_pass, - fastcgi_root, fastcgi_index, fastcgi_params, fastcgi_connect_timeout, - fastcgi_send_timeout, fastcgi_read_timeout, fastcgi_send_lowat, - fastcgi_header_buffer_size, fastcgi_buffers, + fastcgi_root, fastcgi_index, fastcgi_params, + fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout, + fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size, fastcgi_temp_path, fastcgi_max_temp_file_size, fastcgi_temp_file_write_size, fastcgi_next_upstream и fastcgi_x_powered_by. - *) Исправление: ошибка "[alert] zero size buf"; ошибка появилась в 0.1.3. + *) Исправление: ошибка "[alert] zero size buf"; ошибка появилась в + 0.1.3. *) Изменение: в директиве proxy_pass нужно обязательно указывать URI после имени хоста. @@ -61,7 +86,8 @@ Изменения в nginx 0.1.13 21.12.2004 - *) Добавление: директивы server_names_hash и server_names_hash_threshold. + *) Добавление: директивы server_names_hash и + server_names_hash_threshold. *) Исправление: имена *.domain.tld в директиве server_name не работали. @@ -72,13 +98,14 @@ *) Добавление: параметр лога %request_length. - *) Исправление: при использовании /dev/poll, select и poll на платформах, - где возможны ложные срабатывания указанных методов, могли быть - длительные задержки при обработке запроса по keep-alive соединению. - Наблюдалось по крайней мере на Solaris с использованием /dev/poll. + *) Исправление: при использовании /dev/poll, select и poll на + платформах, где возможны ложные срабатывания указанных методов, + могли быть длительные задержки при обработке запроса по keep-alive + соединению. Наблюдалось по крайней мере на Solaris с использованием + /dev/poll. - *) Исправление: директива send_lowat игнорируется на Linux, так как Linux - не поддерживает опцию SO_SNDLOWAT. + *) Исправление: директива send_lowat игнорируется на Linux, так как + Linux не поддерживает опцию SO_SNDLOWAT. Изменения в nginx 0.1.11 02.12.2004 @@ -97,10 +124,11 @@ *) Исправление: ngx_http_auto_index_module возвращал ошибку 500, если в каталоге есть битый symlink. - *) Исправление: файлы больше 4G не передавались с использованием sendfile. + *) Исправление: файлы больше 4G не передавались с использованием + sendfile. - *) Исправление: если бэкенд резолвился в несколько адресов и при ожидании - от него ответа происходила ошибка, то процесс зацикливался. + *) Исправление: если бэкенд резолвился в несколько адресов и при + ожидании от него ответа происходила ошибка, то процесс зацикливался. *) Исправление: при использовании метода /dev/poll рабочий процесс мог завершиться с сообщением "unknown cycle". @@ -111,8 +139,8 @@ *) Исправление: директива send_lowat не работала на Linux. - *) Исправление: если в конфигурации не было раздела events, то происходил - segmentation fault. + *) Исправление: если в конфигурации не было раздела events, то + происходил segmentation fault. *) Исправление: nginx не собирался под OpenBSD. @@ -125,8 +153,8 @@ или "%XX", то терялся последний символ в строке запроса; ошибка появилась в 0.1.9. - *) Исправление: исправление в версии 0.1.9 для файлов больше 2G на Linux - не работало. + *) Исправление: исправление в версии 0.1.9 для файлов больше 2G на + Linux не работало. Изменения в nginx 0.1.9 25.11.2004 @@ -163,8 +191,9 @@ Изменения в nginx 0.1.6 11.11.2004 - *) Исправление: при некоторых комбинациях директив location c регулярными - выражениями использовалась конфигурация не из того location. + *) Исправление: при некоторых комбинациях директив location c + регулярными выражениями использовалась конфигурация не из того + location. Изменения в nginx 0.1.5 11.11.2004 @@ -204,8 +233,8 @@ *) Добавление: директива proxy_set_x_url. - *) Исправление: модуль проксировании мог привести к зацикливанию, если не - использовался sendfile. + *) Исправление: модуль проксировании мог привести к зацикливанию, если + не использовался sendfile. Изменения в nginx 0.1.2 21.10.2004 @@ -220,12 +249,12 @@ *) Исправление: нельзя переконфигурировать nginx, если конфигурационный файл указан в командной строке; ошибка появилась в 0.1.1. - *) Исправление: модуль проксировании мог привести к зацикливанию, если не - использовался sendfile. + *) Исправление: модуль проксировании мог привести к зацикливанию, если + не использовался sendfile. *) Исправление: при использовании sendfile текст ответа не - перекодировался согласно директивам модуля charset; ошибка появилась в - 0.1.1. + перекодировался согласно директивам модуля charset; ошибка появилась + в 0.1.1. *) Исправление: очень редкая ошибка при обработке kqueue. @@ -253,8 +282,8 @@ *) Исправление: ошибки в модуле /dev/poll. - *) Исправление: при проксировании и использовании временных файлов ответы - портились. + *) Исправление: при проксировании и использовании временных файлов + ответы портились. *) Исправление: бэкенду передавались запросы с неперекодированными символами. diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -181,6 +181,7 @@ WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/win32/ngx_socket.h \ src/os/win32/ngx_os.h \ src/os/win32/ngx_gui.h \ + src/os/win32/ngx_gui_resources.h \ src/os/win32/ngx_process_cycle.h" WIN32_CONFIG=src/os/win32/ngx_win32_config.h @@ -201,7 +202,7 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/win32/ngx_process_cycle.c \ src/event/ngx_event_acceptex.c" -NGX_WIN32_ICONS="src/os/win32/nginx.ico src/os/win32/tray.ico" +NGX_WIN32_ICONS="src/os/win32/nginx.ico src/os/win32/nginx_tray.ico" NGX_WIN32_RC="src/os/win32/nginx.rc" 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.1.15" +#define NGINX_VER "nginx/0.1.16" #define NGINX_VAR "NGINX" #define NGX_NEWPID_EXT ".newbin" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -111,10 +111,6 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx * NGX_CONF_FILE_DONE the configuration file is done */ -#if 0 -ngx_log_debug(cf->log, "token %d" _ rc); -#endif - if (rc == NGX_ERROR) { break; } @@ -173,9 +169,7 @@ ngx_log_debug(cf->log, "token %d" _ rc); { found = 1; -#if 0 -ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data); -#endif + /* is the directive's location right ? */ if ((cmd->type & cf->cmd_type) == 0) { @@ -284,10 +278,6 @@ ngx_log_debug(cf->log, "command '%s'" _ rv = cmd->set(cf, cmd, conf); -#if 0 -ngx_log_debug(cf->log, "rv: %d" _ rv); -#endif - if (rv == NGX_CONF_OK) { break; @@ -366,10 +356,6 @@ static int ngx_conf_read_token(ngx_conf_ b = cf->conf_file->buffer; start = b->pos; -#if 0 -ngx_log_debug(cf->log, "TOKEN START"); -#endif - for ( ;; ) { if (b->pos >= b->last) { @@ -398,12 +384,6 @@ ngx_log_debug(cf->log, "TOKEN START"); ch = *b->pos++; -#if 0 -ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _ - last_space _ need_space _ - quoted _ s_quoted _ d_quoted _ ch); -#endif - if (ch == LF) { cf->conf_file->line++; @@ -574,10 +554,6 @@ ngx_log_debug(cf->log, "%d:%d:%d:%d:%d ' *dst = '\0'; word->len = len; -#if 0 -ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data); -#endif - if (ch == ';') { return NGX_OK; } 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 @@ -13,8 +13,8 @@ ngx_os_io_t ngx_io; ngx_listening_t *ngx_listening_inet_stream_socket(ngx_conf_t *cf, - in_addr_t addr, - in_port_t port) + in_addr_t addr, + in_port_t port) { size_t len; ngx_listening_t *ls; diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -64,9 +64,16 @@ typedef enum { typedef enum { - NGX_TCP_NOPUSH_DISABLED = -1, + NGX_TCP_NODELAY_UNSET = 0, + NGX_TCP_NODELAY_SET, + NGX_TCP_NODELAY_DISABLED +} ngx_connection_tcp_nodelay_e; + + +typedef enum { NGX_TCP_NOPUSH_UNSET = 0, - NGX_TCP_NOPUSH_SET + NGX_TCP_NOPUSH_SET, + NGX_TCP_NOPUSH_DISABLED } ngx_connection_tcp_nopush_e; @@ -109,7 +116,7 @@ struct ngx_connection_s { ngx_uint_t number; - unsigned log_error:2; /* ngx_connection_log_error_e */ + unsigned log_error:2; /* ngx_connection_log_error_e */ unsigned buffered:1; unsigned single_connection:1; @@ -118,8 +125,8 @@ struct ngx_connection_s { unsigned sendfile:1; unsigned sndlowat:1; - unsigned tcp_nodelay:1; - signed tcp_nopush:2; + unsigned tcp_nodelay:2; /* ngx_connection_tcp_nodelay_e */ + unsigned tcp_nopush:2; /* ngx_connection_tcp_nopush_e */ #if (NGX_HAVE_IOCP) unsigned accept_context_updated: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 @@ -86,9 +86,15 @@ void ngx_log_error_core(ngx_uint_t level /* pid#tid */ p = ngx_sprintf(p, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); + if (log->connection) { + p = ngx_sprintf(p, "*%ui ", log->connection); + } + +#if 0 if (log->data && *(int *) log->data != -1) { p = ngx_sprintf(p, "*%ud ", *(u_int *) log->data); } +#endif #if (NGX_HAVE_VARIADIC_MACROS) @@ -137,7 +143,7 @@ void ngx_log_error_core(ngx_uint_t level } if (level != NGX_LOG_DEBUG && log->handler) { - p = log->handler(log->data, p, last - p); + p = log->handler(log, p, last - p); } ngx_log_write(log, errstr, p - errstr); diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -40,14 +40,25 @@ #define NGX_LOG_DEBUG_ALL 0x7ffffff0 -typedef u_char *(*ngx_log_handler_pt) (void *ctx, u_char *buf, size_t len); +typedef u_char *(*ngx_log_handler_pt) (ngx_log_t *log, u_char *buf, size_t len); struct ngx_log_s { ngx_uint_t log_level; ngx_open_file_t *file; + + ngx_uint_t connection; + + ngx_log_handler_pt handler; void *data; - ngx_log_handler_pt handler; + + /* + * we declare "action" as "char *" because the actions are usually + * the static strings and in the "u_char *" case we have to override + * their types all the time + */ + + char *action; }; @@ -60,24 +71,32 @@ struct ngx_log_s { #define NGX_HAVE_VARIADIC_MACROS 1 -#define ngx_log_error(level, log, args...) \ +#define ngx_log_error(level, log, args...) \ if (log->log_level >= level) ngx_log_error_core(level, log, args) void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); +#define ngx_log_debug(level, log, args...) \ + if (log->log_level & level) \ + ngx_log_error_core(NGX_LOG_DEBUG, log, args) + /*********************************/ #elif (NGX_HAVE_C99_VARIADIC_MACROS) #define NGX_HAVE_VARIADIC_MACROS 1 -#define ngx_log_error(level, log, ...) \ +#define ngx_log_error(level, log, ...) \ if (log->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__) void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); +#define ngx_log_debug(level, log, ...) \ + if (log->log_level & level) \ + ngx_log_error_core(NGX_LOG_DEBUG, log, __VA_ARGS__) + /*********************************/ #else /* NO VARIADIC MACROS */ @@ -100,80 +119,59 @@ void ngx_log_debug_core(ngx_log_t *log, #if (NGX_HAVE_VARIADIC_MACROS) -#define ngx_log_debug0(level, log, err, fmt) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt) - -#define ngx_log_debug1(level, log, err, fmt, arg1) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, arg1) - -#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, arg1, arg2) - -#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, arg1, arg2, arg3) - -#define ngx_log_debug4(level, log, err, fmt, arg1, arg2, arg3, arg4) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, arg1, arg2, arg3, arg4) - -#define ngx_log_debug5(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5) - -#define ngx_log_debug6(level, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5, arg6) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5, arg6) - -#define ngx_log_debug7(level, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - if (log->log_level & level) \ - ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define ngx_log_debug0 ngx_log_debug +#define ngx_log_debug1 ngx_log_debug +#define ngx_log_debug2 ngx_log_debug +#define ngx_log_debug3 ngx_log_debug +#define ngx_log_debug4 ngx_log_debug +#define ngx_log_debug5 ngx_log_debug +#define ngx_log_debug6 ngx_log_debug +#define ngx_log_debug7 ngx_log_debug +#define ngx_log_debug8 ngx_log_debug #else /* NO VARIADIC MACROS */ -#define ngx_log_debug0(level, log, err, fmt) \ - if (log->log_level & level) \ +#define ngx_log_debug0(level, log, err, fmt) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt) -#define ngx_log_debug1(level, log, err, fmt, arg1) \ - if (log->log_level & level) \ +#define ngx_log_debug1(level, log, err, fmt, arg1) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt, arg1) -#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \ - if (log->log_level & level) \ +#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt, arg1, arg2) -#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3) \ - if (log->log_level & level) \ +#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3) -#define ngx_log_debug4(level, log, err, fmt, arg1, arg2, arg3, arg4) \ - if (log->log_level & level) \ +#define ngx_log_debug4(level, log, err, fmt, arg1, arg2, arg3, arg4) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4) -#define ngx_log_debug5(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5) \ - if (log->log_level & level) \ +#define ngx_log_debug5(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4, arg5) -#define ngx_log_debug6(level, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5, arg6) \ - if (log->log_level & level) \ +#define ngx_log_debug6(level, log, err, fmt, \ + arg1, arg2, arg3, arg4, arg5, arg6) \ + if (log->log_level & level) \ ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6) -#define ngx_log_debug7(level, log, err, fmt, \ - arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - if (log->log_level & level) \ - ngx_log_debug_core(log, err, fmt, \ +#define ngx_log_debug7(level, log, err, fmt, \ + arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + if (log->log_level & level) \ + ngx_log_debug_core(log, err, fmt, \ arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define ngx_log_debug8(level, log, err, fmt, \ + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + if (log->log_level & level) \ + ngx_log_debug_core(log, err, fmt, \ + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + #endif #else /* NO NGX_DEBUG */ @@ -187,6 +185,8 @@ void ngx_log_debug_core(ngx_log_t *log, #define ngx_log_debug6(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6) #define ngx_log_debug7(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, \ arg6, arg7) +#define ngx_log_debug8(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7, arg8) #endif diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c +++ b/src/core/ngx_output_chain.c @@ -80,7 +80,17 @@ ngx_int_t ngx_output_chain(ngx_output_ch if (bsize == 0 && !ngx_buf_special(ctx->in->buf)) { ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0, - "zero size buf in output"); + "zero size buf in output " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + ctx->in->buf->temporary, + ctx->in->buf->recycled, + ctx->in->buf->in_file, + ctx->in->buf->start, + ctx->in->buf->pos, + ctx->in->buf->last, + ctx->in->buf->file, + ctx->in->buf->file_pos, + ctx->in->buf->file_last); ngx_debug_point(); diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -310,7 +310,7 @@ static int ngx_devpoll_set_event(ngx_eve int ngx_devpoll_process_events(ngx_cycle_t *cycle) { - int events; + int events, revents; ngx_int_t i; ngx_uint_t j, lock, accept_lock, expire; size_t n; @@ -463,30 +463,40 @@ int ngx_devpoll_process_events(ngx_cycle } #endif + revents = event_list[i].revents; + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "devpoll: fd:%d, ev:%04Xd, rev:%04Xd", - event_list[i].fd, - event_list[i].events, event_list[i].revents); + event_list[i].fd, event_list[i].events, revents); - if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { + if (revents & (POLLERR|POLLHUP|POLLNVAL)) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd", - event_list[i].fd, - event_list[i].events, event_list[i].revents); + event_list[i].fd, event_list[i].events, revents); } - if (event_list[i].revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) - { + if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "strange ioctl(DP_POLL) events " "fd:%d ev:%04Xd rev:%04Xd", - event_list[i].fd, - event_list[i].events, event_list[i].revents); + event_list[i].fd, event_list[i].events, revents); + } + + if ((revents & (POLLERR|POLLHUP|POLLNVAL)) + && (revents & (POLLIN|POLLOUT)) == 0) + { + /* + * if the error events were returned without POLLIN or POLLOUT, + * then add these flags to handle the events at least in one + * active handler + */ + + revents |= POLLIN|POLLOUT; } wev = c->write; - if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP)) && wev->active) { + if ((revents & POLLOUT) && wev->active) { wev->ready = 1; if (!ngx_threaded && !ngx_accept_mutex_held) { @@ -505,7 +515,7 @@ int ngx_devpoll_process_events(ngx_cycle rev = c->read; - if ((event_list[i].events & (POLLIN|POLLERR|POLLHUP)) && rev->active) { + if ((revents & POLLIN) && rev->active) { rev->ready = 1; if (!ngx_threaded && !ngx_accept_mutex_held) { diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -198,37 +198,40 @@ static void ngx_epoll_done(ngx_cycle_t * static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags) { - int op, prev; + int op; + uint32_t events, prev; ngx_event_t *e; ngx_connection_t *c; struct epoll_event ee; c = ev->data; + events = (uint32_t) event; + if (event == NGX_READ_EVENT) { e = c->write; prev = EPOLLOUT; #if (NGX_READ_EVENT != EPOLLIN) - event = EPOLLIN; + events = EPOLLIN; #endif } else { e = c->read; prev = EPOLLIN; #if (NGX_WRITE_EVENT != EPOLLOUT) - event = EPOLLOUT; + events = EPOLLOUT; #endif } if (e->active) { op = EPOLL_CTL_MOD; - event |= prev; + events |= prev; } else { op = EPOLL_CTL_ADD; } - ee.events = event | flags; + ee.events = events | flags; ee.data.u64 = (uintptr_t) c | ev->instance; ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, @@ -252,14 +255,15 @@ static int ngx_epoll_add_event(ngx_event static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags) { - int op, prev; + int op; + uint32_t prev; ngx_event_t *e; ngx_connection_t *c; struct epoll_event ee; /* - * when the file descriptor is closed the epoll automatically deletes - * it from its queue so we do not need to delete explicity the event + * when the file descriptor is closed, the epoll automatically deletes + * it from its queue, so we do not need to delete explicity the event * before the closing the file descriptor */ @@ -370,6 +374,7 @@ int ngx_epoll_process_events(ngx_cycle_t { int events; size_t n; + uint32_t revents; ngx_int_t instance, i; ngx_uint_t lock, accept_lock, expire; ngx_err_t err; @@ -521,27 +526,40 @@ int ngx_epoll_process_events(ngx_cycle_t log = c->log ? c->log : cycle->log; #endif + revents = event_list[i].events; + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, "epoll: fd:%d ev:%04XD d:%p", - c->fd, event_list[i].events, event_list[i].data); + c->fd, revents, event_list[i].data); - if (event_list[i].events & (EPOLLERR|EPOLLHUP)) { + if (revents & (EPOLLERR|EPOLLHUP)) { ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, "epoll_wait() error on fd:%d ev:%04XD", - c->fd, event_list[i].events); + c->fd, revents); + } + + if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "strange epoll_wait() events fd:%d ev:%04XD", + c->fd, revents); } - if (event_list[i].events & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { - ngx_log_error(NGX_LOG_ALERT, log, 0, - "strange epoll_wait() events fd:%d ev:%04XD", - c->fd, event_list[i].events); + if ((revents & (EPOLLERR|EPOLLHUP)) + && (revents & (EPOLLIN|EPOLLOUT)) == 0) + { + /* + * if the error events were returned without EPOLLIN or EPOLLOUT, + * then add these flags to handle the events at least in one + * active handler + */ + + revents |= EPOLLIN|EPOLLOUT; } wev = c->write; - if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) - && wev->active) - { + if ((revents & EPOLLOUT) && wev->active) { + if (ngx_threaded) { wev->posted_ready = 1; ngx_post_event(wev); @@ -564,9 +582,8 @@ int ngx_epoll_process_events(ngx_cycle_t * if the accept event is the last one. */ - if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) - && rev->active) - { + if ((revents & EPOLLIN) && rev->active) { + if (ngx_threaded && !rev->accept) { rev->posted_ready = 1; diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -262,7 +262,7 @@ static ngx_int_t ngx_poll_del_event(ngx_ static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle) { - int ready; + int ready, revents; ngx_int_t i, nready; ngx_uint_t n, found, lock, expire; ngx_msec_t timer; @@ -378,33 +378,30 @@ static ngx_int_t ngx_poll_process_events for (i = 0; i < nevents && ready; i++) { + revents = event_list[i].revents; + #if 0 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll: %d: fd:%d ev:%04Xd rev:%04Xd", - i, event_list[i].fd, - event_list[i].events, event_list[i].revents); + i, event_list[i].fd, event_list[i].events, revents); #else - if (event_list[i].revents) { + if (revents) { ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll: %d: fd:%d ev:%04Xd rev:%04Xd", - i, event_list[i].fd, - event_list[i].events, event_list[i].revents); + i, event_list[i].fd, event_list[i].events, revents); } #endif - if (event_list[i].revents & POLLNVAL) { + if (revents & POLLNVAL) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll() error fd:%d ev:%04Xd rev:%04Xd", - event_list[i].fd, - event_list[i].events, event_list[i].revents); + event_list[i].fd, event_list[i].events, revents); } - if (event_list[i].revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) - { + if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "strange poll() events fd:%d ev:%04Xd rev:%04Xd", - event_list[i].fd, - event_list[i].events, event_list[i].revents); + event_list[i].fd, event_list[i].events, revents); } if (event_list[i].fd == -1) { @@ -447,9 +444,21 @@ static ngx_int_t ngx_poll_process_events continue; } + if ((revents & (POLLERR|POLLHUP|POLLNVAL)) + && (revents & (POLLIN|POLLOUT)) == 0) + { + /* + * if the error events were returned without POLLIN or POLLOUT, + * then add these flags to handle the events at least in one + * active handler + */ + + revents |= POLLIN|POLLOUT; + } + found = 0; - if (event_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) { + if (revents & POLLIN) { found = 1; ev = c->read; @@ -474,7 +483,7 @@ static ngx_int_t ngx_poll_process_events #endif } - if (event_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { + if (revents & POLLOUT) { found = 1; ev = c->write; ev->ready = 1; 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 @@ -201,7 +201,7 @@ static ngx_int_t ngx_event_module_init(n } - /* TODO: 128 is cache line size */ + /* TODO: adjust cache line size, 128 is P4 cache line size */ size = 128 /* ngx_accept_mutex */ + 128; /* ngx_connection_counter */ diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -10,29 +10,22 @@ #include -typedef struct { - int flag; - ngx_str_t *name; -} ngx_accept_log_ctx_t; - - static void ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log); -static u_char *ngx_accept_log_error(void *data, u_char *buf, size_t len); +static u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len); void ngx_event_accept(ngx_event_t *ev) { - ngx_uint_t instance, accepted; - socklen_t len; - struct sockaddr *sa; - ngx_err_t err; - ngx_log_t *log; - ngx_pool_t *pool; - ngx_socket_t s; - ngx_event_t *rev, *wev; - ngx_connection_t *c, *ls; - ngx_event_conf_t *ecf; - ngx_accept_log_ctx_t *ctx; + ngx_uint_t instance, accepted; + socklen_t len; + struct sockaddr *sa; + ngx_err_t err; + ngx_log_t *log; + ngx_pool_t *pool; + ngx_socket_t s; + ngx_event_t *rev, *wev; + ngx_connection_t *c, *ls; + ngx_event_conf_t *ecf; ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); @@ -81,16 +74,7 @@ void ngx_event_accept(ngx_event_t *ev) ngx_memcpy(log, ls->log, sizeof(ngx_log_t)); pool->log = log; - if (!(ctx = ngx_palloc(pool, sizeof(ngx_accept_log_ctx_t)))) { - ngx_destroy_pool(pool); - return; - } - - /* -1 disables the connection number logging */ - ctx->flag = -1; - ctx->name = &ls->listening->addr_text; - - log->data = ctx; + log->data = &ls->listening->addr_text; log->handler = ngx_accept_log_error; len = ls->listening->socklen; @@ -467,9 +451,7 @@ static void ngx_close_accepted_socket(ng } -static u_char *ngx_accept_log_error(void *data, u_char *buf, size_t len) +static u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len) { - ngx_accept_log_ctx_t *ctx = data; - - return ngx_snprintf(buf, len, " while accept() on %V", ctx->name); + return ngx_snprintf(buf, len, " while accept() on %V", log->data); } diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -8,11 +8,8 @@ #include #include #include -#include -/* AF_INET only */ - ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { int rc; @@ -170,6 +167,7 @@ ngx_int_t ngx_event_connect_peer(ngx_pee } #if (NGX_WIN32) + /* * Winsock assignes a socket number divisible by 4 * so to find a connection we divide a socket number by 4. @@ -232,6 +230,11 @@ ngx_int_t ngx_event_connect_peer(ngx_pee c->log_error = pc->log_error; + if (peer->sockaddr->sa_family != AF_INET) { + c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; + c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; + } + pc->connection = c; /* @@ -289,6 +292,9 @@ ngx_int_t ngx_event_connect_peer(ngx_pee } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected"); + + wev->ready = 1; + return NGX_OK; } diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -17,8 +17,6 @@ static ngx_int_t ngx_event_pipe_write_ch static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, ngx_buf_t *buf); -static ngx_inline void ngx_event_pipe_add_free_buf(ngx_chain_t **chain, - ngx_chain_t *cl); static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p); @@ -29,6 +27,8 @@ ngx_int_t ngx_event_pipe(ngx_event_pipe_ for ( ;; ) { if (do_write) { + p->log->action = "sending to client"; + if (ngx_event_pipe_write_to_downstream(p) == NGX_ABORT) { return NGX_ABORT; } @@ -37,6 +37,8 @@ ngx_int_t ngx_event_pipe(ngx_event_pipe_ p->read = 0; p->upstream_blocked = 0; + p->log->action = "reading upstream"; + if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) { return NGX_ABORT; } @@ -77,12 +79,12 @@ ngx_int_t ngx_event_pipe(ngx_event_pipe_ } -ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) +static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) { ssize_t n, size; ngx_int_t rc; ngx_buf_t *b; - ngx_chain_t *chain, *cl, *tl; + ngx_chain_t *chain, *cl; if (p->upstream_eof || p->upstream_error || p->upstream_done) { return NGX_OK; @@ -169,8 +171,12 @@ ngx_int_t ngx_event_pipe_read_upstream(n p->allocated++; - ngx_alloc_link_and_set_buf(tl, b, p->pool, NGX_ABORT); - chain = tl; + if (!(chain = ngx_alloc_chain_link(p->pool))) { + return NGX_ABORT; + } + + chain->buf = b; + chain->next = NULL; } else if (!p->cachable && p->downstream->write->ready) { @@ -191,7 +197,7 @@ ngx_int_t ngx_event_pipe_read_upstream(n { /* - * if it's allowed then save some bufs from r->in + * if it is allowed, then save some bufs from r->in * to a temporary file, and add them to a r->out chain */ @@ -227,7 +233,7 @@ ngx_int_t ngx_event_pipe_read_upstream(n } else { - /* if there're no bufs to read in then disable a level event */ + /* there are no bufs to read in */ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "no pipe bufs to read in"); @@ -298,52 +304,56 @@ ngx_int_t ngx_event_pipe_read_upstream(n #if (NGX_DEBUG) - if (p->in || p->busy || p->free_raw_bufs) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe buf"); - } - for (cl = p->busy; cl; cl = cl->next) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf busy %p, pos %p, size: %z", + ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe buf busy s:%d t:%d f:%d " + "%p, pos %p, size: %z " + "file: %O, size: %z", + (cl->buf->shadow ? 1 : 0), + cl->buf->temporary, cl->buf->in_file, cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos); + cl->buf->last - cl->buf->pos, + cl->buf->file_pos, + cl->buf->file_last - cl->buf->file_pos); } for (cl = p->out; cl; cl = cl->next) { - if (cl->buf->in_file && cl->buf->temporary) { - ngx_log_debug5(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf out shadow %p, pos %p, size: %z " - "file: %O, size: %z", - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - - } else if (cl->buf->in_file) { - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf out file %O, size: %z", - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - } else { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf out %p, pos %p, size: %z", - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos); - } + ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe buf out s:%d t:%d f:%d " + "%p, pos %p, size: %z " + "file: %O, size: %z", + (cl->buf->shadow ? 1 : 0), + cl->buf->temporary, cl->buf->in_file, + cl->buf->start, cl->buf->pos, + cl->buf->last - cl->buf->pos, + cl->buf->file_pos, + cl->buf->file_last - cl->buf->file_pos); } for (cl = p->in; cl; cl = cl->next) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf in %p, pos %p, size: %z", + ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe buf in s:%d t:%d f:%d " + "%p, pos %p, size: %z " + "file: %O, size: %z", + (cl->buf->shadow ? 1 : 0), + cl->buf->temporary, cl->buf->in_file, cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos); + cl->buf->last - cl->buf->pos, + cl->buf->file_pos, + cl->buf->file_last - cl->buf->file_pos); } for (cl = p->free_raw_bufs; cl; cl = cl->next) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe buf free %p, last %p, size: %z", - cl->buf->start, cl->buf->last, - cl->buf->end - cl->buf->last); + ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe buf free s:%d t:%d f:%d " + "%p, pos %p, size: %z " + "file: %O, size: %z", + (cl->buf->shadow ? 1 : 0), + cl->buf->temporary, cl->buf->in_file, + cl->buf->start, cl->buf->pos, + cl->buf->last - cl->buf->pos, + cl->buf->file_pos, + cl->buf->file_last - cl->buf->file_pos); } #endif @@ -377,12 +387,11 @@ ngx_int_t ngx_event_pipe_read_upstream(n } -ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) +static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) { size_t bsize; ngx_uint_t flush; - ngx_buf_t *b; - ngx_chain_t *out, **ll, *cl, *tl; + ngx_chain_t *out, **ll, *cl; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe write downstream: %d", p->downstream->write->ready); @@ -522,11 +531,9 @@ ngx_int_t ngx_event_pipe_write_to_downst /* add the free shadow raw buf to p->free_raw_bufs */ if (cl->buf->last_shadow) { - b = cl->buf->shadow; - b->pos = b->last = b->start; - b->shadow = NULL; - ngx_alloc_link_and_set_buf(tl, b, p->pool, NGX_ABORT); - ngx_event_pipe_add_free_buf(&p->free_raw_bufs, tl); + if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) { + return NGX_ABORT; + } cl->buf->last_shadow = 0; } @@ -631,13 +638,21 @@ static ngx_int_t ngx_event_pipe_write_ch ngx_chain_add_link(p->out, p->last_out, cl); if (b->last_shadow) { + + if (!(tl = ngx_alloc_chain_link(p->pool))) { + return NGX_ABORT; + } + + tl->buf = b->shadow; + tl->next = NULL; + + *last_free = tl; + last_free = &tl->next; + b->shadow->pos = b->shadow->start; b->shadow->last = b->shadow->start; - ngx_alloc_link_and_set_buf(tl, b->shadow, p->pool, NGX_ABORT); - - *last_free = tl; - last_free = &tl->next; + ngx_event_pipe_remove_shadow_links(b->shadow); } } @@ -673,7 +688,12 @@ ngx_int_t ngx_event_pipe_copy_input_filt b->recycled = 1; buf->shadow = b; - ngx_alloc_link_and_set_buf(cl, b, p->pool, NGX_ERROR); + if (!(cl = ngx_alloc_chain_link(p->pool))) { + return NGX_ERROR; + } + + cl->buf = b; + cl->next = NULL; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); @@ -742,28 +762,48 @@ static ngx_inline void ngx_event_pipe_fr } -static ngx_inline void ngx_event_pipe_add_free_buf(ngx_chain_t **chain, - ngx_chain_t *cl) +ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b) { - if (*chain == NULL) { - *chain = cl; - return; + ngx_chain_t *cl; + + if (!(cl = ngx_alloc_chain_link(p->pool))) { + return NGX_ERROR; } - if ((*chain)->buf->pos != (*chain)->buf->last) { - cl->next = (*chain)->next; - (*chain)->next = cl; + b->pos = b->start; + b->last = b->start; + b->shadow = NULL; + + cl->buf = b; + + if (p->free_raw_bufs == NULL) { + p->free_raw_bufs = cl; + cl->next = NULL; + + return NGX_OK; + } + + if (p->free_raw_bufs->buf->pos == p->free_raw_bufs->buf->last) { - } else { - cl->next = (*chain); - (*chain) = cl; + /* add the free buf to the list start */ + + cl->next = p->free_raw_bufs; + p->free_raw_bufs = cl; + + return NGX_OK; } + + /* the first free buf is partialy filled, thus add the free buf after it */ + + cl->next = p->free_raw_bufs->next; + p->free_raw_bufs->next = cl; + + return NGX_OK; } static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p) { - ngx_buf_t *b; ngx_chain_t *cl, *tl; for ( ;; ) { @@ -785,19 +825,10 @@ static ngx_int_t ngx_event_pipe_drain_ch while (cl) { if (cl->buf->last_shadow) { - b = cl->buf->shadow; - b->pos = b->last = b->start; - b->shadow = NULL; - - if (!(tl = ngx_alloc_chain_link(p->pool))) { + if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) { return NGX_ABORT; } - tl->buf = b; - tl->next = NULL; - - ngx_event_pipe_add_free_buf(&p->free_raw_bufs, tl); - cl->buf->last_shadow = 0; } diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h --- a/src/event/ngx_event_pipe.h +++ b/src/event/ngx_event_pipe.h @@ -88,6 +88,7 @@ struct ngx_event_pipe_s { ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, int do_write); ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf); +ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b); #endif /* _NGX_EVENT_PIPE_H_INCLUDED_ */ diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c --- a/src/http/modules/ngx_http_chunked_filter.c +++ b/src/http/modules/ngx_http_chunked_filter.c @@ -67,7 +67,7 @@ static ngx_int_t ngx_http_chunked_body_f ngx_buf_t *b; ngx_chain_t out, tail, *cl, *tl, **ll; - if (in == NULL || !r->chunked) { + if (in == NULL || !r->chunked || r->header_only) { return ngx_http_next_body_filter(r, in); } diff --git a/src/http/modules/ngx_http_fastcgi_handler.c b/src/http/modules/ngx_http_fastcgi_handler.c --- a/src/http/modules/ngx_http_fastcgi_handler.c +++ b/src/http/modules/ngx_http_fastcgi_handler.c @@ -1385,7 +1385,7 @@ static ngx_int_t ngx_http_fastcgi_input_ ngx_buf_t *buf) { ngx_int_t rc; - ngx_buf_t *b; + ngx_buf_t *b, **prev; ngx_str_t line; ngx_chain_t *cl; ngx_http_request_t *r; @@ -1399,6 +1399,7 @@ static ngx_int_t ngx_http_fastcgi_input_ f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); b = NULL; + prev = &buf->shadow; f->pos = buf->pos; f->last = buf->last; @@ -1510,11 +1511,14 @@ static ngx_int_t ngx_http_fastcgi_input_ ngx_memzero(b, sizeof(ngx_buf_t)); b->pos = f->pos; - b->shadow = buf; + b->start = buf->start; + b->end = buf->end; b->tag = p->tag; b->temporary = 1; b->recycled = 1; - buf->shadow = b; + + *prev = b; + prev = &b->shadow; if (!(cl = ngx_alloc_chain_link(p->pool))) { return NGX_ERROR; @@ -1523,6 +1527,8 @@ static ngx_int_t ngx_http_fastcgi_input_ cl->buf = b; cl->next = NULL; + /* STUB */ b->num = buf->num; + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); ngx_chain_add_link(p->in, p->last_in, cl); @@ -1563,7 +1569,16 @@ static ngx_int_t ngx_http_fastcgi_input_ } if (b) { + b->shadow = buf; b->last_shadow = 1; + + return NGX_OK; + } + + /* there is no data record in the buf, add it to free chain */ + + if (ngx_event_pipe_add_free_buf(p, buf) != NGX_OK) { + return NGX_ERROR; } return NGX_OK; diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -471,8 +471,8 @@ static ngx_int_t ngx_http_gzip_body_filt /* * We preallocate a memory for zlib in one buffer (200K-400K), this - * dicreases a number of malloc() and free() calls and also probably - * dicreases a number of syscalls (sbrk() and so on). + * decreases a number of malloc() and free() calls and also probably + * decreases a number of syscalls (sbrk() and so on). * Besides we free this memory as soon as the gzipping will complete * and do not wait while a whole response will be sent to a client. * diff --git a/src/http/modules/ngx_http_rewrite_handler.c b/src/http/modules/ngx_http_rewrite_handler.c --- a/src/http/modules/ngx_http_rewrite_handler.c +++ b/src/http/modules/ngx_http_rewrite_handler.c @@ -9,9 +9,10 @@ #include -#define NGX_HTTP_REWRITE_COPY_MATCH 0 -#define NGX_HTTP_REWRITE_COPY_SHORT 1 -#define NGX_HTTP_REWRITE_COPY_LONG 2 +#define NGX_HTTP_REWRITE_COPY_CAPTURE 0 +#define NGX_HTTP_REWRITE_COPY_SHORT 1 +#define NGX_HTTP_REWRITE_COPY_LONG 2 +#define NGX_HTTP_REWRITE_START_ARGS 3 typedef struct { @@ -119,7 +120,7 @@ static ngx_int_t ngx_http_rewrite_handle uintptr_t data; ngx_int_t rc; ngx_uint_t i, m, n; - ngx_str_t uri; + ngx_str_t uri, args; ngx_http_rewrite_op_t *op; ngx_http_rewrite_rule_t *rule; ngx_http_rewrite_srv_conf_t *scf; @@ -176,13 +177,14 @@ static ngx_int_t ngx_http_rewrite_handle uri.len = rule[i].size; for (n = 1; n < (ngx_uint_t) rc; n++) { - uri.len += captures[2 * n + 1] - captures[2 * n]; + uri.len += captures[2 * n + 1] - captures[2 * n]; } if (!(uri.data = ngx_palloc(r->pool, uri.len))) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + args.data = NULL; p = uri.data; op = rule[i].ops.elts; @@ -198,22 +200,34 @@ static ngx_int_t ngx_http_rewrite_handle } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) { p = ngx_cpymem(p, (void *) op[n].data, op[n].len); - } else { /* NGX_HTTP_REWRITE_COPY_MATCH */ + } else if (op[n].op == NGX_HTTP_REWRITE_START_ARGS) { + args.data = p; + + } else { /* NGX_HTTP_REWRITE_COPY_CAPTURE */ m = 2 * op[n].data; p = ngx_cpymem(p, &r->uri.data[captures[m]], captures[m + 1] - captures[m]); } } - uri.len = p - uri.data; + if (args.data) { + uri.len = args.data - uri.data; + args.len = p - args.data; + + r->args = args; + + } else { + uri.len = p - uri.data; + args.len = 0; + } + + r->uri = uri; if (scf->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, - "rewritten uri: \"%V\"", &uri); + "rewritten uri: \"%V\", args: \"%V\"", &uri, &args); } - r->uri = uri; - if (ngx_http_set_exten(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -359,7 +373,9 @@ static char *ngx_http_rewrite_rule(ngx_c return NGX_CONF_ERROR; } - for (i = 0; i < value[2].len; /* void */) { + i = 0; + + while (i < value[2].len) { if (!(op = ngx_push_array(&rule->ops))) { return NGX_CONF_ERROR; @@ -372,7 +388,8 @@ static char *ngx_http_rewrite_rule(ngx_c && value[2].data[i + 1] >= '1' && value[2].data[i + 1] <= '9') { - op->op = NGX_HTTP_REWRITE_COPY_MATCH; + op->op = NGX_HTTP_REWRITE_COPY_CAPTURE; + op->len = 0; op->data = value[2].data[++i] - '0'; if (rule->ncaptures < op->data) { @@ -381,39 +398,53 @@ static char *ngx_http_rewrite_rule(ngx_c i++; - } else { + continue; + } + + if (value[2].data[i] == '?') { + op->op = NGX_HTTP_REWRITE_START_ARGS; + op->len = 0; + op->data = 0; + i++; - while (i < value[2].len && value[2].data[i] != '$') { - i++; - } + continue; + } - len = &value[2].data[i] - data; - rule->size += len; + i++; - if (len) { - - op->len = len; + while (i < value[2].len + && value[2].data[i] != '$' + && value[2].data[i] != '?') + { + i++; + } - if (len <= sizeof(uintptr_t)) { - op->op = NGX_HTTP_REWRITE_COPY_SHORT; - op->data = 0; + len = &value[2].data[i] - data; + rule->size += len; + + if (len) { + + op->len = len; - while (len--) { - op->data <<= 8; - op->data |= data[len]; - } + if (len <= sizeof(uintptr_t)) { + op->op = NGX_HTTP_REWRITE_COPY_SHORT; + op->data = 0; - } else { - op->op = NGX_HTTP_REWRITE_COPY_LONG; + while (len--) { + op->data <<= 8; + op->data |= data[len]; + } - if (!(p = ngx_palloc(cf->pool, len))) { - return NGX_CONF_ERROR; - } + } else { + op->op = NGX_HTTP_REWRITE_COPY_LONG; - ngx_memcpy(p, data, len); - op->data = (uintptr_t) p; + if (!(p = ngx_palloc(cf->pool, len))) { + return NGX_CONF_ERROR; } + + ngx_memcpy(p, data, len); + op->data = (uintptr_t) p; } } } diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -76,7 +76,6 @@ static ngx_int_t ngx_http_static_handler ngx_chain_t out; ngx_file_info_t fi; ngx_http_cleanup_t *file_cleanup, *redirect_cleanup; - ngx_http_log_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; ngx_http_static_loc_conf_t *slcf; #if (NGX_HTTP_CACHE) @@ -476,8 +475,7 @@ static ngx_int_t ngx_http_static_handler #endif - ctx = log->data; - ctx->action = "sending response to client"; + log->action = "sending response to client"; file_cleanup->data.file.fd = fd; file_cleanup->data.file.name = name.data; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -778,17 +778,17 @@ void ngx_http_proxy_close_connection(ngx } -u_char *ngx_http_proxy_log_error(void *data, u_char *buf, size_t len) +u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len) { - ngx_http_proxy_log_ctx_t *ctx = data; - u_char *p; ngx_int_t escape; ngx_str_t uri; ngx_http_request_t *r; ngx_peer_connection_t *peer; + ngx_http_proxy_log_ctx_t *ctx; ngx_http_proxy_upstream_conf_t *uc; + ctx = log->data; r = ctx->proxy->request; uc = ctx->proxy->lcf->upstream; peer = &ctx->proxy->upstream->peer; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -251,7 +251,7 @@ void ngx_http_proxy_check_broken_connect void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev); void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p); -u_char *ngx_http_proxy_log_error(void *data, u_char *buf, size_t len); +u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len); void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); void ngx_http_proxy_close_connection(ngx_http_proxy_ctx_t *p); diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -36,15 +36,6 @@ typedef struct ngx_http_in_addr_s ngx_h struct ngx_http_log_ctx_s { - ngx_uint_t connection; - - /* - * we declare "action" as "char *" because the actions are usually - * the static strings and in the "u_char *" case we have to override - * all the time their types - */ - - char *action; ngx_str_t *client; ngx_http_request_t *request; }; 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 @@ -351,13 +351,10 @@ ngx_module_t ngx_http_core_module = { void ngx_http_handler(ngx_http_request_t *r) { - ngx_http_log_ctx_t *ctx; + r->connection->log->action = NULL; r->connection->unexpected_eof = 0; - ctx = r->connection->log->data; - ctx->action = NULL; - switch (r->headers_in.connection_type) { case 0: if (r->http_version > NGX_HTTP_VERSION_10) { @@ -541,6 +538,10 @@ ngx_int_t ngx_http_find_location_config( r->connection->sendfile = 0; } + if (r->keepalive && clcf->keepalive_timeout == 0) { + r->keepalive = 0; + } + if (!clcf->tcp_nopush) { /* disable TCP_NOPUSH/TCP_CORK use */ r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; 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 @@ -35,7 +35,7 @@ static void ngx_http_lingering_close_han static void ngx_http_client_error(ngx_http_request_t *r, int client_error, int error); -static u_char *ngx_http_log_error(void *data, u_char *buf, size_t len); +static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); /* NGX_HTTP_PARSE_... errors */ @@ -111,12 +111,14 @@ void ngx_http_init_connection(ngx_connec return; } - ctx->connection = c->number; ctx->client = &c->addr_text; - ctx->action = "reading client request line"; ctx->request = NULL; + + c->log->connection = c->number; + c->log->handler = ngx_http_log_error; c->log->data = ctx; - c->log->handler = ngx_http_log_error; + c->log->action = "reading client request line"; + c->log_error = NGX_ERROR_INFO; rev = c->read; @@ -634,7 +636,7 @@ static void ngx_http_process_request_lin return; } - ctx->action = "reading client request headers"; + c->log->action = "reading client request headers"; rev->event_handler = ngx_http_process_request_headers; ngx_http_process_request_headers(rev); @@ -1099,7 +1101,7 @@ static ngx_int_t ngx_http_process_reques } } - if (r->method == NGX_HTTP_POST && r->headers_in.content_length_n <= 0) { + if (r->method == NGX_HTTP_POST && r->headers_in.content_length_n == -1) { return NGX_HTTP_PARSE_POST_WO_CL_HEADER; } @@ -1608,7 +1610,6 @@ static void ngx_http_set_keepalive(ngx_h ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_http_connection_t *hc; - ngx_http_log_ctx_t *ctx; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; @@ -1617,8 +1618,7 @@ static void ngx_http_set_keepalive(ngx_h ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler"); - ctx = c->log->data; - ctx->action = "closing request"; + c->log->action = "closing request"; hc = r->http_connection; b = r->header_in; @@ -1682,7 +1682,7 @@ static void ngx_http_set_keepalive(ngx_h ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request"); hc->pipeline = 1; - ctx->action = "reading client pipelined request line"; + c->log->action = "reading client pipelined request line"; ngx_http_init_request(rev); return; } @@ -1760,7 +1760,7 @@ static void ngx_http_set_keepalive(ngx_h } } - ctx->action = "keepalive"; + c->log->action = "keepalive"; if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { if (ngx_tcp_push(c->fd) == NGX_ERROR) { @@ -1776,8 +1776,10 @@ static void ngx_http_set_keepalive(ngx_h tcp_nodelay = 1; } - if (tcp_nodelay && clcf->tcp_nodelay && !c->tcp_nodelay) { - + if (tcp_nodelay + && clcf->tcp_nodelay + && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, @@ -1789,7 +1791,7 @@ static void ngx_http_set_keepalive(ngx_h return; } - c->tcp_nodelay = 1; + c->tcp_nodelay = NGX_TCP_NODELAY_SET; } #if 0 @@ -1809,7 +1811,6 @@ static void ngx_http_keepalive_handler(n ssize_t n; ngx_buf_t *b; ngx_connection_t *c; - ngx_http_log_ctx_t *ctx; ngx_http_connection_t *hc; c = rev->data; @@ -1821,16 +1822,14 @@ static void ngx_http_keepalive_handler(n return; } - ctx = (ngx_http_log_ctx_t *) rev->log->data; - #if (NGX_HAVE_KQUEUE) if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (rev->pending_eof) { - rev->log->handler = NULL; + c->log->handler = NULL; ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno, "kevent() reported that client %V closed " - "keepalive connection", ctx->client); + "keepalive connection", &c->addr_text); #if (NGX_HTTP_SSL) if (c->ssl) { c->ssl->no_send_shut = 1; @@ -1889,18 +1888,19 @@ static void ngx_http_keepalive_handler(n return; } - rev->log->handler = NULL; + c->log->handler = NULL; if (n == 0) { ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno, - "client %V closed keepalive connection", ctx->client); + "client %V closed keepalive connection", &c->addr_text); ngx_http_close_connection(c); return; } b->last += n; - rev->log->handler = ngx_http_log_error; - ctx->action = "reading client request line"; + + c->log->handler = ngx_http_log_error; + c->log->action = "reading client request line"; ngx_http_init_request(rev); } @@ -2302,16 +2302,17 @@ static void ngx_http_client_error(ngx_ht } -static u_char *ngx_http_log_error(void *data, u_char *buf, size_t len) +static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len) { - ngx_http_log_ctx_t *ctx = data; - - u_char *p; + u_char *p; + ngx_http_log_ctx_t *ctx; p = buf; - if (ctx->action) { - p = ngx_snprintf(p, len, " while %s", ctx->action); + ctx = log->data; + + if (log->action) { + p = ngx_snprintf(p, len, " while %s", log->action); len -= p - buf; } 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 @@ -117,8 +117,8 @@ void ngx_http_upstream_init(ngx_http_req } u->peer.log = r->connection->log; - u->saved_ctx = r->connection->log->data; - u->saved_handler = r->connection->log->handler; + u->saved_log_ctx = r->connection->log->data; + u->saved_log_handler = r->connection->log->handler; r->connection->log->data = u->log_ctx; r->connection->log->handler = u->log_handler; @@ -160,6 +160,14 @@ static void ngx_http_upstream_check_brok ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, "http upstream check client, write event:%d", ev->write); + c = ev->data; + r = c->data; + u = r->upstream; + + if (u->peer.connection == NULL) { + return; + } + #if (NGX_HAVE_KQUEUE) if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { @@ -174,10 +182,6 @@ static void ngx_http_upstream_check_brok ev->error = 1; } - c = ev->data; - r = c->data; - u = r->upstream; - if (!u->cachable && u->peer.connection) { ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno, "kevent() reported that client closed " @@ -203,8 +207,6 @@ static void ngx_http_upstream_check_brok #endif - c = ev->data; - n = recv(c->fd, buf, 1, MSG_PEEK); err = ngx_socket_errno; @@ -218,9 +220,6 @@ static void ngx_http_upstream_check_brok return; } - r = c->data; - u = r->upstream; - if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) { if (ngx_del_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) { ngx_http_upstream_finalize_request(r, u, @@ -242,8 +241,7 @@ static void ngx_http_upstream_check_brok ev->error = 1; - } else { - /* n == 0 */ + } else { /* n == 0 */ err = 0; } @@ -272,10 +270,8 @@ static void ngx_http_upstream_connect(ng { ngx_int_t rc; ngx_connection_t *c; - ngx_http_log_ctx_t *ctx; - ctx = r->connection->log->data; - ctx->action = "connecting to upstream"; + r->connection->log->action = "connecting to upstream"; r->connection->single_connection = 0; @@ -413,9 +409,8 @@ static void ngx_http_upstream_reinit(ngx static void ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) { - int rc; - ngx_connection_t *c; - ngx_http_log_ctx_t *ctx; + int rc; + ngx_connection_t *c; c = u->peer.connection; @@ -437,8 +432,7 @@ static void ngx_http_upstream_send_reque #endif - ctx = c->log->data; - ctx->action = "sending request to upstream"; + c->log->action = "sending request to upstream"; rc = ngx_output_chain(&u->output, u->request_sent ? NULL : r->request_body->bufs); @@ -515,7 +509,6 @@ static void ngx_http_upstream_send_reque { ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_log_ctx_t *ctx; ngx_http_upstream_t *u; c = wev->data; @@ -526,8 +519,7 @@ static void ngx_http_upstream_send_reque "http upstream send request handler"); if (wev->timedout) { - ctx = c->log->data; - ctx->action = "sending request to upstream"; + c->log->action = "sending request to upstream"; ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); return; } @@ -548,7 +540,6 @@ static void ngx_http_upstream_process_he ngx_int_t rc; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_log_ctx_t *ctx; ngx_http_upstream_t *u; c = rev->data; @@ -556,10 +547,9 @@ static void ngx_http_upstream_process_he u = r->upstream; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, - "http upstream process handler"); + "http upstream process header"); - ctx = c->log->data; - ctx->action = "reading response header from upstream"; + c->log->action = "reading response header from upstream"; if (rev->timedout) { ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); @@ -576,7 +566,7 @@ static void ngx_http_upstream_process_he u->header_in.pos = u->header_in.start; u->header_in.last = u->header_in.start; - u->header_in.end = u->header_in.last + u->conf->header_buffer_size; + u->header_in.end = u->header_in.start + u->conf->header_buffer_size; u->header_in.temporary = 1; u->header_in.tag = u->output.tag; @@ -815,7 +805,6 @@ static void ngx_http_upstream_process_bo { ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_log_ctx_t *ctx; ngx_http_upstream_t *u; ngx_event_pipe_t *p; @@ -823,17 +812,15 @@ static void ngx_http_upstream_process_bo r = c->data; u = r->upstream; - ctx = ev->log->data; - if (ev->write) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "http proxy process downstream"); - ctx->action = "sending to client"; + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream process downstream"); + c->log->action = "sending to client"; } else { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "http proxy process upstream"); - ctx->action = "reading upstream body"; + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream process upstream"); + c->log->action = "reading upstream"; } p = &u->pipe; @@ -882,8 +869,8 @@ static void ngx_http_upstream_process_bo #endif if (p->upstream_done || p->upstream_eof || p->upstream_error) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "http proxy upstream exit: %p", p->out); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream exit: %p", p->out); #if 0 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); #endif @@ -893,8 +880,8 @@ static void ngx_http_upstream_process_bo } if (p->downstream_error) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "http proxy downstream error"); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream downstream error"); if (!u->cachable && u->peer.connection) { ngx_http_upstream_finalize_request(r, u, 0); @@ -976,7 +963,7 @@ static void ngx_http_upstream_next(ngx_h if (u->stale && (u->conf->use_stale & ft_type)) { ngx_http_upstream_finalize_request(r, u, - ngx_http_proxy_send_cached_response(r)); + ngx_http_send_cached_response(r)); return; } @@ -1010,8 +997,8 @@ static void ngx_http_upstream_finalize_r ngx_http_upstream_t *u, ngx_int_t rc) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "finalize http upstream request"); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "finalize http upstream request: %i", rc); u->finalize_request(r, rc); @@ -1023,15 +1010,17 @@ static void ngx_http_upstream_finalize_r ngx_close_connection(u->peer.connection); } + u->peer.connection = NULL; + if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) { rc = 0; } - if (u->saved_ctx) { - r->connection->log->data = u->saved_ctx; - r->connection->log->handler = u->saved_handler; + if (u->saved_log_ctx) { + r->connection->log->data = u->saved_log_ctx; + r->connection->log->handler = u->saved_log_handler; } if (u->pipe.temp_file) { @@ -1043,7 +1032,7 @@ static void ngx_http_upstream_finalize_r #if 0 if (u->cache) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http proxy cache fd: %d", + "http upstream cache fd: %d", u->cache->ctx.file.fd); } #endif @@ -1057,6 +1046,8 @@ static void ngx_http_upstream_finalize_r #endif } + r->connection->log->action = "sending to client"; + if (rc == 0 && r->main == NULL) { rc = ngx_http_send_last(r); } @@ -1111,24 +1102,24 @@ static u_char *ngx_http_upstream_log_sta } -u_char *ngx_http_upstream_log_error(void *data, u_char *buf, size_t len) +u_char *ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len) { - ngx_http_log_ctx_t *ctx = data; - u_char *p; ngx_int_t escape; ngx_str_t uri; + ngx_http_log_ctx_t *ctx; ngx_http_request_t *r; ngx_http_upstream_t *u; ngx_peer_connection_t *peer; + ctx = log->data; r = ctx->request; u = r->upstream; peer = &u->peer; p = ngx_snprintf(buf, len, " while %s, client: %V, URL: %V, upstream: %V%V%s%V", - ctx->action, + log->action, &r->connection->addr_text, &r->unparsed_uri, &u->schema, 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 @@ -92,8 +92,8 @@ struct ngx_http_upstream_s { ngx_http_log_ctx_t *log_ctx; ngx_log_handler_pt log_handler; - ngx_http_log_ctx_t *saved_ctx; - ngx_log_handler_pt saved_handler; + ngx_http_log_ctx_t *saved_log_ctx; + ngx_log_handler_pt saved_log_handler; /* used to parse an upstream HTTP header */ ngx_uint_t status; @@ -113,7 +113,7 @@ struct ngx_http_upstream_s { void ngx_http_upstream_init(ngx_http_request_t *r); -u_char *ngx_http_upstream_log_error(void *data, u_char *buf, size_t len); +u_char *ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len); extern char *ngx_http_upstream_header_errors[]; diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -81,7 +81,18 @@ ngx_int_t ngx_http_write_filter(ngx_http #if 1 if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "zero size buf in writer"); + "zero size buf in writer " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + cl->buf->temporary, + cl->buf->recycled, + cl->buf->in_file, + cl->buf->start, + cl->buf->pos, + cl->buf->last, + cl->buf->file, + cl->buf->file_pos, + cl->buf->file_last); + ngx_debug_point(); } #endif @@ -120,7 +131,18 @@ ngx_int_t ngx_http_write_filter(ngx_http #if 1 if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "zero size buf in writer"); + "zero size buf in writer " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + cl->buf->temporary, + cl->buf->recycled, + cl->buf->in_file, + cl->buf->start, + cl->buf->pos, + cl->buf->last, + cl->buf->file, + cl->buf->file_pos, + cl->buf->file_last); + ngx_debug_point(); } #endif @@ -161,15 +183,16 @@ ngx_int_t ngx_http_write_filter(ngx_http } if (size == 0 && !c->buffered) { - if (!last) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "the http output chain is empty"); + if (last) { + return NGX_OK; + } - ngx_debug_point(); + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "the http output chain is empty"); - return NGX_ERROR; - } - return NGX_OK; + ngx_debug_point(); + + return NGX_ERROR; } sent = c->sent; @@ -192,7 +215,7 @@ ngx_int_t ngx_http_write_filter(ngx_http ctx->out = chain; - if (chain || c->buffered) { + if (chain || (last && c->buffered)) { return NGX_AGAIN; } diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c --- a/src/os/unix/ngx_channel.c +++ b/src/os/unix/ngx_channel.c @@ -38,6 +38,8 @@ ngx_int_t ngx_write_channel(ngx_socket_t *(int *) CMSG_DATA(&cmsg.cm) = ch->fd; } + msg.msg_flags = 0; + #else if (ch->fd == -1) { @@ -58,7 +60,6 @@ ngx_int_t ngx_write_channel(ngx_socket_t msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; - msg.msg_flags = 0; n = sendmsg(s, &msg, 0); 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 @@ -279,11 +279,17 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( } } - if (rc == 0 && sent == 0) { + /* + * sendfile() in FreeBSD 3.x-4.x may return value >= 0 + * on success, although only 0 is documented + */ + + if (rc >= 0 && sent == 0) { /* - * rc and sent equal to zero when someone has truncated - * the file, so the offset became beyond the end of the file + * if rc is OK and sent equal to zero, then someone + * has truncated the file, so the offset became beyond + * the end of the file */ ngx_log_error(NGX_LOG_ALERT, c->log, 0, diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -89,7 +89,18 @@ ngx_chain_t *ngx_linux_sendfile_chain(ng #if 1 if (!ngx_buf_in_memory(cl->buf) && !cl->buf->in_file) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "zero size buf in sendfile"); + "zero size buf in sendfile " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + cl->buf->temporary, + cl->buf->recycled, + cl->buf->in_file, + cl->buf->start, + cl->buf->pos, + cl->buf->last, + cl->buf->file, + cl->buf->file_pos, + cl->buf->file_last); + ngx_debug_point(); } #endif @@ -129,7 +140,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ng { /* the TCP_CORK and TCP_NODELAY are mutually exclusive */ - if (c->tcp_nodelay) { + if (c->tcp_nodelay == NGX_TCP_NODELAY_SET) { tcp_nodelay = 0; @@ -146,20 +157,20 @@ ngx_chain_t *ngx_linux_sendfile_chain(ng if (err != NGX_EINTR) { wev->error = 1; - ngx_connection_error(c, ngx_socket_errno, + ngx_connection_error(c, err, "setsockopt(TCP_NODELAY) failed"); return NGX_CHAIN_ERROR; } } else { - c->tcp_nodelay = 0; + c->tcp_nodelay = NGX_TCP_NODELAY_UNSET; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "no tcp_nodelay"); } } - if (!c->tcp_nodelay) { + if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { err = ngx_errno; diff --git a/src/os/unix/rfork_thread.S b/src/os/unix/rfork_thread.S --- a/src/os/unix/rfork_thread.S +++ b/src/os/unix/rfork_thread.S @@ -4,7 +4,6 @@ */ - #include #include @@ -19,14 +18,14 @@ ENTRY(rfork_thread) mov %esp, %ebp push %esi - mov 12(%ebp), %esi # the stack address + mov 12(%ebp), %esi # the thread stack address sub $4, %esi mov 20(%ebp), %eax # the thread argument mov %eax, (%esi) sub $4, %esi - mov 16(%ebp), %eax # the start thread address + mov 16(%ebp), %eax # the thread start address mov %eax, (%esi) push 8(%ebp) # rfork(2) flags @@ -41,8 +40,7 @@ ENTRY(rfork_thread) parent: add $8, %esp pop %esi - mov %ebp, %esp - pop %ebp + leave ret child: @@ -59,8 +57,7 @@ child: error: add $8, %esp pop %esi - mov %ebp, %esp - pop %ebp + leave PIC_PROLOGUE /* libc's cerror: jmp PIC_PLT(HIDENAME(cerror)) */