nginx-0.1.11-RELEASE import

*) 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
       ":/".
This commit is contained in:
Igor Sysoev 2004-12-02 18:40:46 +00:00
parent 4e7b11b02b
commit 42b12b34fa
49 changed files with 988 additions and 359 deletions

View File

@ -45,6 +45,11 @@ if [ $NGX_TEST_BUILD_RTSIG = YES ]; then
CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
fi 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 # the filter order is important
# ngx_http_write_filter # ngx_http_write_filter

View File

@ -25,6 +25,7 @@ CPU=NO
NGX_TEST_BUILD_DEVPOLL=NO NGX_TEST_BUILD_DEVPOLL=NO
NGX_TEST_BUILD_EPOLL=NO NGX_TEST_BUILD_EPOLL=NO
NGX_TEST_BUILD_RTSIG=NO NGX_TEST_BUILD_RTSIG=NO
NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO
NGX_PLATFORM= NGX_PLATFORM=
NGX_WINE= NGX_WINE=
@ -146,6 +147,7 @@ do
--test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;; --test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;;
--test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;; --test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;;
--test-build-rtsig) NGX_TEST_BUILD_RTSIG=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\"" echo "$0: error: invalid option \"$option\""
@ -212,11 +214,6 @@ if test -z "$NGX_PREFIX"; then
fi fi
if test -z "$NGX_GROUP"; then
NGX_GROUP=NGX_USER
fi
case ".$NGX_SBIN_PATH" in case ".$NGX_SBIN_PATH" in
./*) ./*)
;; ;;

View File

@ -47,7 +47,26 @@ if [ $NGX_PLATFORM != win32 ]; then
if test -z "$NGX_USER"; then if test -z "$NGX_USER"; then
NGX_USER=nobody 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 fi

View File

@ -21,12 +21,6 @@ ngx_spacer='
CC_AUX_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" 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 # Linux kernel version
version=`grep "#define LINUX_VERSION_CODE" /usr/include/linux/version.h \ version=`grep "#define LINUX_VERSION_CODE" /usr/include/linux/version.h \

View File

@ -7,3 +7,5 @@ cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_param #ifndef $ngx_param
#define $ngx_param $ngx_value #define $ngx_param $ngx_value
#endif #endif
END

View File

@ -43,31 +43,15 @@ ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
. auto/endianess . 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_type="time_t"; . auto/types/sizeof
#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_param=TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value 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 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 # syscalls, libc calls and some features

View File

@ -6,6 +6,147 @@
title="nginx"> 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"> <changes ver="0.1.10" date="26.11.2004">
<change type="bugfix"> <change type="bugfix">
@ -23,11 +164,10 @@ bug appeared in 0.1.9.
<change type="bugfix"> <change type="bugfix">
<para lang="ru"> <para lang="ru">
ÉÓÐÒÁ×ÌÅÎÉÅ × ×ÅÒÓÉÉ 0.1.9 ÄÌÑ ÆÁÊÌÏ× ÂÏÌØÛÅ ÎÁ Linux ÎÅ ÒÁÂÏÔÁÌÏ. ÉÓÐÒÁ×ÌÅÎÉÅ × ×ÅÒÓÉÉ 0.1.9 ÄÌÑ ÆÁÊÌÏ× ÂÏÌØÛÅ 2G ÎÁ Linux ÎÅ ÒÁÂÏÔÁÌÏ.
</para> </para>
<para lang="en"> <para lang="en">
the fix in 0.1.9 for the files bigger than 2G on Linux the fix in 0.1.9 for the files bigger than 2G on Linux did not work.
did not work.
</para> </para>
</change> </change>
@ -123,7 +263,7 @@ the proxy_max_temp_file_size directive.
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.1.5. ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.1.5.
</para> </para>
<para lang="en"> <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; file was changed;
bug appeared in 0.1.5. bug appeared in 0.1.5.
</para> </para>

View File

@ -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 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_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_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[] = { static ngx_conf_enum_t ngx_debug_points[] = {
@ -80,6 +81,13 @@ static ngx_command_t ngx_core_commands[] = {
0, 0,
NULL }, NULL },
{ ngx_string("worker_priority"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_set_priority,
0,
0,
NULL },
{ ngx_string("pid"), { ngx_string("pid"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot, ngx_conf_set_str_slot,
@ -447,6 +455,7 @@ static void *ngx_core_module_create_conf(ngx_cycle_t *cycle)
* *
* ccf->pid = NULL; * ccf->pid = NULL;
* ccf->newpid = NULL; * ccf->newpid = NULL;
* ccf->priority = 0;
*/ */
ccf->daemon = NGX_CONF_UNSET; ccf->daemon = NGX_CONF_UNSET;
ccf->master = 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; return NGX_CONF_ERROR;
} }
ccf->username = NGX_USER;
ccf->user = pwd->pw_uid; ccf->user = pwd->pw_uid;
grp = getgrnam(NGX_GROUP); 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; value = (ngx_str_t *) cf->args->elts;
ccf->username = (char *) value[1].data;
pwd = getpwnam((const char *) value[1].data); pwd = getpwnam((const char *) value[1].data);
if (pwd == NULL) { if (pwd == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, 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 #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;
}

View File

@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_ #define _NGINX_H_INCLUDED_
#define NGINX_VER "nginx/0.1.10" #define NGINX_VER "nginx/0.1.11"
#define NGINX_VAR "NGINX" #define NGINX_VAR "NGINX"
#define NGX_NEWPID_EXT ".newbin" #define NGX_NEWPID_EXT ".newbin"

View File

@ -109,8 +109,8 @@ typedef struct {
((b->flush || b->last_buf) && !ngx_buf_in_memory(b) && !b->in_file) ((b->flush || b->last_buf) && !ngx_buf_in_memory(b) && !b->in_file)
#define ngx_buf_size(b) \ #define ngx_buf_size(b) \
(ngx_buf_in_memory(b) ? (size_t) (b->last - b->pos): \ (ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
(size_t) (b->file_last - b->file_pos)) (b->file_last - b->file_pos))
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size); 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); ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);

