diff --git a/auto/sources b/auto/sources index 9c6ec193e..c61d83af3 100644 --- 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/docs/xml/change_log_conf.xml b/docs/xml/change_log_conf.xml index 9b1218449..4abb779fd 100644 --- a/docs/xml/change_log_conf.xml +++ b/docs/xml/change_log_conf.xml @@ -3,7 +3,7 @@ -78 +76 *) diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index 1a9c480ed..eb466d823 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,86 @@ +Изменения в nginx +nginx changelog + + + + + + +если ответ передавался chunk'ами, то при запросе HEAD выдавался +завершающий chunk. + + +if the response were transferred by chunks, then on the HEAD request +the final chunk was issued. + + + + + +заголовок "Connection: keep-alive" выдавался, даже если директива +keepalive_timeout запрещала использование keep-alive. + + +the "Connection: keep-alive" header were issued, even if the +keepalive_timeout derective forbade the keep-alive use. + + + + + +ошибки в модуле ngx_http_fastcgi_module вызывали segmentation fault. + + +the errors in the ngx_http_fastcgi_module caused the segmentation faults. + + + + + +при использовании SSL сжатый ответ мог передаваться не до конца. + + +the compressed response encrypted by SSL may not transferred complete. + + + + + +опции TCP_NODELAY, TCP_NOPSUH и TCP_CORK, специфичные для TCP сокетов, +не используются для unix domain сокетов. + + +the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK options, +are not used for the unix domain sockets. + + + + + +директива rewrite поддерживает перезаписывание аргументов. + + +the rewrite directive supports the agruments rewriting. + + + + + +на запрос POST с заголовком "Content-Length: 0" возвращался ответ 400; +ошибка появилась в 0.1.14. + + +the response code 400 was returend for the POST request with the +"Content-Length: 0" header; +bug appeared in 0.1.14. + + + + + diff --git a/src/core/nginx.h b/src/core/nginx.h index 2d18bc996..0b9d9905c 100644 --- 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 index 3c7898ae2..19a567f68 100644 --- 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_str_t *filename) * 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'" _ cmd->name.data); 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_t *cf) 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 '%c'" _ *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 index 64be1ec86..b3fa5de35 100644 --- 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 index 20589a502..5479faaaf 100644 --- 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 index b7198cd7f..d9c5c59bc 100644 --- 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, ngx_log_t *log, ngx_err_t err, /* 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, ngx_log_t *log, ngx_err_t err, } 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 index c54c18723..588837fff 100644 --- 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; - void *data; + + ngx_uint_t connection; + ngx_log_handler_pt handler; + void *data; + + /* + * 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, ngx_err_t err, const char *fmt, ...); #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, ngx_err_t err, const char *fmt, ...); #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 index 2b8da22be..557dd22c9 100644 --- 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_chain_ctx_t *ctx, ngx_chain_t *in) 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 index 34775f2b1..aa61df7de 100644 --- 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_event_t *ev, int event, u_int flags) 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_t *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_t *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 index 907d6aeb5..af2781851 100644 --- 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 *cycle) 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_t *ev, int event, u_int flags) 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 *cycle) { 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 *cycle) 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 (event_list[i].events & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { + if (revents & ~(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); + c->fd, revents); + } + + 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 *cycle) * 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 index 18f72c3b5..12726b58d 100644 --- 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_event_t *ev, int event, u_int flags) 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(ngx_cycle_t *cycle) 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(ngx_cycle_t *cycle) 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(ngx_cycle_t *cycle) #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 index 9960225fc..d79e5ff71 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -201,7 +201,7 @@ static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle) } - /* 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 index 70a7c89a4..d809a77aa 100644 --- 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(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) { - 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 index 75277a7bd..1a3e8f806 100644 --- 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_peer_connection_t *pc) } #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_peer_connection_t *pc) 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_peer_connection_t *pc) } 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 index ad67931c1..0206bf8fe 100644 --- 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_chain_to_temp_file(ngx_event_pipe_t *p); static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, ngx_buf_t *buf); -static ngx_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_t *p, int do_write) 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_t *p, int do_write) 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_t *p, int do_write) } -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(ngx_event_pipe_t *p) 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(ngx_event_pipe_t *p) { /* - * 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(ngx_event_pipe_t *p) } 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(ngx_event_pipe_t *p) #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(ngx_event_pipe_t *p) } -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_downstream(ngx_event_pipe_t *p) /* 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_chain_to_temp_file(ngx_event_pipe_t *p) ngx_chain_add_link(p->out, p->last_out, cl); if (b->last_shadow) { - 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); + 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_event_pipe_remove_shadow_links(b->shadow); } } @@ -673,7 +688,12 @@ ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) 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_free_shadow_raw_buf(ngx_chain_t **free, } -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; - } else { - cl->next = (*chain); - (*chain) = cl; + 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) { + + /* 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_chains(ngx_event_pipe_t *p) 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 index 9781820d9..887f8b7f2 100644 --- 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 index 5134151ed..5145ff67f 100644 --- 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_filter(ngx_http_request_t *r, 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 index 41efa0bb9..9f5016a45 100644 --- 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_filter(ngx_event_pipe_t *p, 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_filter(ngx_event_pipe_t *p, 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_filter(ngx_event_pipe_t *p, 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_filter(ngx_event_pipe_t *p, 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_filter(ngx_event_pipe_t *p, } 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 index 0cd1d91df..cda9ca31e 100644 --- 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_filter(ngx_http_request_t *r, /* * 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 index 002edb88d..636331bc4 100644 --- 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_handler(ngx_http_request_t *r) 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_handler(ngx_http_request_t *r) 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_handler(ngx_http_request_t *r) } 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; - if (scf->log) { - ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, - "rewritten uri: \"%V\"", &uri); + 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\", args: \"%V\"", &uri, &args); + } + 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_conf_t *cf, ngx_command_t *cmd, 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_conf_t *cf, ngx_command_t *cmd, && 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_conf_t *cf, ngx_command_t *cmd, 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) { + while (i < value[2].len + && value[2].data[i] != '$' + && value[2].data[i] != '?') + { + i++; + } - op->len = len; + len = &value[2].data[i] - data; + rule->size += len; - if (len <= sizeof(uintptr_t)) { - op->op = NGX_HTTP_REWRITE_COPY_SHORT; - op->data = 0; + if (len) { - while (len--) { - op->data <<= 8; - op->data |= data[len]; - } + op->len = len; - } else { - op->op = NGX_HTTP_REWRITE_COPY_LONG; + if (len <= sizeof(uintptr_t)) { + op->op = NGX_HTTP_REWRITE_COPY_SHORT; + op->data = 0; - if (!(p = ngx_palloc(cf->pool, len))) { - return NGX_CONF_ERROR; - } - - ngx_memcpy(p, data, len); - op->data = (uintptr_t) p; + while (len--) { + op->data <<= 8; + op->data |= data[len]; } + + } else { + op->op = NGX_HTTP_REWRITE_COPY_LONG; + + 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 index 4cc0de1c2..fa2bcd55b 100644 --- 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_http_request_t *r) 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(ngx_http_request_t *r) #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 index 3e9383e53..ea3a0ca43 100644 --- 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_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) { - 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 index 915ca6219..4dd97c22c 100644 --- 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_connection(ngx_event_t *ev); 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 index 9425e3b36..a21c6709f 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -36,15 +36,6 @@ typedef struct ngx_http_in_addr_s ngx_http_in_addr_t; 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 index f2f69f4df..bf455d867 100644 --- 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(ngx_http_request_t *r) 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 index 811031296..209c547d8 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -35,7 +35,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *ev); 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_connection_t *c) return; } - ctx->connection = c->number; ctx->client = &c->addr_text; - ctx->action = "reading client request line"; ctx->request = NULL; - c->log->data = ctx; + + c->log->connection = c->number; c->log->handler = ngx_http_log_error; + c->log->data = ctx; + 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_line(ngx_event_t *rev) 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_request_header(ngx_http_request_t *r) } } - 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_http_request_t *r) 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_http_request_t *r) 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_http_request_t *r) 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_http_request_t *r) } } - 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_http_request_t *r) 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_http_request_t *r) return; } - c->tcp_nodelay = 1; + c->tcp_nodelay = NGX_TCP_NODELAY_SET; } #if 0 @@ -1809,7 +1811,6 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) 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(ngx_event_t *rev) 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(ngx_event_t *rev) 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_http_request_t *r, } -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 index 2e5459d9c..dae826926 100644 --- 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_request_t *r) } 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_broken_connection(ngx_event_t *ev) 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_broken_connection(ngx_event_t *ev) 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_broken_connection(ngx_event_t *ev) #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_broken_connection(ngx_event_t *ev) 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_broken_connection(ngx_event_t *ev) ev->error = 1; - } else { - /* n == 0 */ + } else { /* n == 0 */ err = 0; } @@ -272,10 +270,8 @@ static void ngx_http_upstream_connect(ngx_http_request_t *r, { 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_http_request_t *r, 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_request(ngx_http_request_t *r, #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_request_handler(ngx_event_t *wev) { 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_request_handler(ngx_event_t *wev) "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_header(ngx_event_t *rev) 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_header(ngx_event_t *rev) 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_header(ngx_event_t *rev) 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_body(ngx_event_t *ev) { 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_body(ngx_event_t *ev) 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_body(ngx_event_t *ev) #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_body(ngx_event_t *ev) } 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_http_request_t *r, 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_request(ngx_http_request_t *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_request(ngx_http_request_t *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_request(ngx_http_request_t *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_request(ngx_http_request_t *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_status(ngx_http_request_t *r, u_char *buf, } -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 index 6614211a6..79ba2a194 100644 --- 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 index 632c6bf93..d4de4a162 100644 --- 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_request_t *r, ngx_chain_t *in) #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_request_t *r, ngx_chain_t *in) #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_request_t *r, ngx_chain_t *in) } if (size == 0 && !c->buffered) { - if (!last) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "the http output chain is empty"); - - ngx_debug_point(); - - return NGX_ERROR; + if (last) { + return NGX_OK; } - return NGX_OK; + + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "the http output chain is empty"); + + ngx_debug_point(); + + return NGX_ERROR; } sent = c->sent; @@ -192,7 +215,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) 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 index 1fd5cb46b..853c5d6fd 100644 --- 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 s, ngx_channel_t *ch, size_t size, *(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 s, ngx_channel_t *ch, size_t size, 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 index 0b4dfc0d0..50cad3090 100644 --- 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(ngx_connection_t *c, ngx_chain_t *in, } } - 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 index 59bc59c76..d45d7c073 100644 --- 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(ngx_connection_t *c, ngx_chain_t *in, #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(ngx_connection_t *c, ngx_chain_t *in, { /* 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(ngx_connection_t *c, ngx_chain_t *in, 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 index 42630a78a..161007d6b 100644 --- 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)) */ diff --git a/src/os/win32/nginx.rc b/src/os/win32/nginx.rc index 7a2e24133..fee869a24 100644 --- a/src/os/win32/nginx.rc +++ b/src/os/win32/nginx.rc @@ -1,10 +1,10 @@ // Copyright (C) Igor Sysoev -#include +#include nginx icon discardable "src\\os\\win32\\nginx.ico" -tray icon discardable "src\\os\\win32\\tray.ico" +tray icon discardable "src\\os\\win32\\nginx_tray.ico" nginx menu discardable begin diff --git a/src/os/win32/tray.ico b/src/os/win32/nginx_tray.ico similarity index 100% rename from src/os/win32/tray.ico rename to src/os/win32/nginx_tray.ico diff --git a/src/os/win32/ngx_gui.h b/src/os/win32/ngx_gui.h index 1c2fd9b43..e44e6aa15 100644 --- a/src/os/win32/ngx_gui.h +++ b/src/os/win32/ngx_gui.h @@ -10,11 +10,7 @@ #include #include - - -#define NGX_WM_TRAY WM_USER -#define NGX_WM_EXIT WM_USER + 1 -#define NGX_WM_ABOUT WM_USER + 2 +#include void ngx_message_box(char *title, ngx_uint_t type, ngx_err_t err, diff --git a/src/os/win32/ngx_gui_resources.h b/src/os/win32/ngx_gui_resources.h new file mode 100644 index 000000000..cfbb00f1a --- /dev/null +++ b/src/os/win32/ngx_gui_resources.h @@ -0,0 +1,19 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#ifndef _NGX_GUI_RESOURCES_H_INCLUDED_ +#define _NGX_GUI_RESOURCES_H_INCLUDED_ + + +#include + + +#define NGX_WM_TRAY WM_USER +#define NGX_WM_EXIT WM_USER + 1 +#define NGX_WM_ABOUT WM_USER + 2 + + +#endif /* _NGX_GUI_RESOURCES_H_INCLUDED_ */