summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-12-02 18:40:46 +0000
committerIgor Sysoev <igor@sysoev.ru>2004-12-02 18:40:46 +0000
commit42b12b34fa74c15cfb1746d71cde949f3d5807ef (patch)
treec44cd3f35d794e6e2be01d516e72737464f76fff
parent4e7b11b02bd42ed284a5f006a13b0635fc33d556 (diff)
downloadnginx-release-0.1.11.tar.gz
nginx-0.1.11-RELEASE importrelease-0.1.11
*) Feature: the worker_priority directive. *) Change: both tcp_nopush and tcp_nodelay directives affect the transferred response. *) Bugfix: nginx did not call initgroups(). Thanks to Andrew Sitnikov and Andrei Nigmatulin. *) Change: now the ngx_http_autoindex_module shows the file size in the bytes. *) Bugfix: the ngx_http_autoindex_module returned the 500 error if the broken symlink was in a directory. *) 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: the worker process may exit with the "unknown cycle" message when the /dev/poll method was used. *) Bugfix: "close() channel failed" errors. *) Bugfix: the autodetection of the "nobody" and "nogroup" groups. *) Bugfix: the send_lowat directive did not work on Linux. *) 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 ":/".
-rw-r--r--auto/modules5
-rw-r--r--auto/options7
-rw-r--r--auto/os/conf21
-rw-r--r--auto/os/linux6
-rw-r--r--auto/types/value2
-rwxr-xr-xauto/unix26
-rw-r--r--docs/xml/nginx/changes.xml148
-rw-r--r--src/core/nginx.c51
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_buf.h4
-rw-r--r--src/core/ngx_config.h5
-rw-r--r--src/core/ngx_cycle.c7
-rw-r--r--src/core/ngx_cycle.h53
-rw-r--r--src/core/ngx_output_chain.c59
-rw-r--r--src/core/ngx_string.c2
-rw-r--r--src/event/modules/ngx_devpoll_module.c11
-rw-r--r--src/event/ngx_event.c25
-rw-r--r--src/event/ngx_event_connect.c9
-rw-r--r--src/event/ngx_event_openssl.c151
-rw-r--r--src/event/ngx_event_openssl.h9
-rw-r--r--src/event/ngx_event_pipe.c4
-rw-r--r--src/event/ngx_event_pipe.h2
-rw-r--r--src/http/modules/ngx_http_autoindex_handler.c46
-rw-r--r--src/http/modules/ngx_http_chunked_filter.c7
-rw-r--r--src/http/modules/ngx_http_index_handler.c7
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c178
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_upstream.c15
-rw-r--r--src/http/ngx_http_cache.h5
-rw-r--r--src/http/ngx_http_core_module.c4
-rw-r--r--src/http/ngx_http_header_filter.c8
-rw-r--r--src/http/ngx_http_log_handler.c5
-rw-r--r--src/http/ngx_http_parse.c63
-rw-r--r--src/http/ngx_http_request.c38
-rw-r--r--src/http/ngx_http_write_filter.c3
-rw-r--r--src/os/unix/ngx_aio_write_chain.c6
-rw-r--r--src/os/unix/ngx_files.h2
-rw-r--r--src/os/unix/ngx_freebsd_init.c3
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c50
-rw-r--r--src/os/unix/ngx_linux_sendfile_chain.c106
-rw-r--r--src/os/unix/ngx_os.h3
-rw-r--r--src/os/unix/ngx_posix_init.c7
-rw-r--r--src/os/unix/ngx_process_cycle.c48
-rw-r--r--src/os/unix/ngx_solaris_sendfilev_chain.c57
-rw-r--r--src/os/unix/ngx_writev_chain.c12
-rw-r--r--src/os/win32/ngx_errno.c6
-rw-r--r--src/os/win32/ngx_os.h1
-rw-r--r--src/os/win32/ngx_win32_config.h5
-rw-r--r--src/os/win32/ngx_win32_init.c2
-rw-r--r--src/os/win32/ngx_wsasend_chain.c21
49 files changed, 973 insertions, 344 deletions
diff --git a/auto/modules b/auto/modules
index f02e80337..b793b349b 100644
--- a/auto/modules
+++ b/auto/modules
@@ -45,6 +45,11 @@ if [ $NGX_TEST_BUILD_RTSIG = YES ]; then
CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
fi
+if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
+ have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . auto/have
+ CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
+fi
+
# the filter order is important
# ngx_http_write_filter
diff --git a/auto/options b/auto/options
index 266ea3115..834ca010e 100644
--- a/auto/options
+++ b/auto/options
@@ -25,6 +25,7 @@ CPU=NO
NGX_TEST_BUILD_DEVPOLL=NO
NGX_TEST_BUILD_EPOLL=NO
NGX_TEST_BUILD_RTSIG=NO
+NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO
NGX_PLATFORM=
NGX_WINE=
@@ -146,6 +147,7 @@ do
--test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;;
--test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;;
--test-build-rtsig) NGX_TEST_BUILD_RTSIG=YES ;;
+ --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;;
*)
echo "$0: error: invalid option \"$option\""
@@ -212,11 +214,6 @@ if test -z "$NGX_PREFIX"; then
fi
-if test -z "$NGX_GROUP"; then
- NGX_GROUP=NGX_USER
-fi
-
-
case ".$NGX_SBIN_PATH" in
./*)
;;
diff --git a/auto/os/conf b/auto/os/conf
index 568b718d2..f64483bda 100644
--- a/auto/os/conf
+++ b/auto/os/conf
@@ -47,7 +47,26 @@ if [ $NGX_PLATFORM != win32 ]; then
if test -z "$NGX_USER"; then
NGX_USER=nobody
- NGX_GROUP=nobody
+ fi
+
+ if [ -z "$NGX_GROUP" -a $NGX_USER = nobody ] ; then
+ if grep nobody /etc/group 2>&1 >/dev/null; then
+ echo "checking for nobody group ... found"
+ NGX_GROUP=nobody
+ else
+ echo "checking for nobody group ... not found"
+
+ if grep nogroup /etc/group 2>&1 >/dev/null; then
+ echo "checking for nogroup group ... found"
+ NGX_GROUP=nogroup
+ else
+ echo "checking for nogroup group ... not found"
+ NGX_GROUP=nobody
+ fi
+ fi
+
+ else
+ NGX_GROUP=$NGX_USER
fi
diff --git a/auto/os/linux b/auto/os/linux
index 687377b6e..f3c6722c4 100644
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -21,12 +21,6 @@ ngx_spacer='
CC_AUX_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
-if test -z "$NGX_USER"; then
- NGX_USER=nobody
- NGX_GROUP=nogroup
-fi
-
-
# Linux kernel version
version=`grep "#define LINUX_VERSION_CODE" /usr/include/linux/version.h \
diff --git a/auto/types/value b/auto/types/value
index d823ab323..698ba7d92 100644
--- a/auto/types/value
+++ b/auto/types/value
@@ -7,3 +7,5 @@ cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_param
#define $ngx_param $ngx_value
#endif
+
+END
diff --git a/auto/unix b/auto/unix
index 7cd1dfe71..6bf89e2e6 100755
--- a/auto/unix
+++ b/auto/unix
@@ -43,31 +43,15 @@ ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
. auto/endianess
+ngx_type="size_t"; . auto/types/sizeof
+ngx_param=MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-# printf() formats
+ngx_type="off_t"; . auto/types/sizeof
+ngx_param=MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-#CC_WARN=$CC_STRONG
-#ngx_fmt_collect=no
-#
-#ngx_fmt_name=OFF_T_FMT; ngx_type="off_t"; . auto/types/sizeof
-ngx_param=OFF_T_MAX_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-#eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
-#
-#ngx_fmt_name=TIME_T_FMT; ngx_type="time_t"; . auto/types/sizeof
+ngx_type="time_t"; . auto/types/sizeof
ngx_param=TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
ngx_param=TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
-#eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
-#
-#ngx_fmt_name=SIZE_T_FMT; ngx_type="size_t"; . auto/types/sizeof
-#eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
-#
-#ngx_fmt_name=SIZE_T_X_FMT; . auto/fmt/xfmt
-#
-#ngx_fmt_name=PID_T_FMT; ngx_type="pid_t"; . auto/types/sizeof
-#eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
-#
-#ngx_fmt_name=RLIM_T_FMT; ngx_type="rlim_t"; . auto/types/sizeof
-#eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
# syscalls, libc calls and some features
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index 7d2c1c247..505fbdea8 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -6,6 +6,147 @@
title="nginx">
+<changes ver="0.1.11" date="02.12.2004">
+
+<change type="feature">
+<para lang="ru">
+директива worker_priority.
+</para>
+<para lang="en">
+the worker_priority directive.
+</para>
+</change>
+
+<change type="change">
+<para lang="ru">
+под FreeBSD директивы tcp_nopush и tcp_nodelay вместе влияют на передачу
+ответа.
+</para>
+<para lang="en">
+both tcp_nopush and tcp_nodelay directives affect the transferred response.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+nginx не вызывал initgroups().<br/>
+Спасибо Андрею Ситникову и Андрею Нигматулину.
+</para>
+<para lang="en">
+nginx did not call initgroups().<br/>
+Thanks to Andrew Sitnikov and Andrei Nigmatulin.
+</para>
+</change>
+
+<change type="change">
+<para lang="ru">
+ngx_http_auto_index_module теперь выдаёт размер файлов в байтах.
+</para>
+<para lang="en">
+now the ngx_http_autoindex_module shows the file size in the bytes.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ngx_http_auto_index_module возвращал ошибку 500, если в каталоге есть
+битый symlink.
+</para>
+<para lang="en">
+the ngx_http_autoindex_module returned the 500 error if the broken symlink
+was in a directory.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+файлы больше 4G не передавались с использованием sendfile.
+</para>
+<para lang="en">
+the files bigger than 4G could not be transferred using sendfile.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+если бэкенд резолвился в несколько адресов и при ожидании от него ответа
+происходила ошибка, то процесс зацикливался.
+</para>
+<para lang="en">
+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.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании метода /dev/poll рабочий процесс мог завершиться
+с сообщением "unknown cycle".
+</para>
+<para lang="en">
+the worker process may exit with the "unknown cycle" message when the /dev/poll
+method was used.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ошибки "close() channel failed".
+</para>
+<para lang="en">
+"close() channel failed" errors.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+автоматическое определение групп nobody и nogroup.
+</para>
+<para lang="en">
+the autodetection of the nobody and nogroup groups.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+директива send_lowat не работала на Linux.
+</para>
+<para lang="en">
+the send_lowat directive did not work on Linux.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+если в конфигурации не было раздела events, то происходил segmentation fault.
+</para>
+<para lang="en">
+the segmentation fault occurred if there was no events section
+in configuration.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+nginx не собирался под OpenBSD.
+</para>
+<para lang="en">
+nginx could not be built on OpenBSD.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+двойные слэшы в "://" в URI превращались в ":/".
+</para>
+<para lang="en">
+the double slashes in "://" in the URI were converted to ":/".
+</para>
+</change>
+
+</changes>
+
+
<changes ver="0.1.10" date="26.11.2004">
<change type="bugfix">
@@ -23,11 +164,10 @@ bug appeared in 0.1.9.
<change type="bugfix">
<para lang="ru">
-исправление в версии 0.1.9 для файлов больше на Linux не работало.
+исправление в версии 0.1.9 для файлов больше 2G на Linux не работало.
</para>
<para lang="en">
-the fix in 0.1.9 for the files bigger than 2G on Linux
-did not work.
+the fix in 0.1.9 for the files bigger than 2G on Linux did not work.
</para>
</change>
@@ -123,7 +263,7 @@ the proxy_max_temp_file_size directive.
ошибка появилась в 0.1.5.
</para>
<para lang="en">
-on FreeBSD the segmentation fault may occure if the size of the transferred
+on FreeBSD the segmentation fault may occur if the size of the transferred
file was changed;
bug appeared in 0.1.5.
</para>
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 887fc7997..26406b3e7 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -16,6 +16,7 @@ static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_conf_enum_t ngx_debug_points[] = {
@@ -80,6 +81,13 @@ static ngx_command_t ngx_core_commands[] = {
0,
NULL },
+ { ngx_string("worker_priority"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+ ngx_set_priority,
+ 0,
+ 0,
+ NULL },
+
{ ngx_string("pid"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
@@ -447,6 +455,7 @@ static void *ngx_core_module_create_conf(ngx_cycle_t *cycle)
*
* ccf->pid = NULL;
* ccf->newpid = NULL;
+ * ccf->priority = 0;
*/
ccf->daemon = NGX_CONF_UNSET;
ccf->master = NGX_CONF_UNSET;
@@ -494,6 +503,7 @@ static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
return NGX_CONF_ERROR;
}
+ ccf->username = NGX_USER;
ccf->user = pwd->pw_uid;
grp = getgrnam(NGX_GROUP);
@@ -562,6 +572,8 @@ static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = (ngx_str_t *) cf->args->elts;
+ ccf->username = (char *) value[1].data;
+
pwd = getpwnam((const char *) value[1].data);
if (pwd == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
@@ -586,3 +598,42 @@ static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#endif
}
+
+
+static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_core_conf_t *ccf = conf;
+
+ ngx_str_t *value;
+ ngx_uint_t n, minus;
+
+ if (ccf->priority != 0) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ if (value[1].data[0] == '-') {
+ n = 1;
+ minus = 1;
+
+ } else if (value[1].data[0] == '+') {
+ n = 1;
+ minus = 0;
+
+ } else {
+ n = 0;
+ minus = 0;
+ }
+
+ ccf->priority = ngx_atoi(&value[1].data[n], value[1].len - n);
+ if (ccf->priority == NGX_ERROR) {
+ return "invalid number";
+ }
+
+ if (minus) {
+ ccf->priority = -ccf->priority;
+ }
+
+ return NGX_CONF_OK;
+}
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 9b61fc959..3ac28f155 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.10"
+#define NGINX_VER "nginx/0.1.11"
#define NGINX_VAR "NGINX"
#define NGX_NEWPID_EXT ".newbin"
diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h
index e2d07190a..768400d25 100644
--- a/src/core/ngx_buf.h
+++ b/src/core/ngx_buf.h
@@ -109,8 +109,8 @@ typedef struct {
((b->flush || b->last_buf) && !ngx_buf_in_memory(b) && !b->in_file)
#define ngx_buf_size(b) \
- (ngx_buf_in_memory(b) ? (size_t) (b->last - b->pos): \
- (size_t) (b->file_last - b->file_pos))
+ (ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
+ (b->file_last - b->file_pos))
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 7d4463b09..b72add7f7 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -39,6 +39,11 @@
#endif
+#ifndef NGX_HAVE_SO_SNDLOWAT
+#define NGX_HAVE_SO_SNDLOWAT 1
+#endif
+
+
#if !(NGX_WIN32)
#define ngx_signal_helper(n) SIG##n
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index d91ba8567..9592a81e6 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -50,7 +50,6 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
ngx_open_file_t *file;
ngx_listening_t *ls, *nls;
ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
ngx_core_module_t *module;
log = old_cycle->log;
@@ -434,12 +433,6 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
}
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
- ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
- "using the \"%s\" event method", ecf->name);
-
-
/* close and delete stuff that lefts from an old cycle */
/* close the unneeded listening sockets */
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 2baf82904..face67fe8 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -17,51 +17,54 @@
struct ngx_cycle_s {
- void ****conf_ctx;
- ngx_pool_t *pool;
+ void ****conf_ctx;
+ ngx_pool_t *pool;
- ngx_log_t *log;
- ngx_log_t *new_log;
+ ngx_log_t *log;
+ ngx_log_t *new_log;
- ngx_array_t listening;
- ngx_array_t pathes;
- ngx_list_t open_files;
+ ngx_array_t listening;
+ ngx_array_t pathes;
+ ngx_list_t open_files;
- ngx_uint_t connection_n;
- ngx_connection_t *connections;
- ngx_event_t *read_events;
- ngx_event_t *write_events;
+ ngx_uint_t connection_n;
+ ngx_connection_t *connections;
+ ngx_event_t *read_events;
+ ngx_event_t *write_events;
- ngx_cycle_t *old_cycle;
+ ngx_cycle_t *old_cycle;
- ngx_str_t conf_file;
- ngx_str_t root;
+ ngx_str_t conf_file;
+ ngx_str_t root;
};
typedef struct {
- ngx_flag_t daemon;
- ngx_flag_t master;
+ ngx_flag_t daemon;
+ ngx_flag_t master;
- ngx_int_t worker_processes;
- ngx_int_t debug_points;
+ ngx_int_t worker_processes;
+ ngx_int_t debug_points;
- ngx_uid_t user;
- ngx_gid_t group;
+ int priority;
- ngx_str_t pid;
- ngx_str_t newpid;
+ char *username;
+ ngx_uid_t user;
+ ngx_gid_t group;
+
+ ngx_str_t pid;
+ ngx_str_t newpid;
#if (NGX_THREADS)
- ngx_int_t worker_threads;
- size_t thread_stack_size;
+ ngx_int_t worker_threads;
+ size_t thread_stack_size;
#endif
} ngx_core_conf_t;
typedef struct {
- ngx_pool_t *pool; /* pcre's malloc() pool */
+ ngx_pool_t *pool; /* pcre's malloc() pool */
} ngx_core_tls_t;
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 1c367ccad..b925e4867 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -28,7 +28,8 @@ static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
{
int rc, last;
- size_t size, bsize;
+ off_t bsize;
+ size_t size;
ngx_chain_t *cl, *out, **last_out;
if (ctx->in == NULL && ctx->busy == NULL) {
@@ -81,6 +82,8 @@ ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
"zero size buf");
+ ngx_debug_point();
+
ctx->in = ctx->in->next;
continue;
@@ -118,18 +121,18 @@ ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
if (ctx->in->buf->last_buf) {
- if (bsize < ctx->bufs.size) {
+ if (bsize < (off_t) ctx->bufs.size) {
/*
* allocate small temp buf for the small last buf
* or its small last part
*/
- size = bsize;
+ size = (size_t) bsize;
} else if (ctx->bufs.num == 1
- && (bsize < ctx->bufs.size
- + (ctx->bufs.size >> 2)))
+ && (bsize < (off_t) (ctx->bufs.size
+ + (ctx->bufs.size >> 2))))
{
/*
* allocate a temp buf that equals
@@ -137,7 +140,7 @@ ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
* than 1.25 of bufs.size and a temp buf is single
*/
- size = bsize;
+ size = (size_t) bsize;
}
}
@@ -306,12 +309,12 @@ static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool,
static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
ngx_uint_t sendfile)
{
- size_t size;
+ off_t size;
ssize_t n;
size = ngx_buf_size(src);
- if (size > (size_t) (dst->end - dst->pos)) {
+ if (size > dst->end - dst->pos) {
size = dst->end - dst->pos;
}
@@ -324,9 +327,9 @@ static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
#endif
if (ngx_buf_in_memory(src)) {
- ngx_memcpy(dst->pos, src->pos, size);
- src->pos += size;
- dst->last += size;
+ ngx_memcpy(dst->pos, src->pos, (size_t) size);
+ src->pos += (size_t) size;
+ dst->last += (size_t) size;
if (src->in_file) {
@@ -351,7 +354,7 @@ static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
}
} else {
- n = ngx_read_file(src->file, dst->pos, size, src->file_pos);
+ n = ngx_read_file(src->file, dst->pos, (size_t) size, src->file_pos);
if (n == NGX_ERROR) {
return n;
@@ -363,9 +366,9 @@ static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
}
#endif
- if ((size_t) n != size) {
+ if (n != size) {
ngx_log_error(NGX_LOG_ALERT, src->file->log, 0,
- ngx_read_file_n " reads only %z of %uz from file",
+ ngx_read_file_n " reads only %z of %O from file",
n, size);
if (n == 0) {
return NGX_ERROR;
@@ -399,10 +402,19 @@ ngx_int_t ngx_chain_writer(void *data, ngx_chain_t *in)
{
ngx_chain_writer_ctx_t *ctx = data;
+ off_t size;
ngx_chain_t *cl;
- for (/* void */; in; in = in->next) {
+ for (size = 0; in; in = in->next) {
+
+#if 1
+ if (ngx_buf_size(in->buf) == 0 && !ngx_buf_special(in->buf)) {
+ ngx_debug_point();
+ }
+#endif
+
+ size += ngx_buf_size(in->buf);
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
"chain writer buf size: %uz", ngx_buf_size(in->buf));
@@ -419,6 +431,23 @@ ngx_int_t ngx_chain_writer(void *data, ngx_chain_t *in)
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
"chain writer in: %p", ctx->out);
+ for (cl = ctx->out; cl; cl = cl->next) {
+
+#if 1
+
+ if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
+ ngx_debug_point();
+ }
+
+#endif
+
+ size += ngx_buf_size(cl->buf);
+ }
+
+ if (size == 0) {
+ return NGX_OK;
+ }
+
ctx->out = ngx_send_chain(ctx->connection, ctx->out, ctx->limit);
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 4e5d273c3..4c21fa61c 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -30,7 +30,7 @@ u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n)
/*
* supported formats:
- * %[0][width]O off_t
+ * %[0][width][x][X]O off_t
* %[0][width]T time_t
* %[0][width][u][x|X]z ssize_t/size_t
* %[0][width][u][x|X]d int/u_int
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 1a48ceccf..34775f2b1 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -435,6 +435,16 @@ int ngx_devpoll_process_events(ngx_cycle_t *cycle)
c = &ngx_cycle->connections[event_list[i].fd];
if (c->fd == -1) {
+ if (ngx_cycle->read_events[event_list[i].fd].closed) {
+ continue;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event");
+ continue;
+ }
+
+#if 0
+ if (c->fd == -1) {
old_cycle = ngx_old_cycles.elts;
for (j = 0; j < ngx_old_cycles.nelts; j++) {
if (old_cycle[j] == NULL) {
@@ -451,6 +461,7 @@ int ngx_devpoll_process_events(ngx_cycle_t *cycle)
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "unknown cycle");
exit(1);
}
+#endif
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index bd451bc65..ef25ffc51 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -174,10 +174,25 @@ static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
{
#if !(NGX_WIN32)
- size_t size;
- char *shared;
- ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
+ size_t size;
+ void ***cf;
+ char *shared;
+ ngx_core_conf_t *ccf;
+ ngx_event_conf_t *ecf;
+
+ cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
+
+ if (cf == NULL) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
+ "no \"events\" section in configuration");
+ return NGX_ERROR;
+ }
+
+ ecf = (*cf)[ngx_event_core_module.ctx_index];
+
+ ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
+ "using the \"%s\" event method", ecf->name);
+
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@@ -185,8 +200,6 @@ static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
return NGX_OK;
}
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
/* TODO: 128 is cache line size */
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index c06896895..6f0d94f86 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -81,9 +81,12 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc)
for ( ;; ) {
peer = &pc->peers->peers[pc->cur_peer];
- if (peer->fails <= pc->peers->max_fails
- || (now - peer->accessed > pc->peers->fail_timeout))
- {
+ if (peer->fails <= pc->peers->max_fails) {
+ break;
+ }
+
+ if (now - peer->accessed > pc->peers->fail_timeout) {
+ peer->fails = 0;
break;
}
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 294f3b4ce..c0ec6adfe 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -9,7 +9,9 @@
#include <ngx_event.h>
+static void ngx_ssl_write_handler(ngx_event_t *wev);
static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
+static void ngx_ssl_read_handler(ngx_event_t *rev);
ngx_int_t ngx_ssl_init(ngx_log_t *log)
@@ -69,6 +71,25 @@ ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);
if (n > 0) {
+ if (c->ssl->saved_write_handler) {
+
+ c->write->event_handler = c->ssl->saved_write_handler;
+ c->ssl->saved_write_handler = NULL;
+ c->write->ready = 1;
+
+ if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->write);
+
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+ }
+
return n;
}
@@ -93,13 +114,27 @@ ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
if (sslerr == SSL_ERROR_WANT_WRITE) {
ngx_log_error(NGX_LOG_ALERT, c->log, err,
"SSL wants to write%s", handshake);
- return NGX_ERROR;
-#if 0
+
+ c->write->ready = 0;
+
+ if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ /*
+ * we do not set the timer because there is already the read event timer
+ */
+
+ if (c->ssl->saved_write_handler == NULL) {
+ c->ssl->saved_write_handler = c->write->event_handler;
+ c->write->event_handler = ngx_ssl_write_handler;
+ }
+
return NGX_AGAIN;
-#endif
}
c->ssl->no_rcv_shut = 1;
+ c->ssl->no_send_shut = 1;
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
ngx_log_error(NGX_LOG_INFO, c->log, err,
@@ -115,9 +150,18 @@ ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
}
+static void ngx_ssl_write_handler(ngx_event_t *wev)
+{
+ ngx_connection_t *c;
+
+ c = wev->data;
+ c->read->event_handler(c->read);
+}
+
+
/*
* OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
- * before SSL_write() call to decrease a SSL overhead.
+ * before the SSL_write() call to decrease a SSL overhead.
*
* Besides for protocols such as HTTP it is possible to always buffer
* the output to decrease a SSL overhead some more.
@@ -155,6 +199,14 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
return in;
}
+
+ /* the maximum limit size is the maximum uint32_t value - the page size */
+
+ if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) {
+ limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
+ }
+
+
send = 0;
flush = (in == NULL) ? 1 : 0;
@@ -252,6 +304,25 @@ static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
if (n > 0) {
+ if (c->ssl->saved_read_handler) {
+
+ c->read->event_handler = c->ssl->saved_read_handler;
+ c->ssl->saved_read_handler = NULL;
+ c->read->ready = 1;
+
+ if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->read);
+
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+ }
+
return n;
}
@@ -277,13 +348,28 @@ static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
ngx_log_error(NGX_LOG_ALERT, c->log, err,
"SSL wants to read%s", handshake);
- return NGX_ERROR;
-#if 0
+
+ c->read->ready = 0;
+
+ if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ /*
+ * we do not set the timer because there is already
+ * the write event timer
+ */
+
+ if (c->ssl->saved_read_handler == NULL) {
+ c->ssl->saved_read_handler = c->read->event_handler;
+ c->read->event_handler = ngx_ssl_read_handler;
+ }
+
return NGX_AGAIN;
-#endif
}
c->ssl->no_rcv_shut = 1;
+ c->ssl->no_send_shut = 1;
ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed");
@@ -291,21 +377,42 @@ static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
}
+static void ngx_ssl_read_handler(ngx_event_t *rev)
+{
+ ngx_connection_t *c;
+
+ c = rev->data;
+ c->write->event_handler(c->write);
+}
+
+
ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
{
- int n, sslerr;
+ int n, sslerr, mode;
ngx_uint_t again;
- if (c->timedout) {
- SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN);
+ if (!c->ssl->shutdown_set) {
- } else {
- if (c->ssl->no_rcv_shut) {
- SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN);
+ /* it seems that SSL_set_shutdown() could be called once only */
+
+ if (c->read->timedout) {
+ mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
+
+ } else {
+ mode = 0;
+
+ if (c->ssl->no_rcv_shut) {
+ mode = SSL_RECEIVED_SHUTDOWN;
+ }
+
+ if (c->ssl->no_send_shut) {
+ mode |= SSL_SENT_SHUTDOWN;
+ }
}
- if (c->ssl->no_send_shut) {
- SSL_set_shutdown(c->ssl->ssl, SSL_SENT_SHUTDOWN);
+ if (mode) {
+ SSL_set_shutdown(c->ssl->ssl, mode);
+ c->ssl->shutdown_set = 1;
}
}
@@ -319,17 +426,17 @@ ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
- if (n == 0) {
- again = 1;
- break;
- }
-
- if (n == 1) {
+ if (n == 1 || (n == 0 && c->read->timedout)) {
SSL_free(c->ssl->ssl);
c->ssl = NULL;
return NGX_OK;
}
+ if (n == 0) {
+ again = 1;
+ break;
+ }
+
break;
}
@@ -342,7 +449,7 @@ ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
if (again || sslerr == SSL_ERROR_WANT_READ) {
- ngx_add_timer(c->read, 10000);
+ ngx_add_timer(c->read, 30000);
if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
return NGX_ERROR;
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index dbdb5f7b3..6e7b705b1 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -18,11 +18,13 @@
typedef struct {
SSL *ssl;
ngx_buf_t *buf;
- ngx_event_handler_pt saved_handler;
+ ngx_event_handler_pt saved_read_handler;
+ ngx_event_handler_pt saved_write_handler;
unsigned buffer:1;
unsigned no_rcv_shut:1;
unsigned no_send_shut:1;
+ unsigned shutdown_set:1;
} ngx_ssl_t;
@@ -48,10 +50,5 @@ ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c);
void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
char *fmt, ...);
-#define ngx_ssl_set_nosendshut(ssl) \
- if (ssl) { \
- ssl->no_send_shut = 1; \
- }
-
#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 3ca8a0cf3..310f0ce43 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -379,7 +379,7 @@ 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)
{
- size_t bsize;
+ off_t bsize;
ngx_uint_t flush;
ngx_buf_t *b;
ngx_chain_t *out, **ll, *cl, *tl;
@@ -442,7 +442,7 @@ ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write busy: %uz", bsize);
+ "pipe write busy: %O", bsize);
out = NULL;
ll = NULL;
diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h
index 961f0666b..9781820d9 100644
--- a/src/event/ngx_event_pipe.h
+++ b/src/event/ngx_event_pipe.h
@@ -62,7 +62,7 @@ struct ngx_event_pipe_s {
ngx_bufs_t bufs;
ngx_buf_tag_t tag;
- size_t busy_size;
+ ssize_t busy_size;
off_t read_length;
diff --git a/src/http/modules/ngx_http_autoindex_handler.c b/src/http/modules/ngx_http_autoindex_handler.c
index f5ec9704f..ac2438e7f 100644
--- a/src/http/modules/ngx_http_autoindex_handler.c
+++ b/src/http/modules/ngx_http_autoindex_handler.c
@@ -105,11 +105,10 @@ static u_char tail[] =
static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r)
{
- u_char *last, scale;
+ u_char *last;
size_t len;
- off_t length;
ngx_tm_t tm;
- ngx_int_t rc, size;
+ ngx_int_t rc;
ngx_uint_t i, level;
ngx_err_t err;
ngx_buf_t *b;
@@ -307,7 +306,7 @@ static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r)
+ NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
+ sizeof("</a>") - 1
+ sizeof(" 28-Sep-1970 12:00 ") - 1
- + sizeof("1023G") - 1
+ + 19
+ 2;
}
@@ -383,44 +382,11 @@ static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r)
tm.ngx_tm_min);
if (entry[i].dir) {
- b->last = ngx_cpymem(b->last, " -", sizeof(" -") - 1);
+ b->last = ngx_cpymem(b->last, " -",
+ sizeof(" -") - 1);
} else {
- length = entry[i].size;
-
- if (length > 1024 * 1024 * 1024 - 1) {
- size = (ngx_int_t) (length / (1024 * 1024 * 1024));
- if ((length % (1024 * 1024 * 1024))
- > (1024 * 1024 * 1024 / 2 - 1))
- {
- size++;
- }
- scale = 'G';
-
- } else if (length > 1024 * 1024 - 1) {
- size = (ngx_int_t) (length / (1024 * 1024));
- if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) {
- size++;
- }
- scale = 'M';
-
- } else if (length > 9999) {
- size = (ngx_int_t) (length / 1024);
- if (length % 1024 > 511) {
- size++;
- }
- scale = 'K';
-
- } else {
- size = (ngx_int_t) length;
- scale = ' ';
- }
-
- b->last = ngx_sprintf(b->last, "%4i", size);
-
- if (scale != ' ') {
- *b->last++ = scale;
- }
+ b->last = ngx_sprintf(b->last, "%19O", entry[i].size);
}
*b->last++ = CR;
diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c
index 929a7ed2c..5134151ed 100644
--- a/src/http/modules/ngx_http_chunked_filter.c
+++ b/src/http/modules/ngx_http_chunked_filter.c
@@ -63,7 +63,7 @@ static ngx_int_t ngx_http_chunked_body_filter(ngx_http_request_t *r,
ngx_chain_t *in)
{
u_char *chunk;
- size_t size;
+ off_t size;
ngx_buf_t *b;
ngx_chain_t out, tail, *cl, *tl, **ll;
@@ -106,13 +106,14 @@ static ngx_int_t ngx_http_chunked_body_filter(ngx_http_request_t *r,
return NGX_ERROR;
}
- if (!(chunk = ngx_palloc(r->pool, sizeof("00000000" CRLF) - 1))) {
+ chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1);
+ if (chunk == NULL) {
return NGX_ERROR;
}
b->temporary = 1;
b->pos = chunk;
- b->last = ngx_sprintf(chunk, "%xz" CRLF, size);
+ b->last = ngx_sprintf(chunk, "%xO" CRLF, size);
out.buf = b;
}
diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c
index 3386953bd..74ccf0ae1 100644
--- a/src/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -448,8 +448,7 @@ static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
ngx_http_index_loc_conf_t *prev = parent;
ngx_http_index_loc_conf_t *conf = child;
- ngx_uint_t i;
- ngx_str_t *index, *prev_index;
+ ngx_str_t *index;
if (conf->max_index_len == 0) {
if (prev->max_index_len != 0) {
@@ -465,6 +464,8 @@ static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
return NGX_CONF_OK;
}
+#if 0
+
if (prev->max_index_len != 0) {
prev_index = prev->indices.elts;
@@ -476,6 +477,8 @@ static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
}
}
+#endif
+
if (conf->max_index_len < prev->max_index_len) {
conf->max_index_len = prev->max_index_len;
}
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index 425a1a6af..651dfa67b 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -275,12 +275,9 @@ ngx_module_t ngx_http_proxy_module = {
static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = {
- { ngx_string("proxy"), /* STUB */ 100,
- ngx_http_proxy_log_proxy_state },
- { ngx_string("proxy_cache_state"), sizeof("BYPASS") - 1,
- ngx_http_proxy_log_cache_state },
- { ngx_string("proxy_reason"), sizeof("BPS") - 1,
- ngx_http_proxy_log_reason },
+ { ngx_string("proxy"), 0, ngx_http_proxy_log_proxy_state },
+ { ngx_string("proxy_cache_state"), 0, ngx_http_proxy_log_cache_state },
+ { ngx_string("proxy_reason"), 0, ngx_http_proxy_log_reason },
{ ngx_null_string, 0, NULL }
};
@@ -792,111 +789,180 @@ u_char *ngx_http_proxy_log_error(void *data, u_char *buf, size_t len)
static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
u_char *buf, uintptr_t data)
{
- ngx_http_proxy_ctx_t *p;
+ ngx_uint_t i;
+ ngx_http_proxy_ctx_t *p;
+ ngx_http_proxy_state_t *state;
p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
if (p == NULL) {
+ if (buf == NULL) {
+ return (u_char *) 1;
+ }
+
*buf = '-';
return buf + 1;
}
- if (p->state->cache_state == 0) {
- *buf++ = '-';
- } else {
- buf = ngx_cpymem(buf, cache_states[p->state->cache_state - 1].data,
- cache_states[p->state->cache_state - 1].len);
+ if (buf == NULL) {
+ /* find the request line length */
+ return (u_char *) (uintptr_t) (p->states.nelts * /* STUB */ 100);
}
- *buf++ = '/';
- if (p->state->expired == 0) {
- *buf++ = '-';
+ i = 0;
+ state = p->states.elts;
- } else {
- buf = ngx_sprintf(buf, "%T", p->state->expired);
- }
+ for ( ;; ) {
+ if (state[i].cache_state == 0) {
+ *buf++ = '-';
- *buf++ = '/';
+ } else {
+ buf = ngx_cpymem(buf, cache_states[state[i].cache_state - 1].data,
+ cache_states[state[i].cache_state - 1].len);
+ }
- if (p->state->bl_time == 0) {
- *buf++ = '-';
+ *buf++ = '/';
- } else {
- buf = ngx_sprintf(buf, "%T", p->state->bl_time);
- }
+ if (state[i].expired == 0) {
+ *buf++ = '-';
- *buf++ = '/';
+ } else {
+ buf = ngx_sprintf(buf, "%T", state[i].expired);
+ }
- *buf++ = '*';
+ *buf++ = '/';
- *buf++ = ' ';
+ if (state[i].bl_time == 0) {
+ *buf++ = '-';
- if (p->state->status == 0) {
- *buf++ = '-';
+ } else {
+ buf = ngx_sprintf(buf, "%T", state[i].bl_time);
+ }
- } else {
- buf = ngx_sprintf(buf, "%ui", p->state->status);
- }
+ *buf++ = '/';
- *buf++ = '/';
+ *buf++ = '*';
- if (p->state->reason == 0) {
- *buf++ = '-';
+ *buf++ = ' ';
- } else {
- buf = ngx_cpymem(buf, cache_reasons[p->state->reason - 1].data,
- cache_reasons[p->state->reason - 1].len);
- }
+ if (state[i].status == 0) {
+ *buf++ = '-';
+
+ } else {
+ buf = ngx_sprintf(buf, "%ui", state[i].status);
+ }
- *buf++ = '/';
+ *buf++ = '/';
- if (p->state->reason < NGX_HTTP_PROXY_CACHE_XAE) {
- *buf++ = '-';
+ if (state[i].reason == 0) {
+ *buf++ = '-';
- } else {
- buf = ngx_sprintf(buf, "%T", p->state->expires);
- }
+ } else {
+ buf = ngx_cpymem(buf, cache_reasons[state[i].reason - 1].data,
+ cache_reasons[state[i].reason - 1].len);
+ }
+
+ *buf++ = '/';
+
+ if (state[i].reason < NGX_HTTP_PROXY_CACHE_XAE) {
+ *buf++ = '-';
+
+ } else {
+ buf = ngx_sprintf(buf, "%T", state[i].expires);
+ }
- *buf++ = ' ';
- *buf++ = '*';
+ *buf++ = ' ';
+ *buf++ = '*';
- return buf;
+ if (++i == p->states.nelts) {
+ return buf;
+ }
+
+ *buf++ = ',';
+ *buf++ = ' ';
+ }
}
static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r,
u_char *buf, uintptr_t data)
{
- ngx_http_proxy_ctx_t *p;
+ ngx_uint_t i;
+ ngx_http_proxy_ctx_t *p;
+ ngx_http_proxy_state_t *state;
p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
if (p == NULL || p->state->cache_state == 0) {
+ if (buf == NULL) {
+ return (u_char *) 1;
+ }
+
*buf = '-';
return buf + 1;
}
- return ngx_cpymem(buf, cache_states[p->state->cache_state - 1].data,
- cache_states[p->state->cache_state - 1].len);
+ if (buf == NULL) {
+ /* find the request line length */
+ return (u_char *) (p->states.nelts * sizeof("BYPASS") - 1);
+ }
+
+ i = 0;
+ state = p->states.elts;
+
+ for ( ;; ) {
+ buf = ngx_cpymem(buf, cache_states[state[i].cache_state - 1].data,
+ cache_states[state[i].cache_state - 1].len);
+
+ if (++i == p->states.nelts) {
+ return buf;
+ }
+
+ *buf++ = ',';
+ *buf++ = ' ';
+ }
}
static u_char *ngx_http_proxy_log_reason(ngx_http_request_t *r, u_char *buf,
uintptr_t data)
{
- ngx_http_proxy_ctx_t *p;
+ ngx_uint_t i;
+ ngx_http_proxy_ctx_t *p;
+ ngx_http_proxy_state_t *state;
p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
if (p == NULL || p->state->reason == 0) {
+ if (buf == NULL) {
+ return (u_char *) 1;
+ }
+
*buf = '-';
return buf + 1;
}
- return ngx_cpymem(buf, cache_reasons[p->state->reason - 1].data,
- cache_reasons[p->state->reason - 1].len);
+ if (buf == NULL) {
+ /* find the request line length */
+ return (u_char *) (p->states.nelts * sizeof("BPS") - 1);
+ }
+
+ i = 0;
+ state = p->states.elts;
+
+ for ( ;; ) {
+ buf = ngx_cpymem(buf, cache_reasons[state[i].reason - 1].data,
+ cache_reasons[state[i].reason - 1].len);
+
+ if (++i == p->states.nelts) {
+ return buf;
+ }
+
+ *buf++ = ',';
+ *buf++ = ' ';
+ }
}
@@ -1387,9 +1453,8 @@ static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
- ssize_t *np = data;
-
#if (NGX_FREEBSD)
+ ssize_t *np = data;
if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -1401,6 +1466,7 @@ static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
}
#elif !(NGX_HAVE_SO_SNDLOWAT)
+ ssize_t *np = data;
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"\"proxy_send_lowat\" is not supported, ignored");
diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c
index 23d40c493..47d2b17df 100644
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -528,6 +528,7 @@ static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p)
{
ngx_chain_t *cl;
ngx_output_chain_ctx_t *output;
+ ngx_http_proxy_state_e state;
/* reinit the request chain */
@@ -560,11 +561,17 @@ static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p)
/* add one more state */
+ state = p->state->cache_state;
+
if (!(p->state = ngx_push_array(&p->states))) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
+ ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t));
+
+ p->state->cache_state = state;
+
p->status = 0;
p->status_count = 0;
}
@@ -719,9 +726,9 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
writer->out = NULL;
writer->last = &writer->out;
writer->connection = c;
- writer->limit = OFF_T_MAX_VALUE;
+ writer->limit = 0;
- if (p->upstream->peer.tries > 1 && p->request_sent) {
+ if (p->request_sent) {
ngx_http_proxy_reinit_upstream(p);
}
@@ -803,13 +810,13 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
p->request_sent ? NULL:
p->request->request_body->bufs);
+ p->request_sent = 1;
+
if (rc == NGX_ERROR) {
ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR);
return;
}
- p->request_sent = 1;
-
if (c->write->timer_set) {
ngx_del_timer(c->write);
}
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index aa6690265..c882b3006 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -97,6 +97,11 @@ typedef struct {
} ngx_http_cache_t;
+typedef struct {
+ ngx_path_t path;
+ ngx_str_t key;
+} ngx_http_cache_ctx_t;
+
#define NGX_HTTP_CACHE_STALE 1
#define NGX_HTTP_CACHE_AGED 2
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index c4cb8b9f0..e3ccd8ff6 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1815,9 +1815,8 @@ static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
- ssize_t *np = data;
-
#if (NGX_FREEBSD)
+ ssize_t *np = data;
if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -1829,6 +1828,7 @@ static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data)
}
#elif !(NGX_HAVE_SO_SNDLOWAT)
+ ssize_t *np = data;
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"\"send_lowat\" is not supported, ignored");
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index 3fa11086d..31fa82635 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -252,9 +252,7 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r)
* Konqueror keeps the connection alive for about N seconds.
*/
- if (clcf->keepalive_header
- && (r->headers_in.gecko || r->headers_in.konqueror))
- {
+ if (clcf->keepalive_header) {
len += sizeof("Keep-Alive: timeout=") - 1 + TIME_T_LEN + 2;
}
@@ -384,9 +382,7 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r)
b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF,
sizeof("Connection: keep-alive" CRLF) - 1);
- if (clcf->keepalive_header
- && (r->headers_in.gecko || r->headers_in.konqueror))
- {
+ if (clcf->keepalive_header) {
b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF,
clcf->keepalive_header);
}
diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c
index 581a1ce65..fd373444e 100644
--- a/src/http/ngx_http_log_handler.c
+++ b/src/http/ngx_http_log_handler.c
@@ -166,7 +166,10 @@ ngx_int_t ngx_http_log_handler(ngx_http_request_t *r)
len++;
#endif
- ngx_test_null(line, ngx_palloc(r->pool, len), NGX_ERROR);
+ if (!(line = ngx_palloc(r->pool, len))) {
+ return NGX_ERROR;
+ }
+
p = line;
for (i = 0; i < log[l].ops->nelts; i++) {
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 96ed49c74..77db813ae 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -665,6 +665,8 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
u_char c, ch, decoded, *p, *u;
enum {
sw_usual = 0,
+ sw_colon,
+ sw_colon_slash,
sw_slash,
sw_dot,
sw_dot_dot,
@@ -730,9 +732,70 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
case '?':
r->args_start = p;
break;
+ case ':':
+ state = sw_colon;
+ *u++ = ch;
+ break;
case '.':
r->uri_ext = u + 1;
+ *u++ = ch;
+ break;
+ default:
+ *u++ = ch;
+ break;
+ }
+ ch = *p++;
+ break;
+
+ case sw_colon:
+ switch(ch) {
+#if (NGX_WIN32)
+ case '\\':
+ state = sw_colon_slash;
+ *u++ = '/';
+ break;
+#endif
+ case '/':
+ state = sw_colon_slash;
+ *u++ = ch;
+ break;
+ case ':':
+ *u++ = ch;
+ break;
+ case '%':
+ quoted_state = state;
+ state = sw_quoted;
+ break;
default:
+ state = sw_usual;
+ *u++ = ch;
+ break;
+ }
+ ch = *p++;
+ break;
+
+ case sw_colon_slash:
+ switch(ch) {
+#if (NGX_WIN32)
+ case '\\':
+ state = sw_slash;
+ *u++ = '/';
+ break;
+#endif
+ case '/':
+ state = sw_slash;
+ *u++ = ch;
+ break;
+ case '.':
+ state = sw_dot;
+ *u++ = ch;
+ break;
+ case '%':
+ quoted_state = state;
+ state = sw_quoted;
+ break;
+ default:
+ state = sw_usual;
*u++ = ch;
break;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index b6013fcea..fe3d516cf 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1190,8 +1190,9 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
#if 0
/* MSIE ignores the SSL "close notify" alert */
-
- ngx_ssl_set_nosendshut(r->connection->ssl);
+ if (c->ssl) {
+ r->connection->ssl->no_send_shut = 1;
+ }
#endif
}
@@ -1269,7 +1270,7 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
}
if (r->connection->read->pending_eof) {
-#if (NGX_KQUEUE)
+#if (NGX_HAVE_KQUEUE)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log,
r->connection->read->kq_errno,
"kevent() reported about an closed connection");
@@ -1702,24 +1703,26 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
}
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+ tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
} else {
- if (clcf->tcp_nodelay && !c->tcp_nodelay) {
- tcp_nodelay = 1;
+ tcp_nodelay = 1;
+ }
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+ if (tcp_nodelay && clcf->tcp_nodelay && !c->tcp_nodelay) {
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int)) == -1)
- {
- ngx_connection_error(c, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) failed");
- ngx_http_close_connection(c);
- return;
- }
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
- c->tcp_nodelay = 1;
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "setsockopt(TCP_NODELAY) failed");
+ ngx_http_close_connection(c);
+ return;
}
+
+ c->tcp_nodelay = 1;
}
#if 0
@@ -1761,6 +1764,11 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev)
ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
"kevent() reported that client %V closed "
"keepalive connection", ctx->client);
+#if (NGX_HTTP_SSL)
+ if (c->ssl) {
+ c->ssl->no_send_shut = 1;
+ }
+#endif
ngx_http_close_connection(c);
return;
}
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 67f686267..50e8bc249 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -152,8 +152,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
sent = c->sent;
- chain = c->send_chain(c, ctx->out,
- clcf->limit_rate ? clcf->limit_rate: OFF_T_MAX_VALUE);
+ chain = c->send_chain(c, ctx->out, clcf->limit_rate);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http write filter %p", chain);
diff --git a/src/os/unix/ngx_aio_write_chain.c b/src/os/unix/ngx_aio_write_chain.c
index 4d45f079a..c1109dc12 100644
--- a/src/os/unix/ngx_aio_write_chain.c
+++ b/src/os/unix/ngx_aio_write_chain.c
@@ -20,6 +20,12 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in,
ngx_err_t err;
ngx_chain_t *cl;
+ /* the maximum limit size is the maximum size_t value - the page size */
+
+ if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
+ limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+ }
+
send = 0;
sent = 0;
cl = in;
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 03de946a3..be9cebe6f 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -104,7 +104,7 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
#else
#define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name)
#endif
-#define ngx_de_info(name, dir) stat((const char *) name, &(dir)->info)
+#define ngx_de_info(name, dir) lstat((const char *) name, &(dir)->info)
#define ngx_de_info_n "stat()"
#define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode))
#define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode))
diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c
index b76dc0cb9..044d9d5c9 100644
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -204,6 +204,9 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
}
+ ngx_tcp_nodelay_and_tcp_nopush = 1;
+
+
return ngx_posix_init(log);
}
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index f86e1c0d7..187365cb2 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -37,9 +37,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
{
int rc;
u_char *prev;
- off_t fprev, sent, send, sprev, aligned;
- size_t hsize, fsize;
- ssize_t size;
+ off_t size, send, prev_send, aligned, sent, fprev;
+ size_t header_size, file_size;
ngx_uint_t eintr, eagain, complete;
ngx_err_t err;
ngx_buf_t *file;
@@ -67,6 +66,12 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
#endif
+ /* the maximum limit size is the maximum size_t value - the page size */
+
+ if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
+ limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+ }
+
send = 0;
eagain = 0;
@@ -82,11 +87,11 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
for ( ;; ) {
file = NULL;
- fsize = 0;
- hsize = 0;
+ file_size = 0;
+ header_size = 0;
eintr = 0;
complete = 0;
- sprev = send;
+ prev_send = send;
header.nelts = 0;
trailer.nelts = 0;
@@ -115,7 +120,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (prev == cl->buf->pos) {
- iov->iov_len += size;
+ iov->iov_len += (size_t) size;
} else {
if (!(iov = ngx_array_push(&header))) {
@@ -123,11 +128,11 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = size;
+ iov->iov_len = (size_t) size;
}
- prev = cl->buf->pos + size;
- hsize += size;
+ prev = cl->buf->pos + (size_t) size;
+ header_size += (size_t) size;
send += size;
}
@@ -138,7 +143,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
/* coalesce the neighbouring file bufs */
do {
- size = (size_t) (cl->buf->file_last - cl->buf->file_pos);
+ size = cl->buf->file_last - cl->buf->file_pos;
if (send + size > limit) {
size = limit - send;
@@ -151,7 +156,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
}
- fsize += size;
+ file_size += (size_t) size;
send += size;
fprev = cl->buf->file_pos + size;
cl = cl->next;
@@ -189,7 +194,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (prev == cl->buf->pos) {
- iov->iov_len += size;
+ iov->iov_len += (size_t) size;
} else {
if (!(iov = ngx_array_push(&trailer))) {
@@ -197,10 +202,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = size;
+ iov->iov_len = (size_t) size;
}
- prev = cl->buf->pos + size;
+ prev = cl->buf->pos + (size_t) size;
send += size;
cl = cl->next;
}
@@ -245,13 +250,13 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
*/
if (ngx_freebsd_sendfile_nbytes_bug == 0) {
- hsize = 0;
+ header_size = 0;
}
sent = 0;
rc = sendfile(file->file->fd, c->fd, file->file_pos,
- fsize + hsize, &hdtr, &sent, 0);
+ file_size + header_size, &hdtr, &sent, 0);
if (rc == -1) {
err = ngx_errno;
@@ -265,8 +270,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() sent only %O bytes",
- sent);
+ "sendfile() sent only %O bytes", sent);
} else {
wev->error = 1;
@@ -291,13 +295,13 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"sendfile: %d, @%O %O:%uz",
- rc, file->file_pos, sent, fsize + hsize);
+ rc, file->file_pos, sent, file_size + header_size);
} else {
rc = writev(c->fd, header.elts, header.nelts);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "writev: %d of %uz", rc, hsize);
+ "writev: %d of %uz", rc, header_size);
if (rc == -1) {
err = ngx_errno;
@@ -320,7 +324,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
sent = rc > 0 ? rc : 0;
}
- if (send - sprev == sent) {
+ if (send - prev_send == sent) {
complete = 1;
}
@@ -353,7 +357,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (ngx_buf_in_memory(cl->buf)) {
- cl->buf->pos += sent;
+ cl->buf->pos += (size_t) sent;
}
if (cl->buf->in_file) {
diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c
index bcf9d4c76..c09d03675 100644
--- a/src/os/unix/ngx_linux_sendfile_chain.c
+++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -25,11 +25,10 @@
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit)
{
- int rc;
+ int rc, tcp_nodelay;
u_char *prev;
- off_t fprev, send, sprev, aligned;
- size_t fsize;
- ssize_t size, sent;
+ off_t size, send, prev_send, aligned, sent, fprev;
+ size_t file_size;
ngx_uint_t eintr, complete;
ngx_err_t err;
ngx_buf_t *file;
@@ -49,6 +48,14 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
return in;
}
+
+ /* the maximum limit size is the maximum size_t value - the page size */
+
+ if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
+ limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+ }
+
+
send = 0;
header.elts = headers;
@@ -58,10 +65,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
for ( ;; ) {
file = NULL;
- fsize = 0;
+ file_size = 0;
eintr = 0;
complete = 0;
- sprev = send;
+ prev_send = send;
header.nelts = 0;
@@ -89,7 +96,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (prev == cl->buf->pos) {
- iov->iov_len += size;
+ iov->iov_len += (size_t) size;
} else {
if (!(iov = ngx_array_push(&header))) {
@@ -97,10 +104,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = size;
+ iov->iov_len = (size_t) size;
}
- prev = cl->buf->pos + size;
+ prev = cl->buf->pos + (size_t) size;
send += size;
}
@@ -111,25 +118,62 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
&& cl
&& cl->buf->in_file)
{
- if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
- err = ngx_errno;
- /*
- * there is a tiny chance to be interrupted, however
- * we continue a processing without the TCP_CORK
- */
+ /* the TCP_CORK and TCP_NODELAY are mutually exclusive */
- if (err != NGX_EINTR) {
- wev->error = 1;
- ngx_connection_error(c, err, ngx_tcp_nopush_n " failed");
- return NGX_CHAIN_ERROR;
+ if (c->tcp_nodelay) {
+
+ tcp_nodelay = 0;
+
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
+ {
+ err = ngx_errno;
+
+ /*
+ * there is a tiny chance to be interrupted, however
+ * we continue a processing with the TCP_NODELAY
+ * and without the TCP_CORK
+ */
+
+ if (err != NGX_EINTR) {
+ wev->error = 1;
+ ngx_connection_error(c, ngx_socket_errno,
+ "setsockopt(TCP_NODELAY) failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ } else {
+ c->tcp_nodelay = 0;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "no tcp_nodelay");
}
+ }
- } else {
- c->tcp_nopush = NGX_TCP_NOPUSH_SET;
+ if (!c->tcp_nodelay) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "tcp_nopush");
+ if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
+ err = ngx_errno;
+
+ /*
+ * there is a tiny chance to be interrupted, however
+ * we continue a processing without the TCP_CORK
+ */
+
+ if (err != NGX_EINTR) {
+ wev->error = 1;
+ ngx_connection_error(c, err,
+ ngx_tcp_nopush_n " failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ } else {
+ c->tcp_nopush = NGX_TCP_NOPUSH_SET;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "tcp_nopush");
+ }
}
}
@@ -141,7 +185,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
/* coalesce the neighbouring file bufs */
do {
- size = (size_t) (cl->buf->file_last - cl->buf->file_pos);
+ size = cl->buf->file_last - cl->buf->file_pos;
if (send + size > limit) {
size = limit - send;
@@ -154,7 +198,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
}
- fsize += size;
+ file_size += (size_t) size;
send += size;
fprev = cl->buf->file_pos + size;
cl = cl->next;
@@ -172,7 +216,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
#else
offset = (int32_t) file->file_pos;
#endif
- rc = sendfile(c->fd, file->file->fd, &offset, fsize);
+ rc = sendfile(c->fd, file->file->fd, &offset, file_size);
if (rc == -1) {
err = ngx_errno;
@@ -195,8 +239,8 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
sent = rc > 0 ? rc : 0;
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfile: %d, @%O %z:%uz",
- rc, file->file_pos, sent, fsize);
+ "sendfile: %d, @%O %O:%uz",
+ rc, file->file_pos, sent, file_size);
} else {
rc = writev(c->fd, header.elts, header.nelts);
@@ -221,10 +265,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
sent = rc > 0 ? rc : 0;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent);
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent);
}
- if (send - sprev == sent) {
+ if (send - prev_send == sent) {
complete = 1;
}
@@ -257,7 +301,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (ngx_buf_in_memory(cl->buf)) {
- cl->buf->pos += sent;
+ cl->buf->pos += (size_t) sent;
}
if (cl->buf->in_file) {
diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h
index ee91df336..42fc88629 100644
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -50,7 +50,8 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in,
extern ngx_os_io_t ngx_os_io;
extern ngx_int_t ngx_ncpu;
extern ngx_int_t ngx_max_sockets;
-extern ngx_int_t ngx_inherited_nonblocking;
+extern ngx_uint_t ngx_inherited_nonblocking;
+extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
#define ngx_stderr_fileno STDERR_FILENO
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index 56be0cefb..626d821e9 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -8,9 +8,10 @@
#include <ngx_core.h>
-ngx_int_t ngx_ncpu;
-ngx_int_t ngx_max_sockets;
-ngx_int_t ngx_inherited_nonblocking;
+ngx_int_t ngx_ncpu;
+ngx_int_t ngx_max_sockets;
+ngx_uint_t ngx_inherited_nonblocking;
+ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
struct rlimit rlmt;
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 3d1c51bc0..c3b9905b0 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -17,7 +17,7 @@ static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle);
static void ngx_master_exit(ngx_cycle_t *cycle);
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
-static void ngx_worker_process_init(ngx_cycle_t *cycle);
+static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority);
static void ngx_channel_handler(ngx_event_t *ev);
#if (NGX_THREADS)
static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle);
@@ -564,6 +564,33 @@ static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle)
continue;
}
+
+ ch.command = NGX_CMD_OPEN_CHANNEL;
+ ch.pid = ngx_processes[ngx_process_slot].pid;
+ ch.slot = ngx_process_slot;
+ ch.fd = ngx_processes[ngx_process_slot].channel[0];
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (n == ngx_process_slot
+ || ngx_processes[n].pid == -1
+ || ngx_processes[n].channel[0] == -1)
+ {
+ continue;
+ }
+
+ ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d",
+ ch.slot, ch.pid, ch.fd,
+ n, ngx_processes[n].pid,
+ ngx_processes[n].channel[0]);
+
+ /* TODO: NGX_AGAIN */
+
+ ngx_write_channel(ngx_processes[n].channel[0],
+ &ch, sizeof(ngx_channel_t), cycle->log);
+ }
+
live = 1;
continue;
@@ -611,7 +638,7 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
ngx_err_t err;
ngx_core_conf_t *ccf;
- ngx_worker_process_init(cycle);
+ ngx_worker_process_init(cycle, 1);
ngx_setproctitle("worker process");
@@ -718,7 +745,7 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
}
-static void ngx_worker_process_init(ngx_cycle_t *cycle)
+static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
{
sigset_t set;
ngx_int_t n;
@@ -739,6 +766,13 @@ static void ngx_worker_process_init(ngx_cycle_t *cycle)
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (geteuid() == 0) {
+ if (priority && ccf->priority != 0) {
+ if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "setpriority(%d) failed", ccf->priority);
+ }
+ }
+
if (setgid(ccf->group) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setgid(%d) failed", ccf->group);
@@ -746,6 +780,12 @@ static void ngx_worker_process_init(ngx_cycle_t *cycle)
exit(2);
}
+ if (initgroups(ccf->username, ccf->group) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "initgroups(%s, %d) failed",
+ ccf->username, ccf->group);
+ }
+
if (setuid(ccf->user) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setuid(%d) failed", ccf->user);
@@ -1041,7 +1081,7 @@ static void ngx_garbage_collector_cycle(ngx_cycle_t *cycle, void *data)
ngx_path_t **path;
ngx_event_t *ev;
- ngx_worker_process_init(cycle);
+ ngx_worker_process_init(cycle, 0);
ev = &cycle->read_events[ngx_channel];
diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c
index 21f8b8f7c..4c873aa11 100644
--- a/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -9,6 +9,28 @@
#include <ngx_event.h>
+#if (NGX_TEST_BUILD_SOLARIS_SENDFILEV)
+
+/* Solaris declarations */
+
+typedef struct sendfilevec {
+ int sfv_fd;
+ u_int sfv_flag;
+ off_t sfv_off;
+ size_t sfv_len;
+} sendfilevec_t;
+
+#define SFV_FD_SELF -2
+
+static ssize_t sendfilev(int fd, const struct sendfilevec *vec,
+ int sfvcnt, size_t *xferred)
+{
+ return -1;
+}
+
+#endif
+
+
#define NGX_SENDFILEVECS 16
@@ -17,8 +39,9 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
{
int fd;
u_char *prev;
- off_t fprev, sprev, send, aligned;
- ssize_t size, sent, n;
+ off_t size, send, prev_send, aligned, fprev;
+ size_t sent;
+ ssize_t n;
ngx_int_t eintr, complete;
ngx_err_t err;
sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS];
@@ -36,6 +59,14 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
return ngx_writev_chain(c, in, limit);
}
+
+ /* the maximum limit size is the maximum size_t value - the page size */
+
+ if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
+ limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+ }
+
+
send = 0;
complete = 0;
@@ -51,7 +82,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
sfv = NULL;
eintr = 0;
sent = 0;
- sprev = send;
+ prev_send = send;
vec.nelts = 0;
@@ -73,7 +104,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (prev == cl->buf->pos) {
- sfv->sfv_len += size;
+ sfv->sfv_len += (size_t) size;
} else {
if (!(sfv = ngx_array_push(&vec))) {
@@ -83,16 +114,16 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
sfv->sfv_fd = SFV_FD_SELF;
sfv->sfv_flag = 0;
sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos;
- sfv->sfv_len = size;
+ sfv->sfv_len = (size_t) size;
}
- prev = cl->buf->pos + size;
+ prev = cl->buf->pos + (size_t) size;
send += size;
} else {
prev = NULL;
- size = (size_t) (cl->buf->file_last - cl->buf->file_pos);
+ size = cl->buf->file_last - cl->buf->file_pos;
if (send + size > limit) {
size = limit - send;
@@ -106,7 +137,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
}
if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) {
- sfv->sfv_len += size;
+ sfv->sfv_len += (size_t) size;
} else {
if (!(sfv = ngx_array_push(&vec))) {
@@ -117,7 +148,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
sfv->sfv_fd = fd;
sfv->sfv_flag = 0;
sfv->sfv_off = cl->buf->file_pos;
- sfv->sfv_len = size;
+ sfv->sfv_len = (size_t) size;
}
fprev = cl->buf->file_pos + size;
@@ -136,7 +167,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfilev() sent only %z bytes", sent);
+ "sendfilev() sent only %uz bytes", sent);
} else {
wev->error = 1;
@@ -148,7 +179,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"sendfilev: %z %z", n, sent);
- if (send - sprev == sent) {
+ if (send - prev_send == (off_t) sent) {
complete = 1;
}
@@ -166,8 +197,8 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
size = ngx_buf_size(cl->buf);
- if (sent >= size) {
- sent -= size;
+ if ((off_t) sent >= size) {
+ sent = (size_t) ((off_t) sent - size);
if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
index 2af64699b..8f1087b26 100644
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -16,7 +16,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{
u_char *prev;
ssize_t n, size, sent;
- off_t send, sprev;
+ off_t send, prev_send;
ngx_uint_t eintr, complete;
ngx_err_t err;
ngx_array_t vec;
@@ -42,6 +42,12 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
#endif
+ /* the maximum limit size is the maximum size_t value - the page size */
+
+ if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
+ limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+ }
+
send = 0;
complete = 0;
@@ -54,7 +60,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
prev = NULL;
iov = NULL;
eintr = 0;
- sprev = send;
+ prev_send = send;
vec.nelts = 0;
@@ -118,7 +124,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent);
- if (send - sprev == sent) {
+ if (send - prev_send == sent) {
complete = 1;
}
diff --git a/src/os/win32/ngx_errno.c b/src/os/win32/ngx_errno.c
index 8e9280d92..268ed5261 100644
--- a/src/os/win32/ngx_errno.c
+++ b/src/os/win32/ngx_errno.c
@@ -43,7 +43,11 @@ static ngx_str_t wsa_errors[] = {
ngx_null_string, /* 10039 */
ngx_null_string, /* 10040 */
ngx_null_string, /* 10041 */
- ngx_null_string, /* 10042 */
+
+ /* WSAENOPROTOOPT 10042 */
+ ngx_string("An unknown, invalid, or unsupported option or level was "
+ "specified in a getsockopt or setsockopt call"),
+
ngx_null_string, /* 10043 */
ngx_null_string, /* 10044 */
ngx_null_string, /* 10045 */
diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h
index 6d720fa58..611f7ef5c 100644
--- a/src/os/win32/ngx_os.h
+++ b/src/os/win32/ngx_os.h
@@ -48,6 +48,7 @@ extern ngx_uint_t ngx_ncpu;
extern ngx_uint_t ngx_max_wsabufs;
extern ngx_int_t ngx_max_sockets;
extern ngx_uint_t ngx_inherited_nonblocking;
+extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
extern ngx_uint_t ngx_win32_version;
extern ngx_fd_t ngx_stderr_fileno;
diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h
index c7703c29e..79cea3f4f 100644
--- a/src/os/win32/ngx_win32_config.h
+++ b/src/os/win32/ngx_win32_config.h
@@ -141,5 +141,10 @@ typedef uint32_t ngx_atomic_t;
#define NGX_HAVE_SENDFILE 1
#endif
+#ifndef NGX_HAVE_SO_SNDLOWAT
+/* setsockopt(SO_SNDLOWAT) returns error WSAENOPROTOOPT */
+#define NGX_HAVE_SO_SNDLOWAT 0
+#endif
+
#endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c
index cb8c93128..2b8891321 100644
--- a/src/os/win32/ngx_win32_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -13,6 +13,8 @@ ngx_uint_t ngx_ncpu;
ngx_uint_t ngx_max_wsabufs;
ngx_int_t ngx_max_sockets;
ngx_uint_t ngx_inherited_nonblocking = 1;
+ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
+
ngx_fd_t ngx_stderr_fileno;
diff --git a/src/os/win32/ngx_wsasend_chain.c b/src/os/win32/ngx_wsasend_chain.c
index 1d75e0969..d5b1334a1 100644
--- a/src/os/win32/ngx_wsasend_chain.c
+++ b/src/os/win32/ngx_wsasend_chain.c
@@ -17,7 +17,7 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
{
int rc;
u_char *prev;
- u_long size, sent, send, sprev;
+ u_long size, sent, send, prev_send;
ngx_uint_t complete;
ngx_err_t err;
ngx_event_t *wev;
@@ -32,6 +32,12 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
return in;
}
+ /* the maximum limit size is the maximum u_long value - the page size */
+
+ if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) {
+ limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
+ }
+
send = 0;
complete = 0;
@@ -48,7 +54,7 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
for ( ;; ) {
prev = NULL;
wsabuf = NULL;
- sprev = send;
+ prev_send = send;
vec.nelts = 0;
@@ -105,7 +111,7 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSASend: fd:%d, s:%ul", c->fd, sent);
- if (send - sprev == sent) {
+ if (send - prev_send == sent) {
complete = 1;
}
@@ -153,8 +159,7 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
{
int rc;
u_char *prev;
- size_t size;
- u_long send, sent;
+ u_long size, send, sent;
LPWSABUF wsabuf;
ngx_err_t err;
ngx_event_t *wev;
@@ -175,6 +180,12 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
if (!wev->complete) {
/* post the overlapped WSASend() */
+
+ /* the maximum limit size is the maximum u_long value - the page size */
+
+ if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) {
+ limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
+ }
/*
* WSABUFs must be 4-byte aligned otherwise