View File

@ -39,6 +39,11 @@
#endif #endif
#ifndef NGX_HAVE_SO_SNDLOWAT
#define NGX_HAVE_SO_SNDLOWAT 1
#endif
#if !(NGX_WIN32) #if !(NGX_WIN32)
#define ngx_signal_helper(n) SIG##n #define ngx_signal_helper(n) SIG##n

View File

@ -50,7 +50,6 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
ngx_open_file_t *file; ngx_open_file_t *file;
ngx_listening_t *ls, *nls; ngx_listening_t *ls, *nls;
ngx_core_conf_t *ccf; ngx_core_conf_t *ccf;
ngx_event_conf_t *ecf;
ngx_core_module_t *module; ngx_core_module_t *module;
log = old_cycle->log; 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 and delete stuff that lefts from an old cycle */
/* close the unneeded listening sockets */ /* close the unneeded listening sockets */

View File

@ -17,51 +17,54 @@
struct ngx_cycle_s { struct ngx_cycle_s {
void ****conf_ctx; void ****conf_ctx;
ngx_pool_t *pool; ngx_pool_t *pool;
ngx_log_t *log; ngx_log_t *log;
ngx_log_t *new_log; ngx_log_t *new_log;
ngx_array_t listening; ngx_array_t listening;
ngx_array_t pathes; ngx_array_t pathes;
ngx_list_t open_files; ngx_list_t open_files;
ngx_uint_t connection_n; ngx_uint_t connection_n;
ngx_connection_t *connections; ngx_connection_t *connections;
ngx_event_t *read_events; ngx_event_t *read_events;
ngx_event_t *write_events; ngx_event_t *write_events;
ngx_cycle_t *old_cycle; ngx_cycle_t *old_cycle;
ngx_str_t conf_file; ngx_str_t conf_file;
ngx_str_t root; ngx_str_t root;
}; };
typedef struct { typedef struct {
ngx_flag_t daemon; ngx_flag_t daemon;
ngx_flag_t master; ngx_flag_t master;
ngx_int_t worker_processes; ngx_int_t worker_processes;
ngx_int_t debug_points; ngx_int_t debug_points;
ngx_uid_t user; int priority;
ngx_gid_t group;
ngx_str_t pid; char *username;
ngx_str_t newpid; ngx_uid_t user;
ngx_gid_t group;
ngx_str_t pid;
ngx_str_t newpid;
#if (NGX_THREADS) #if (NGX_THREADS)
ngx_int_t worker_threads; ngx_int_t worker_threads;
size_t thread_stack_size; size_t thread_stack_size;
#endif #endif
} ngx_core_conf_t; } ngx_core_conf_t;
typedef struct { typedef struct {
ngx_pool_t *pool; /* pcre's malloc() pool */ ngx_pool_t *pool; /* pcre's malloc() pool */
} ngx_core_tls_t; } ngx_core_tls_t;

View File

@ -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) ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
{ {
int rc, last; int rc, last;
size_t size, bsize; off_t bsize;
size_t size;
ngx_chain_t *cl, *out, **last_out; ngx_chain_t *cl, *out, **last_out;
if (ctx->in == NULL && ctx->busy == NULL) { 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, ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
"zero size buf"); "zero size buf");
ngx_debug_point();
ctx->in = ctx->in->next; ctx->in = ctx->in->next;
continue; 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 (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 * allocate small temp buf for the small last buf
* or its small last part * or its small last part
*/ */
size = bsize; size = (size_t) bsize;
} else if (ctx->bufs.num == 1 } else if (ctx->bufs.num == 1
&& (bsize < ctx->bufs.size && (bsize < (off_t) (ctx->bufs.size
+ (ctx->bufs.size >> 2))) + (ctx->bufs.size >> 2))))
{ {
/* /*
* allocate a temp buf that equals * 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 * 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, static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
ngx_uint_t sendfile) ngx_uint_t sendfile)
{ {
size_t size; off_t size;
ssize_t n; ssize_t n;
size = ngx_buf_size(src); size = ngx_buf_size(src);
if (size > (size_t) (dst->end - dst->pos)) { if (size > dst->end - dst->pos) {
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 #endif
if (ngx_buf_in_memory(src)) { if (ngx_buf_in_memory(src)) {
ngx_memcpy(dst->pos, src->pos, size); ngx_memcpy(dst->pos, src->pos, (size_t) size);
src->pos += size; src->pos += (size_t) size;
dst->last += size; dst->last += (size_t) size;
if (src->in_file) { 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 { } 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) { if (n == NGX_ERROR) {
return n; return n;
@ -363,9 +366,9 @@ static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
} }
#endif #endif
if ((size_t) n != size) { if (n != size) {
ngx_log_error(NGX_LOG_ALERT, src->file->log, 0, 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); n, size);
if (n == 0) { if (n == 0) {
return NGX_ERROR; 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; ngx_chain_writer_ctx_t *ctx = data;
off_t size;
ngx_chain_t *cl; 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, ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
"chain writer buf size: %uz", ngx_buf_size(in->buf)); "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, ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
"chain writer in: %p", ctx->out); "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); ctx->out = ngx_send_chain(ctx->connection, ctx->out, ctx->limit);
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,

View File

@ -30,7 +30,7 @@ u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n)
/* /*
* supported formats: * supported formats:
* %[0][width]O off_t * %[0][width][x][X]O off_t
* %[0][width]T time_t * %[0][width]T time_t
* %[0][width][u][x|X]z ssize_t/size_t * %[0][width][u][x|X]z ssize_t/size_t
* %[0][width][u][x|X]d int/u_int * %[0][width][u][x|X]d int/u_int

View File

@ -434,6 +434,16 @@ int ngx_devpoll_process_events(ngx_cycle_t *cycle)
for (i = 0; i < events; i++) { for (i = 0; i < events; i++) {
c = &ngx_cycle->connections[event_list[i].fd]; 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) { if (c->fd == -1) {
old_cycle = ngx_old_cycles.elts; old_cycle = ngx_old_cycles.elts;
for (j = 0; j < ngx_old_cycles.nelts; j++) { for (j = 0; j < ngx_old_cycles.nelts; j++) {
@ -451,6 +461,7 @@ int ngx_devpoll_process_events(ngx_cycle_t *cycle)
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "unknown cycle"); ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "unknown cycle");
exit(1); exit(1);
} }
#endif
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"devpoll: fd:%d, ev:%04Xd, rev:%04Xd", "devpoll: fd:%d, ev:%04Xd, rev:%04Xd",

View File

@ -174,10 +174,25 @@ static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
{ {
#if !(NGX_WIN32) #if !(NGX_WIN32)
size_t size; size_t size;
char *shared; void ***cf;
ngx_core_conf_t *ccf; char *shared;
ngx_event_conf_t *ecf; 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); 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; return NGX_OK;
} }
ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
/* TODO: 128 is cache line size */ /* TODO: 128 is cache line size */

View File

@ -81,9 +81,12 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc)
for ( ;; ) { for ( ;; ) {
peer = &pc->peers->peers[pc->cur_peer]; peer = &pc->peers->peers[pc->cur_peer];
if (peer->fails <= pc->peers->max_fails if (peer->fails <= pc->peers->max_fails) {
|| (now - peer->accessed > pc->peers->fail_timeout)) break;
{ }
if (now - peer->accessed > pc->peers->fail_timeout) {
peer->fails = 0;
break; break;
} }

View File

@ -9,7 +9,9 @@
#include <ngx_event.h> #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 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) 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); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);
if (n > 0) { 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; 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) { if (sslerr == SSL_ERROR_WANT_WRITE) {
ngx_log_error(NGX_LOG_ALERT, c->log, err, ngx_log_error(NGX_LOG_ALERT, c->log, err,
"SSL wants to write%s", handshake); "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; return NGX_AGAIN;
#endif
} }
c->ssl->no_rcv_shut = 1; c->ssl->no_rcv_shut = 1;
c->ssl->no_send_shut = 1;
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
ngx_log_error(NGX_LOG_INFO, c->log, err, 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 * 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 * Besides for protocols such as HTTP it is possible to always buffer
* the output to decrease a SSL overhead some more. * 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; 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; send = 0;
flush = (in == NULL) ? 1 : 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); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
if (n > 0) { 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; 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, ngx_log_error(NGX_LOG_ALERT, c->log, err,
"SSL wants to read%s", handshake); "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; return NGX_AGAIN;
#endif
} }
c->ssl->no_rcv_shut = 1; c->ssl->no_rcv_shut = 1;
c->ssl->no_send_shut = 1;
ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed"); 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) ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
{ {
int n, sslerr; int n, sslerr, mode;
ngx_uint_t again; ngx_uint_t again;
if (c->timedout) { if (!c->ssl->shutdown_set) {
SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN);
} else { /* it seems that SSL_set_shutdown() could be called once only */
if (c->ssl->no_rcv_shut) {
SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); 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) { if (mode) {
SSL_set_shutdown(c->ssl->ssl, SSL_SENT_SHUTDOWN); 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); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
if (n == 0) { if (n == 1 || (n == 0 && c->read->timedout)) {
again = 1;
break;
}
if (n == 1) {
SSL_free(c->ssl->ssl); SSL_free(c->ssl->ssl);
c->ssl = NULL; c->ssl = NULL;
return NGX_OK; return NGX_OK;
} }
if (n == 0) {
again = 1;
break;
}
break; break;
} }
@ -342,7 +449,7 @@ ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
if (again || sslerr == SSL_ERROR_WANT_READ) { 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) { if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
return NGX_ERROR; return NGX_ERROR;

View File

@ -18,11 +18,13 @@
typedef struct { typedef struct {
SSL *ssl; SSL *ssl;
ngx_buf_t *buf; 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 buffer:1;
unsigned no_rcv_shut:1; unsigned no_rcv_shut:1;
unsigned no_send_shut:1; unsigned no_send_shut:1;
unsigned shutdown_set:1;
} ngx_ssl_t; } 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, void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
char *fmt, ...); char *fmt, ...);
#define ngx_ssl_set_nosendshut(ssl) \
if (ssl) { \
ssl->no_send_shut = 1; \
}
#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */ #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */

View File

@ -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) 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_uint_t flush;
ngx_buf_t *b; ngx_buf_t *b;
ngx_chain_t *out, **ll, *cl, *tl; 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, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe write busy: %uz", bsize); "pipe write busy: %O", bsize);
out = NULL; out = NULL;
ll = NULL; ll = NULL;

View File

@ -62,7 +62,7 @@ struct ngx_event_pipe_s {
ngx_bufs_t bufs; ngx_bufs_t bufs;
ngx_buf_tag_t tag; ngx_buf_tag_t tag;
size_t busy_size; ssize_t busy_size;
off_t read_length; off_t read_length;

View File

@ -105,11 +105,10 @@ static u_char tail[] =
static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r) static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r)
{ {
u_char *last, scale; u_char *last;
size_t len; size_t len;
off_t length;
ngx_tm_t tm; ngx_tm_t tm;
ngx_int_t rc, size; ngx_int_t rc;
ngx_uint_t i, level; ngx_uint_t i, level;
ngx_err_t err; ngx_err_t err;
ngx_buf_t *b; 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 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
+ sizeof("</a>") - 1 + sizeof("</a>") - 1
+ sizeof(" 28-Sep-1970 12:00 ") - 1 + sizeof(" 28-Sep-1970 12:00 ") - 1
+ sizeof("1023G") - 1 + 19
+ 2; + 2;
} }
@ -383,44 +382,11 @@ static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r)
tm.ngx_tm_min); tm.ngx_tm_min);
if (entry[i].dir) { if (entry[i].dir) {
b->last = ngx_cpymem(b->last, " -", sizeof(" -") - 1); b->last = ngx_cpymem(b->last, " -",
sizeof(" -") - 1);
} else { } else {
length = entry[i].size; b->last = ngx_sprintf(b->last, "%19O", 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++ = CR; *b->last++ = CR;

View File

@ -63,7 +63,7 @@ static ngx_int_t ngx_http_chunked_body_filter(ngx_http_request_t *r,
ngx_chain_t *in) ngx_chain_t *in)
{ {
u_char *chunk; u_char *chunk;
size_t size; off_t size;
ngx_buf_t *b; ngx_buf_t *b;
ngx_chain_t out, tail, *cl, *tl, **ll; 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; 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; return NGX_ERROR;
} }
b->temporary = 1; b->temporary = 1;
b->pos = chunk; b->pos = chunk;
b->last = ngx_sprintf(chunk, "%xz" CRLF, size); b->last = ngx_sprintf(chunk, "%xO" CRLF, size);
out.buf = b; out.buf = b;
} }

View File

@ -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 *prev = parent;
ngx_http_index_loc_conf_t *conf = child; ngx_http_index_loc_conf_t *conf = child;
ngx_uint_t i; ngx_str_t *index;
ngx_str_t *index, *prev_index;
if (conf->max_index_len == 0) { if (conf->max_index_len == 0) {
if (prev->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; return NGX_CONF_OK;
} }
#if 0
if (prev->max_index_len != 0) { if (prev->max_index_len != 0) {
prev_index = prev->indices.elts; 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) { if (conf->max_index_len < prev->max_index_len) {
conf->max_index_len = prev->max_index_len; conf->max_index_len = prev->max_index_len;
} }

View File

@ -275,12 +275,9 @@ ngx_module_t ngx_http_proxy_module = {
static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = { static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = {
{ ngx_string("proxy"), /* STUB */ 100, { ngx_string("proxy"), 0, ngx_http_proxy_log_proxy_state },
ngx_http_proxy_log_proxy_state }, { ngx_string("proxy_cache_state"), 0, ngx_http_proxy_log_cache_state },
{ ngx_string("proxy_cache_state"), sizeof("BYPASS") - 1, { ngx_string("proxy_reason"), 0, ngx_http_proxy_log_reason },
ngx_http_proxy_log_cache_state },
{ ngx_string("proxy_reason"), sizeof("BPS") - 1,
ngx_http_proxy_log_reason },
{ ngx_null_string, 0, NULL } { 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, static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
u_char *buf, uintptr_t data) 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); p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
if (p == NULL) { if (p == NULL) {
if (buf == NULL) {
return (u_char *) 1;
}
*buf = '-'; *buf = '-';
return buf + 1; return buf + 1;
} }
if (p->state->cache_state == 0) {
*buf++ = '-';
} else { if (buf == NULL) {
buf = ngx_cpymem(buf, cache_states[p->state->cache_state - 1].data, /* find the request line length */
cache_states[p->state->cache_state - 1].len); return (u_char *) (uintptr_t) (p->states.nelts * /* STUB */ 100);
} }
*buf++ = '/';
if (p->state->expired == 0) { i = 0;
*buf++ = '-'; state = p->states.elts;
} else { for ( ;; ) {
buf = ngx_sprintf(buf, "%T", p->state->expired); if (state[i].cache_state == 0) {
*buf++ = '-';
} else {
buf = ngx_cpymem(buf, cache_states[state[i].cache_state - 1].data,
cache_states[state[i].cache_state - 1].len);
}
*buf++ = '/';
if (state[i].expired == 0) {
*buf++ = '-';
} else {
buf = ngx_sprintf(buf, "%T", state[i].expired);
}
*buf++ = '/';
if (state[i].bl_time == 0) {
*buf++ = '-';
} else {
buf = ngx_sprintf(buf, "%T", state[i].bl_time);
}
*buf++ = '/';
*buf++ = '*';
*buf++ = ' ';
if (state[i].status == 0) {
*buf++ = '-';
} else {
buf = ngx_sprintf(buf, "%ui", state[i].status);
}
*buf++ = '/';
if (state[i].reason == 0) {
*buf++ = '-';
} 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++ = '*';
if (++i == p->states.nelts) {
return buf;
}
*buf++ = ',';
*buf++ = ' ';
} }
*buf++ = '/';
if (p->state->bl_time == 0) {
*buf++ = '-';
} else {
buf = ngx_sprintf(buf, "%T", p->state->bl_time);
}
*buf++ = '/';
*buf++ = '*';
*buf++ = ' ';
if (p->state->status == 0) {
*buf++ = '-';
} else {
buf = ngx_sprintf(buf, "%ui", p->state->status);
}
*buf++ = '/';
if (p->state->reason == 0) {
*buf++ = '-';
} else {
buf = ngx_cpymem(buf, cache_reasons[p->state->reason - 1].data,
cache_reasons[p->state->reason - 1].len);
}
*buf++ = '/';
if (p->state->reason < NGX_HTTP_PROXY_CACHE_XAE) {
*buf++ = '-';
} else {
buf = ngx_sprintf(buf, "%T", p->state->expires);
}
*buf++ = ' ';
*buf++ = '*';
return buf;
} }
static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r, static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r,
u_char *buf, uintptr_t data) 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); p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
if (p == NULL || p->state->cache_state == 0) { if (p == NULL || p->state->cache_state == 0) {
if (buf == NULL) {
return (u_char *) 1;
}
*buf = '-'; *buf = '-';
return buf + 1; return buf + 1;
} }
return ngx_cpymem(buf, cache_states[p->state->cache_state - 1].data, if (buf == NULL) {
cache_states[p->state->cache_state - 1].len); /* 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, static u_char *ngx_http_proxy_log_reason(ngx_http_request_t *r, u_char *buf,
uintptr_t data) 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); p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
if (p == NULL || p->state->reason == 0) { if (p == NULL || p->state->reason == 0) {
if (buf == NULL) {
return (u_char *) 1;
}
*buf = '-'; *buf = '-';
return buf + 1; return buf + 1;
} }
return ngx_cpymem(buf, cache_reasons[p->state->reason - 1].data, if (buf == NULL) {
cache_reasons[p->state->reason - 1].len); /* 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) static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
{ {
ssize_t *np = data;
#if (NGX_FREEBSD) #if (NGX_FREEBSD)
ssize_t *np = data;
if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 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) #elif !(NGX_HAVE_SO_SNDLOWAT)
ssize_t *np = data;
ngx_conf_log_error(NGX_LOG_WARN, cf, 0, ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"\"proxy_send_lowat\" is not supported, ignored"); "\"proxy_send_lowat\" is not supported, ignored");

View File

@ -528,6 +528,7 @@ static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p)
{ {
ngx_chain_t *cl; ngx_chain_t *cl;
ngx_output_chain_ctx_t *output; ngx_output_chain_ctx_t *output;
ngx_http_proxy_state_e state;
/* reinit the request chain */ /* 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 */ /* add one more state */
state = p->state->cache_state;
if (!(p->state = ngx_push_array(&p->states))) { if (!(p->state = ngx_push_array(&p->states))) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return; return;
} }
ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t));
p->state->cache_state = state;
p->status = 0; p->status = 0;
p->status_count = 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->out = NULL;
writer->last = &writer->out; writer->last = &writer->out;
writer->connection = c; 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); 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_sent ? NULL:
p->request->request_body->bufs); p->request->request_body->bufs);
p->request_sent = 1;
if (rc == NGX_ERROR) { if (rc == NGX_ERROR) {
ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR); ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR);
return; return;
} }
p->request_sent = 1;
if (c->write->timer_set) { if (c->write->timer_set) {
ngx_del_timer(c->write); ngx_del_timer(c->write);
} }

View File

@ -97,6 +97,11 @@ typedef struct {
} ngx_http_cache_t; } 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_STALE 1
#define NGX_HTTP_CACHE_AGED 2 #define NGX_HTTP_CACHE_AGED 2

View File

@ -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) static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data)
{ {
ssize_t *np = data;
#if (NGX_FREEBSD) #if (NGX_FREEBSD)
ssize_t *np = data;
if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 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) #elif !(NGX_HAVE_SO_SNDLOWAT)
ssize_t *np = data;
ngx_conf_log_error(NGX_LOG_WARN, cf, 0, ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"\"send_lowat\" is not supported, ignored"); "\"send_lowat\" is not supported, ignored");

View File

@ -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. * Konqueror keeps the connection alive for about N seconds.
*/ */
if (clcf->keepalive_header if (clcf->keepalive_header) {
&& (r->headers_in.gecko || r->headers_in.konqueror))
{
len += sizeof("Keep-Alive: timeout=") - 1 + TIME_T_LEN + 2; 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, b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF,
sizeof("Connection: keep-alive" CRLF) - 1); sizeof("Connection: keep-alive" CRLF) - 1);
if (clcf->keepalive_header if (clcf->keepalive_header) {
&& (r->headers_in.gecko || r->headers_in.konqueror))
{
b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF, b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF,
clcf->keepalive_header); clcf->keepalive_header);
} }

View File

@ -166,7 +166,10 @@ ngx_int_t ngx_http_log_handler(ngx_http_request_t *r)
len++; len++;
#endif #endif
ngx_test_null(line, ngx_palloc(r->pool, len), NGX_ERROR); if (!(line = ngx_palloc(r->pool, len))) {
return NGX_ERROR;
}
p = line; p = line;
for (i = 0; i < log[l].ops->nelts; i++) { for (i = 0; i < log[l].ops->nelts; i++) {

View File

@ -665,6 +665,8 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
u_char c, ch, decoded, *p, *u; u_char c, ch, decoded, *p, *u;
enum { enum {
sw_usual = 0, sw_usual = 0,
sw_colon,
sw_colon_slash,
sw_slash, sw_slash,
sw_dot, sw_dot,
sw_dot_dot, sw_dot_dot,
@ -730,8 +732,14 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
case '?': case '?':
r->args_start = p; r->args_start = p;
break; break;
case ':':
state = sw_colon;
*u++ = ch;
break;
case '.': case '.':
r->uri_ext = u + 1; r->uri_ext = u + 1;
*u++ = ch;
break;
default: default:
*u++ = ch; *u++ = ch;
break; break;
@ -739,6 +747,61 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
ch = *p++; ch = *p++;
break; 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;
}
ch = *p++;
break;
case sw_slash: case sw_slash:
switch(ch) { switch(ch) {
#if (NGX_WIN32) #if (NGX_WIN32)

View File

@ -1190,8 +1190,9 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
#if 0 #if 0
/* MSIE ignores the SSL "close notify" alert */ /* MSIE ignores the SSL "close notify" alert */
if (c->ssl) {
ngx_ssl_set_nosendshut(r->connection->ssl); r->connection->ssl->no_send_shut = 1;
}
#endif #endif
} }
@ -1269,7 +1270,7 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
} }
if (r->connection->read->pending_eof) { if (r->connection->read->pending_eof) {
#if (NGX_KQUEUE) #if (NGX_HAVE_KQUEUE)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log,
r->connection->read->kq_errno, r->connection->read->kq_errno,
"kevent() reported about an closed connection"); "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; c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
} else { } 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, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "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 (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 #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, ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
"kevent() reported that client %V closed " "kevent() reported that client %V closed "
"keepalive connection", ctx->client); "keepalive connection", ctx->client);
#if (NGX_HTTP_SSL)
if (c->ssl) {
c->ssl->no_send_shut = 1;
}
#endif
ngx_http_close_connection(c); ngx_http_close_connection(c);
return; return;
} }

View File

@ -152,8 +152,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
sent = c->sent; sent = c->sent;
chain = c->send_chain(c, ctx->out, chain = c->send_chain(c, ctx->out, clcf->limit_rate);
clcf->limit_rate ? clcf->limit_rate: OFF_T_MAX_VALUE);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http write filter %p", chain); "http write filter %p", chain);

View File

@ -20,6 +20,12 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in,
ngx_err_t err; ngx_err_t err;
ngx_chain_t *cl; 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; send = 0;
sent = 0; sent = 0;
cl = in; cl = in;

View File

@ -104,7 +104,7 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
#else #else
#define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name) #define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name)
#endif #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_info_n "stat()"
#define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode)) #define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode))
#define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode)) #define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode))

View File

@ -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); return ngx_posix_init(log);
} }

View File

@ -37,9 +37,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
{ {
int rc; int rc;
u_char *prev; u_char *prev;
off_t fprev, sent, send, sprev, aligned; off_t size, send, prev_send, aligned, sent, fprev;
size_t hsize, fsize; size_t header_size, file_size;
ssize_t size;
ngx_uint_t eintr, eagain, complete; ngx_uint_t eintr, eagain, complete;
ngx_err_t err; ngx_err_t err;
ngx_buf_t *file; ngx_buf_t *file;
@ -67,6 +66,12 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
#endif #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; send = 0;
eagain = 0; eagain = 0;
@ -82,11 +87,11 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
for ( ;; ) { for ( ;; ) {
file = NULL; file = NULL;
fsize = 0; file_size = 0;
hsize = 0; header_size = 0;
eintr = 0; eintr = 0;
complete = 0; complete = 0;
sprev = send; prev_send = send;
header.nelts = 0; header.nelts = 0;
trailer.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) { if (prev == cl->buf->pos) {
iov->iov_len += size; iov->iov_len += (size_t) size;
} else { } else {
if (!(iov = ngx_array_push(&header))) { 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_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;
hsize += size; header_size += (size_t) size;
send += 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 */ /* coalesce the neighbouring file bufs */
do { 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) { if (send + size > limit) {
size = limit - send; 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; send += size;
fprev = cl->buf->file_pos + size; fprev = cl->buf->file_pos + size;
cl = cl->next; 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) { if (prev == cl->buf->pos) {
iov->iov_len += size; iov->iov_len += (size_t) size;
} else { } else {
if (!(iov = ngx_array_push(&trailer))) { 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_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; send += size;
cl = cl->next; 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) { if (ngx_freebsd_sendfile_nbytes_bug == 0) {
hsize = 0; header_size = 0;
} }
sent = 0; sent = 0;
rc = sendfile(file->file->fd, c->fd, file->file_pos, 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) { if (rc == -1) {
err = ngx_errno; 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, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
"sendfile() sent only %O bytes", "sendfile() sent only %O bytes", sent);
sent);
} else { } else {
wev->error = 1; 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, ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"sendfile: %d, @%O %O:%uz", "sendfile: %d, @%O %O:%uz",
rc, file->file_pos, sent, fsize + hsize); rc, file->file_pos, sent, file_size + header_size);
} else { } else {
rc = writev(c->fd, header.elts, header.nelts); rc = writev(c->fd, header.elts, header.nelts);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 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) { if (rc == -1) {
err = ngx_errno; 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; sent = rc > 0 ? rc : 0;
} }
if (send - sprev == sent) { if (send - prev_send == sent) {
complete = 1; 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)) { if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += sent; cl->buf->pos += (size_t) sent;
} }
if (cl->buf->in_file) { if (cl->buf->in_file) {

View File

@ -25,11 +25,10 @@
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit) off_t limit)
{ {
int rc; int rc, tcp_nodelay;
u_char *prev; u_char *prev;
off_t fprev, send, sprev, aligned; off_t size, send, prev_send, aligned, sent, fprev;
size_t fsize; size_t file_size;
ssize_t size, sent;
ngx_uint_t eintr, complete; ngx_uint_t eintr, complete;
ngx_err_t err; ngx_err_t err;
ngx_buf_t *file; 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; 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; send = 0;
header.elts = headers; header.elts = headers;
@ -58,10 +65,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
for ( ;; ) { for ( ;; ) {
file = NULL; file = NULL;
fsize = 0; file_size = 0;
eintr = 0; eintr = 0;
complete = 0; complete = 0;
sprev = send; prev_send = send;
header.nelts = 0; 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) { if (prev == cl->buf->pos) {
iov->iov_len += size; iov->iov_len += (size_t) size;
} else { } else {
if (!(iov = ngx_array_push(&header))) { 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_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; send += size;
} }
@ -111,25 +118,62 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
&& cl && cl
&& cl->buf->in_file) && cl->buf->in_file)
{ {
if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
err = ngx_errno;
/* /* the TCP_CORK and TCP_NODELAY are mutually exclusive */
* there is a tiny chance to be interrupted, however
* we continue a processing without the TCP_CORK
*/
if (err != NGX_EINTR) { if (c->tcp_nodelay) {
wev->error = 1;
ngx_connection_error(c, err, ngx_tcp_nopush_n " failed"); tcp_nodelay = 0;
return NGX_CHAIN_ERROR;
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 { if (!c->tcp_nodelay) {
c->tcp_nopush = NGX_TCP_NOPUSH_SET;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
"tcp_nopush"); 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 */ /* coalesce the neighbouring file bufs */
do { 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) { if (send + size > limit) {
size = limit - send; 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; send += size;
fprev = cl->buf->file_pos + size; fprev = cl->buf->file_pos + size;
cl = cl->next; cl = cl->next;
@ -172,7 +216,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
#else #else
offset = (int32_t) file->file_pos; offset = (int32_t) file->file_pos;
#endif #endif
rc = sendfile(c->fd, file->file->fd, &offset, fsize); rc = sendfile(c->fd, file->file->fd, &offset, file_size);
if (rc == -1) { if (rc == -1) {
err = ngx_errno; 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; sent = rc > 0 ? rc : 0;
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"sendfile: %d, @%O %z:%uz", "sendfile: %d, @%O %O:%uz",
rc, file->file_pos, sent, fsize); rc, file->file_pos, sent, file_size);
} else { } else {
rc = writev(c->fd, header.elts, header.nelts); 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; 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; 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)) { if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += sent; cl->buf->pos += (size_t) sent;
} }
if (cl->buf->in_file) { if (cl->buf->in_file) {

View File

@ -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_os_io_t ngx_os_io;
extern ngx_int_t ngx_ncpu; extern ngx_int_t ngx_ncpu;
extern ngx_int_t ngx_max_sockets; 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 #define ngx_stderr_fileno STDERR_FILENO

View File

@ -8,9 +8,10 @@
#include <ngx_core.h> #include <ngx_core.h>
ngx_int_t ngx_ncpu; ngx_int_t ngx_ncpu;
ngx_int_t ngx_max_sockets; ngx_int_t ngx_max_sockets;
ngx_int_t ngx_inherited_nonblocking; ngx_uint_t ngx_inherited_nonblocking;
ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
struct rlimit rlmt; struct rlimit rlmt;

View File

@ -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 ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle);
static void ngx_master_exit(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_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); static void ngx_channel_handler(ngx_event_t *ev);
#if (NGX_THREADS) #if (NGX_THREADS)
static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle); 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; 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; live = 1;
continue; continue;
@ -611,7 +638,7 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
ngx_err_t err; ngx_err_t err;
ngx_core_conf_t *ccf; ngx_core_conf_t *ccf;
ngx_worker_process_init(cycle); ngx_worker_process_init(cycle, 1);
ngx_setproctitle("worker process"); 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; sigset_t set;
ngx_int_t n; 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); ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (geteuid() == 0) { 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) { if (setgid(ccf->group) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setgid(%d) failed", ccf->group); "setgid(%d) failed", ccf->group);
@ -746,6 +780,12 @@ static void ngx_worker_process_init(ngx_cycle_t *cycle)
exit(2); 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) { if (setuid(ccf->user) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setuid(%d) failed", ccf->user); "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_path_t **path;
ngx_event_t *ev; ngx_event_t *ev;
ngx_worker_process_init(cycle); ngx_worker_process_init(cycle, 0);
ev = &cycle->read_events[ngx_channel]; ev = &cycle->read_events[ngx_channel];

View File

@ -9,6 +9,28 @@
#include <ngx_event.h> #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 #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; int fd;
u_char *prev; u_char *prev;
off_t fprev, sprev, send, aligned; off_t size, send, prev_send, aligned, fprev;
ssize_t size, sent, n; size_t sent;
ssize_t n;
ngx_int_t eintr, complete; ngx_int_t eintr, complete;
ngx_err_t err; ngx_err_t err;
sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS]; 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); 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; send = 0;
complete = 0; complete = 0;
@ -51,7 +82,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
sfv = NULL; sfv = NULL;
eintr = 0; eintr = 0;
sent = 0; sent = 0;
sprev = send; prev_send = send;
vec.nelts = 0; 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) { if (prev == cl->buf->pos) {
sfv->sfv_len += size; sfv->sfv_len += (size_t) size;
} else { } else {
if (!(sfv = ngx_array_push(&vec))) { 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_fd = SFV_FD_SELF;
sfv->sfv_flag = 0; sfv->sfv_flag = 0;
sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos; 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; send += size;
} else { } else {
prev = NULL; 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) { if (send + size > limit) {
size = limit - send; 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) { if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) {
sfv->sfv_len += size; sfv->sfv_len += (size_t) size;
} else { } else {
if (!(sfv = ngx_array_push(&vec))) { 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_fd = fd;
sfv->sfv_flag = 0; sfv->sfv_flag = 0;
sfv->sfv_off = cl->buf->file_pos; sfv->sfv_off = cl->buf->file_pos;
sfv->sfv_len = size; sfv->sfv_len = (size_t) size;
} }
fprev = cl->buf->file_pos + 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, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
"sendfilev() sent only %z bytes", sent); "sendfilev() sent only %uz bytes", sent);
} else { } else {
wev->error = 1; 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, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"sendfilev: %z %z", n, sent); "sendfilev: %z %z", n, sent);
if (send - sprev == sent) { if (send - prev_send == (off_t) sent) {
complete = 1; 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); size = ngx_buf_size(cl->buf);
if (sent >= size) { if ((off_t) sent >= size) {
sent -= size; sent = (size_t) ((off_t) sent - size);
if (ngx_buf_in_memory(cl->buf)) { if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last; cl->buf->pos = cl->buf->last;

View File

@ -16,7 +16,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{ {
u_char *prev; u_char *prev;
ssize_t n, size, sent; ssize_t n, size, sent;
off_t send, sprev; off_t send, prev_send;
ngx_uint_t eintr, complete; ngx_uint_t eintr, complete;
ngx_err_t err; ngx_err_t err;
ngx_array_t vec; 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 #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; send = 0;
complete = 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; prev = NULL;
iov = NULL; iov = NULL;
eintr = 0; eintr = 0;
sprev = send; prev_send = send;
vec.nelts = 0; 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); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent);
if (send - sprev == sent) { if (send - prev_send == sent) {
complete = 1; complete = 1;
} }

View File

@ -43,7 +43,11 @@ static ngx_str_t wsa_errors[] = {
ngx_null_string, /* 10039 */ ngx_null_string, /* 10039 */
ngx_null_string, /* 10040 */ ngx_null_string, /* 10040 */
ngx_null_string, /* 10041 */ 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, /* 10043 */
ngx_null_string, /* 10044 */ ngx_null_string, /* 10044 */
ngx_null_string, /* 10045 */ ngx_null_string, /* 10045 */

View File

@ -48,6 +48,7 @@ extern ngx_uint_t ngx_ncpu;
extern ngx_uint_t ngx_max_wsabufs; extern ngx_uint_t ngx_max_wsabufs;
extern ngx_int_t ngx_max_sockets; extern ngx_int_t ngx_max_sockets;
extern ngx_uint_t ngx_inherited_nonblocking; 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_uint_t ngx_win32_version;
extern ngx_fd_t ngx_stderr_fileno; extern ngx_fd_t ngx_stderr_fileno;

View File

@ -141,5 +141,10 @@ typedef uint32_t ngx_atomic_t;
#define NGX_HAVE_SENDFILE 1 #define NGX_HAVE_SENDFILE 1
#endif #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_ */ #endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */

View File

@ -13,6 +13,8 @@ ngx_uint_t ngx_ncpu;
ngx_uint_t ngx_max_wsabufs; ngx_uint_t ngx_max_wsabufs;
ngx_int_t ngx_max_sockets; ngx_int_t ngx_max_sockets;
ngx_uint_t ngx_inherited_nonblocking = 1; ngx_uint_t ngx_inherited_nonblocking = 1;
ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
ngx_fd_t ngx_stderr_fileno; ngx_fd_t ngx_stderr_fileno;

View File

@ -17,7 +17,7 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
{ {
int rc; int rc;
u_char *prev; u_char *prev;
u_long size, sent, send, sprev; u_long size, sent, send, prev_send;
ngx_uint_t complete; ngx_uint_t complete;
ngx_err_t err; ngx_err_t err;
ngx_event_t *wev; ngx_event_t *wev;
@ -32,6 +32,12 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
return 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; send = 0;
complete = 0; complete = 0;
@ -48,7 +54,7 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
for ( ;; ) { for ( ;; ) {
prev = NULL; prev = NULL;
wsabuf = NULL; wsabuf = NULL;
sprev = send; prev_send = send;
vec.nelts = 0; 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, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSASend: fd:%d, s:%ul", c->fd, sent); "WSASend: fd:%d, s:%ul", c->fd, sent);
if (send - sprev == sent) { if (send - prev_send == sent) {
complete = 1; complete = 1;
} }
@ -153,8 +159,7 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
{ {
int rc; int rc;
u_char *prev; u_char *prev;
size_t size; u_long size, send, sent;
u_long send, sent;
LPWSABUF wsabuf; LPWSABUF wsabuf;
ngx_err_t err; ngx_err_t err;
ngx_event_t *wev; ngx_event_t *wev;
@ -176,6 +181,12 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
/* post the overlapped WSASend() */ /* 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 * WSABUFs must be 4-byte aligned otherwise
* WSASend() will return undocumented WSAEINVAL error. * WSASend() will return undocumented WSAEINVAL error.