mirror of
https://github.com/nginx/nginx.git
synced 2024-11-26 02:40:46 -06:00
nginx-0.3.13-RELEASE import
*) Feature: the IMAP/POP3 proxy supports STARTTLS and STLS. *) Bugfix: the IMAP/POP3 proxy did not work with the select, poll, and /dev/poll methods. *) Bugfix: in SSI handling. *) Bugfix: now Solaris sendfilev() is not used to transfer the client request body to FastCGI-server via the unix domain socket. *) Bugfix: the "auth_basic" directive did not disable the authorization; the bug had appeared in 0.3.11.
This commit is contained in:
parent
0624ed3d7e
commit
d3283ff922
@ -36,7 +36,7 @@ fi
|
||||
|
||||
case "$NGX_MACHINE" in
|
||||
|
||||
sun4u | sparc )
|
||||
sun4u | sparc | sparc64 )
|
||||
# "-mcpu=v9" enables the "casa" assembler instruction
|
||||
CFLAGS="$CFLAGS -mcpu=v9"
|
||||
;;
|
||||
|
@ -49,6 +49,8 @@ case $CPU in
|
||||
;;
|
||||
esac
|
||||
|
||||
# __cdecl, use with OpenSSL
|
||||
#CPU_OPT="$CPU_OPT -Gd"
|
||||
# __stdcall
|
||||
#CPU_OPT="$CPU_OPT -Gz"
|
||||
# __fastcall
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
# Open Watcom C 1.0, 1.2
|
||||
# Open Watcom C 1.0, 1.2, 1.3
|
||||
|
||||
# optimizations
|
||||
|
||||
@ -60,7 +60,7 @@ CFLAGS="$CFLAGS -d2"
|
||||
CFLAGS="$CFLAGS -zq"
|
||||
|
||||
# Open Watcom C 1.2
|
||||
#have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
|
||||
have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
|
||||
|
||||
|
||||
# the precompiled headers
|
||||
|
@ -20,7 +20,7 @@ int main() {
|
||||
|
||||
END
|
||||
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_WARN $CC_AUX_FLAGS \
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
|
||||
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
|
||||
|
||||
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
||||
|
@ -31,7 +31,7 @@ int main() {
|
||||
END
|
||||
|
||||
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_WARN $CC_AUX_FLAGS \
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
|
||||
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
|
||||
|
||||
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
||||
|
98
auto/fmt/fmt
98
auto/fmt/fmt
@ -1,98 +0,0 @@
|
||||
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
echo $ngx_n "checking for $ngx_type printf() format ...$ngx_c"
|
||||
|
||||
cat << END >> $NGX_AUTOCONF_ERR
|
||||
|
||||
----------------------------------------
|
||||
checking for $ngx_type printf() format
|
||||
|
||||
END
|
||||
|
||||
|
||||
ngx_format=no
|
||||
ngx_comma=
|
||||
|
||||
|
||||
for ngx_fmt in $ngx_formats
|
||||
do
|
||||
|
||||
cat << END > $NGX_AUTOTEST.c
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/resource.h>
|
||||
$NGX_INCLUDE_INTTYPES_H
|
||||
$NGX_INCLUDE_AUTO_CONFIG_H
|
||||
|
||||
int main() {
|
||||
printf("$ngx_fmt", ($ngx_type) $ngx_max_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
END
|
||||
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_WARN $CC_AUX_FLAGS \
|
||||
-o $NGX_AUTOTEST $NGX_AUTOTEST.c"
|
||||
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
||||
|
||||
ngx_max_val=`echo $ngx_max_value | sed -e "s/L*\$//"`
|
||||
|
||||
if [ -x $NGX_AUTOTEST ]; then
|
||||
|
||||
if [ "`$NGX_AUTOTEST`" = $ngx_max_val ]; then
|
||||
|
||||
if [ $ngx_fmt_collect = yes ]; then
|
||||
echo $ngx_n "$ngx_comma \"${ngx_fmt}\" is appropriate$ngx_c"
|
||||
else
|
||||
echo $ngx_n "$ngx_comma \"${ngx_fmt}\" used$ngx_c"
|
||||
fi
|
||||
|
||||
ngx_format=$ngx_fmt
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f $NGX_AUTOTEST
|
||||
|
||||
if [ $ngx_format != no ]; then
|
||||
if [ $ngx_fmt_collect = yes ]; then
|
||||
eval "ngx_${ngx_size}_fmt=\"\${ngx_${ngx_size}_fmt} \$ngx_format\""
|
||||
ngx_comma=","
|
||||
continue
|
||||
else
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $ngx_n "$ngx_comma \"${ngx_fmt}\" is not appropriate$ngx_c"
|
||||
ngx_comma=","
|
||||
|
||||
echo "----------" >> $NGX_AUTOCONF_ERR
|
||||
cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
|
||||
echo "----------" >> $NGX_AUTOCONF_ERR
|
||||
echo $ngx_test >> $NGX_AUTOCONF_ERR
|
||||
echo "----------" >> $NGX_AUTOCONF_ERR
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
if [ $ngx_format = no ]; then
|
||||
echo "$0: error: printf() $ngx_type format not found"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_fmt_collect = no ]; then
|
||||
cat << END >> $NGX_AUTO_CONFIG_H
|
||||
|
||||
#ifndef $ngx_fmt_name
|
||||
#define $ngx_fmt_name "$ngx_format"
|
||||
#endif
|
||||
|
||||
END
|
||||
|
||||
fi
|
@ -1,86 +0,0 @@
|
||||
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
echo $ngx_n "checking for $ngx_type printf() format ...$ngx_c"
|
||||
|
||||
cat << END >> $NGX_AUTOCONF_ERR
|
||||
|
||||
----------------------------------------
|
||||
checking for $ngx_type printf() format
|
||||
|
||||
END
|
||||
|
||||
|
||||
ngx_format=no
|
||||
ngx_comma=
|
||||
ngx_fmt_x=
|
||||
|
||||
for ngx_fmt in $ngx_formats
|
||||
do
|
||||
|
||||
cat << END > $NGX_AUTOTEST.c
|
||||
|
||||
int main() {
|
||||
printf("$ngx_fmt", ($ngx_type) $ngx_max_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
END
|
||||
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_WARN $CC_AUX_FLAGS \
|
||||
-o $NGX_AUTOTEST $NGX_AUTOTEST.c"
|
||||
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
||||
|
||||
ngx_max_val=`echo $ngx_max_value | sed -e "s/L*\$//"`
|
||||
|
||||
if [ -x $NGX_AUTOTEST ]; then
|
||||
if [ "`$NGX_AUTOTEST`" = $ngx_max_val ]; then
|
||||
ngx_format=$ngx_fmt
|
||||
fi
|
||||
fi
|
||||
|
||||
rm $NGX_AUTOTEST
|
||||
|
||||
if [ $ngx_format != no ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
ngx_fmt_x=`echo $ngx_fmt | sed -e "s/d/X/"`
|
||||
|
||||
echo $ngx_n "$ngx_comma \"${ngx_fmt_x}\" is not appropriate$ngx_c"
|
||||
ngx_comma=","
|
||||
|
||||
echo "----------" >> $NGX_AUTOCONF_ERR
|
||||
cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
|
||||
echo "----------" >> $NGX_AUTOCONF_ERR
|
||||
echo $ngx_test >> $NGX_AUTOCONF_ERR
|
||||
echo "----------" >> $NGX_AUTOCONF_ERR
|
||||
done
|
||||
|
||||
|
||||
if [ $ngx_format = no ]; then
|
||||
echo "$0: error: printf() $ngx_type format not found"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_ptr_size = 4 ]; then
|
||||
ngx_fmt_x="%0`expr 2 \* $ngx_ptr_size`"
|
||||
else
|
||||
ngx_fmt_x="%"
|
||||
fi
|
||||
|
||||
ngx_format=`echo $ngx_format | sed -e "s/d/X/" -e "s/^%/$ngx_fmt_x/"`
|
||||
|
||||
echo "$ngx_comma \"${ngx_format}\" used"
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_CONFIG_H
|
||||
|
||||
#ifndef $ngx_fmt_name
|
||||
#define $ngx_fmt_name "$ngx_format"
|
||||
#endif
|
||||
|
||||
END
|
@ -1,11 +0,0 @@
|
||||
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
cat << END | sed -e 's/d"$/x"/' >> $NGX_AUTO_CONFIG_H
|
||||
|
||||
#ifndef $ngx_fmt_name
|
||||
#define $ngx_fmt_name "$ngx_fmt"
|
||||
#endif
|
||||
|
||||
END
|
@ -23,29 +23,47 @@ if [ $OPENSSL != NONE ]; then
|
||||
|
||||
else
|
||||
|
||||
if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
OPENSSL=NO
|
||||
case "$NGX_PLATFORM" in
|
||||
|
||||
ngx_feature="OpenSSL library"
|
||||
ngx_feature_name="NGX_OPENSSL"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <openssl/ssl.h>"
|
||||
ngx_feature_libs="-lssl -lcrypto"
|
||||
ngx_feature_test="SSL_library_init()"
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
win32)
|
||||
have=NGX_OPENSSL . auto/have
|
||||
have=NGX_SSL . auto/have
|
||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||
OPENSSL=YES
|
||||
|
||||
case "$NGX_SYSTEM" in
|
||||
SunOS)
|
||||
CORE_LIBS="$CORE_LIBS -ldl"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
CORE_INCS="$CORE_INCS c:/openssl/include"
|
||||
CORE_LIBS="$CORE_LIBS c:/openssl/ssleay32.lib"
|
||||
CORE_LIBS="$CORE_LIBS c:/openssl/libeay32.lib"
|
||||
|
||||
fi
|
||||
# libeay32.lib requires gdi32.lib
|
||||
CORE_LIBS="$CORE_LIBS gdi32.lib"
|
||||
# OpenSSL 0.8's libeay32.lib requires advapi32.lib
|
||||
CORE_LIBS="$CORE_LIBS advapi32.lib"
|
||||
;;
|
||||
|
||||
*)
|
||||
OPENSSL=NO
|
||||
|
||||
ngx_feature="OpenSSL library"
|
||||
ngx_feature_name="NGX_OPENSSL"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <openssl/ssl.h>"
|
||||
ngx_feature_libs="-lssl -lcrypto"
|
||||
ngx_feature_test="SSL_library_init()"
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
have=NGX_SSL . auto/have
|
||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||
OPENSSL=YES
|
||||
|
||||
case "$NGX_SYSTEM" in
|
||||
SunOS)
|
||||
CORE_LIBS="$CORE_LIBS -ldl"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
fi
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
if test -n "$OPENSSL_OPT"; then
|
||||
NGX_OPENSSL_CONFIG="./Configure \"$OPENSSL_OPT\""
|
||||
else
|
||||
|
@ -63,7 +63,7 @@ case "$NGX_MACHINE" in
|
||||
have=NGX_HAVE_NONALIGNED . auto/have
|
||||
;;
|
||||
|
||||
sun4u | ia64 )
|
||||
sun4u | sparc | sparc64 | ia64 )
|
||||
have=NGX_ALIGNMENT value=16 . auto/define
|
||||
;;
|
||||
|
||||
|
@ -110,5 +110,5 @@ ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sched.h>"
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="long mask = 0;
|
||||
sched_setaffinity(0, 32, &mask)"
|
||||
sched_setaffinity(0, 32, (cpu_set_t *) &mask)"
|
||||
. auto/feature
|
||||
|
@ -31,7 +31,7 @@ int main() {
|
||||
END
|
||||
|
||||
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_WARN $CC_AUX_FLAGS \
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
|
||||
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
|
||||
|
||||
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
||||
|
@ -33,7 +33,9 @@ int main() {
|
||||
|
||||
END
|
||||
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c"
|
||||
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
|
||||
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
|
||||
|
||||
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
||||
|
||||
if [ -x $NGX_AUTOTEST ]; then
|
||||
|
@ -4,10 +4,7 @@
|
||||
|
||||
have=NGX_HAVE_UNIX_DOMAIN . auto/have
|
||||
|
||||
|
||||
# STUB
|
||||
CC_WARN=
|
||||
ngx_fmt_collect=yes
|
||||
ngx_feature_libs=
|
||||
|
||||
|
||||
# C types
|
||||
|
@ -9,6 +9,60 @@
|
||||
<title lang="en">nginx changelog</title>
|
||||
|
||||
|
||||
<changes ver="0.3.13" date="05.12.2005">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
IMAP/POP3 ÐÒÏËÓÉ ÐÏÄÄÅÒÖÉ×ÁÅÔ STARTTLS É STLS.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the IMAP/POP3 proxy supports STARTTLS and STLS.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
IMAP/POP3 ÐÒÏËÓÉ ÎÅ ÒÁÂÏÔÁÌÁ Ó ÍÅÔÏÄÁÍÉ select, poll É /dev/poll.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the IMAP/POP3 proxy did not work with the select, poll, and /dev/poll methods.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÏÛÉÂËÉ × ÏÂÒÁÂÏÔËÅ SSI.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in SSI handling.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
sendfilev() × Solaris ÔÅÐÅÒØ ÎÅ ÉÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÐÅÒÅÄÁÞÅ ÔÅÌÁ ÚÁÐÒÏÓÁ
|
||||
FastCGI-ÓÅÒ×ÅÒÕ ÞÅÒÅÚ unix domain ÓÏËÅÔ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
now Solaris sendfilev() is not used to transfer the client request body
|
||||
to FastCGI-server via the unix domain socket.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á auth_basic ÎÅ ÚÁÐÒÅÝÁÌÁ ÁÕÔÅÎÔÉÆÉËÁÃÉÀ;
|
||||
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.3.11.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "auth_basic" directive did not disable the authorization;
|
||||
bug appeared in 0.3.11.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="0.3.12" date="26.11.2005">
|
||||
|
||||
<change type="security">
|
||||
@ -75,7 +129,7 @@ bug appeared in 0.3.0.
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ ËÌÉÅÎÔ ÐÅÒÅÄÁÌ ÓÔÒÏËÕ "Transfer-Encoding: chunked" × ÚÁÇÏÌÏÏ×ËÅ
|
||||
ÅÓÌÉ ËÌÉÅÎÔ ÐÅÒÅÄÁÌ ÓÔÒÏËÕ "Transfer-Encoding: chunked" × ÚÁÇÏÌÏ×ËÅ
|
||||
ÚÁÐÒÏÓÁ, ÔÏ nginx ÔÅÐÅÒØ ×ÙÄÁ£Ô ÏÛÉÂËÕ 411.
|
||||
</para>
|
||||
<para lang="en">
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VER "nginx/0.3.12"
|
||||
#define NGINX_VER "nginx/0.3.13"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
|
@ -182,6 +182,8 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
|
||||
|
||||
|
||||
if (filename) {
|
||||
ngx_pfree(cf->pool, cf->conf_file->buffer->start);
|
||||
|
||||
cf->conf_file = prev;
|
||||
|
||||
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
|
||||
|
@ -140,7 +140,8 @@ struct ngx_connection_s {
|
||||
unsigned single_connection:1;
|
||||
unsigned unexpected_eof:1;
|
||||
unsigned timedout:1;
|
||||
unsigned closed:1;
|
||||
unsigned error:1;
|
||||
unsigned destroyed:1;
|
||||
|
||||
unsigned sendfile:1;
|
||||
unsigned sndlowat:1;
|
||||
|
@ -47,6 +47,10 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names, ngx_uint_t nelts)
|
||||
n < nelts;
|
||||
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
if (name->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < name->len; i++) {
|
||||
@ -104,6 +108,10 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names, ngx_uint_t nelts)
|
||||
n < nelts;
|
||||
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
if (name->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < name->len; i++) {
|
||||
@ -135,6 +143,10 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names, ngx_uint_t nelts)
|
||||
n < nelts;
|
||||
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
if (name->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < name->len; i++) {
|
||||
|
@ -102,7 +102,7 @@ ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
}
|
||||
|
||||
if ((size_t) (p->end - m) < NGX_ALIGNMENT) {
|
||||
p->current = p->next;
|
||||
pool->current = p->next;
|
||||
}
|
||||
|
||||
if (p->next == NULL) {
|
||||
@ -117,8 +117,8 @@ ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p->current == NULL) {
|
||||
p->current = n;
|
||||
if (pool->current == NULL) {
|
||||
pool->current = n;
|
||||
}
|
||||
|
||||
p->next = n;
|
||||
|
@ -29,7 +29,7 @@ struct ngx_rbtree_node_s {
|
||||
|
||||
typedef struct ngx_rbtree_s ngx_rbtree_t;
|
||||
|
||||
typedef ngx_rbtree_t *(*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
|
||||
typedef ngx_rbtree_node_t *(*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
|
||||
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
|
||||
|
||||
struct ngx_rbtree_s {
|
||||
|
183
src/core/ngx_resolver.c
Normal file
183
src/core/ngx_resolver.c
Normal file
@ -0,0 +1,183 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_event.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_connection_t *connection;
|
||||
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
|
||||
ngx_str_r server;
|
||||
ngx_str_r name;
|
||||
|
||||
ngx_event_handler_pt handler;
|
||||
|
||||
ngx_log_t *pool;
|
||||
ngx_log_t *log;
|
||||
} ngx_resolver_t;
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_gethostbyname(ngx_resolver_t *r)
|
||||
{
|
||||
ngx_socket_t s;
|
||||
|
||||
if (r->connection) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
s = ngx_socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, r->log, 0, "socket %d", s);
|
||||
|
||||
if (s == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->log, ngx_socket_errno,
|
||||
ngx_socket_n " failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c = ngx_get_connection(s, r->log);
|
||||
|
||||
if (c == NULL) {
|
||||
if (ngx_close_socket(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->log, ngx_socket_errno,
|
||||
ngx_close_socket_n "failed");
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rev = c->read;
|
||||
wev = c->write;
|
||||
|
||||
rev->log = pc->log;
|
||||
wev->log = pc->log;
|
||||
|
||||
r->connection = c;
|
||||
|
||||
/*
|
||||
* TODO: MT: - ngx_atomic_fetch_add()
|
||||
* or protection by critical section or mutex
|
||||
*
|
||||
* TODO: MP: - allocated in a shared memory
|
||||
* - ngx_atomic_fetch_add()
|
||||
* or protection by critical section or mutex
|
||||
*/
|
||||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
#if (NGX_THREADS)
|
||||
rev->lock = pc->lock;
|
||||
wev->lock = pc->lock;
|
||||
rev->own_lock = &c->lock;
|
||||
wev->own_lock = &c->lock;
|
||||
#endif
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
|
||||
"connect to %V, fd:%d #%d", &r->server, s, c->number);
|
||||
|
||||
rc = connect(s, r->sockaddr, r->socklen);
|
||||
|
||||
if (rc == -1) {
|
||||
ngx_log_error(level, r->log, ngx_socket_errno,
|
||||
"connect() to %V failed", &r->server);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (ngx_add_conn) {
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ngx_add_conn) {
|
||||
if (rc == -1) {
|
||||
|
||||
/* NGX_EINPROGRESS */
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
|
||||
|
||||
wev->ready = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, ngx_socket_errno,
|
||||
"connect(): %d", rc);
|
||||
|
||||
/* aio, iocp */
|
||||
|
||||
if (ngx_blocking(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||
ngx_blocking_n " failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* FreeBSD's aio allows to post an operation on non-connected socket.
|
||||
* NT does not support it.
|
||||
*
|
||||
* TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT
|
||||
*/
|
||||
|
||||
rev->ready = 1;
|
||||
wev->ready = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue */
|
||||
|
||||
event = NGX_CLEAR_EVENT;
|
||||
|
||||
} else {
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
event = NGX_LEVEL_EVENT;
|
||||
}
|
||||
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == -1) {
|
||||
|
||||
/* NGX_EINPROGRESS */
|
||||
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
|
||||
|
||||
wev->ready = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
@ -1036,3 +1036,19 @@ done:
|
||||
*dst = d;
|
||||
*src = s;
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_MEMCPY_LIMIT)
|
||||
|
||||
void *
|
||||
ngx_memcpy(void *dst, void *src, size_t n)
|
||||
{
|
||||
if (n > NGX_MEMCPY_LIMIT) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "memcpy %uz bytes", n);
|
||||
ngx_debug_point();
|
||||
}
|
||||
|
||||
return memcpy(dst, src, n);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -63,6 +63,13 @@ typedef struct {
|
||||
#define ngx_memset(buf, c, n) (void) memset(buf, c, n)
|
||||
|
||||
|
||||
#if (NGX_MEMCPY_LIMIT)
|
||||
|
||||
void *ngx_memcpy(void *dst, void *src, size_t n);
|
||||
#define ngx_cpymem(dst, src, n) ((u_char *) ngx_memcpy(dst, src, n)) + (n)
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* gcc3, msvc, and icc7 compile memcpy() to the inline "rep movs".
|
||||
* gcc3 compiles memcpy(d, s, 4) to the inline "mov"es.
|
||||
@ -71,6 +78,8 @@ typedef struct {
|
||||
#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)
|
||||
#define ngx_cpymem(dst, src, n) ((u_char *) memcpy(dst, src, n)) + (n)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if ( __INTEL_COMPILER >= 800 )
|
||||
|
||||
|
@ -276,8 +276,10 @@ static ngx_int_t
|
||||
ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
#if 0
|
||||
ngx_event_t *e;
|
||||
ngx_connection_t *c;
|
||||
#endif
|
||||
|
||||
ev->active = 1;
|
||||
ev->disabled = 0;
|
||||
@ -285,12 +287,11 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
|
||||
ngx_mutex_lock(list_mutex);
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
|
||||
if (nchanges > 0
|
||||
&& ev->index < (u_int) nchanges
|
||||
if (ev->index < (u_int) nchanges
|
||||
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
|
||||
== (uintptr_t) ev)
|
||||
== (uintptr_t) ev)
|
||||
{
|
||||
if (change_list[ev->index].flags == EV_DISABLE) {
|
||||
|
||||
@ -346,12 +347,9 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
|
||||
ngx_mutex_lock(list_mutex);
|
||||
|
||||
#if 1
|
||||
|
||||
if (nchanges > 0
|
||||
&& ev->index < (u_int) nchanges
|
||||
if (ev->index < (u_int) nchanges
|
||||
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
|
||||
== (uintptr_t) ev)
|
||||
== (uintptr_t) ev)
|
||||
{
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"kevent deleted: %d: ft:%d",
|
||||
@ -359,7 +357,9 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
|
||||
/* if the event is still not passed to a kernel we will not pass it */
|
||||
|
||||
if (ev->index < (u_int) --nchanges) {
|
||||
nchanges--;
|
||||
|
||||
if (ev->index < (u_int) nchanges) {
|
||||
e = (ngx_event_t *)
|
||||
((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
|
||||
change_list[ev->index] = change_list[nchanges];
|
||||
@ -371,8 +371,6 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* when the file descriptor is closed the kqueue automatically deletes
|
||||
* its filters so we do not need to delete explicity the event
|
||||
@ -551,7 +549,9 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
|
||||
if (event_list[i].flags & EV_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data,
|
||||
"kevent() error on %d", event_list[i].ident);
|
||||
"kevent() error on %d filter:%d flags:%04Xd",
|
||||
event_list[i].ident, event_list[i].filter,
|
||||
event_list[i].flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -181,6 +181,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
||||
if (peer->sockaddr->sa_family != AF_INET) {
|
||||
c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
|
||||
|
||||
#if (NGX_SOLARIS)
|
||||
/* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
|
||||
c->sendfile = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
rev = c->read;
|
||||
|
@ -301,12 +301,12 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
||||
|
||||
*d = '\0';
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"SSL: %s, cipher: \"%s\"",
|
||||
SSL_get_version(c->ssl->connection), &buf[1]);
|
||||
|
||||
if (SSL_session_reused(c->ssl->connection)) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"SSL reused session");
|
||||
}
|
||||
|
||||
@ -630,7 +630,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||
for ( ;; ) {
|
||||
|
||||
while (in && buf->last < buf->end) {
|
||||
if (in->buf->last_buf) {
|
||||
if (in->buf->last_buf || in->buf->flush) {
|
||||
flush = 1;
|
||||
}
|
||||
|
||||
@ -645,11 +645,6 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||
size = buf->end - buf->last;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: the taking in->buf->flush into account can be
|
||||
* implemented using the limit on the higher level
|
||||
*/
|
||||
|
||||
if (send + size > limit) {
|
||||
size = (ssize_t) (limit - send);
|
||||
flush = 1;
|
||||
@ -943,7 +938,7 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void ngx_cdecl
|
||||
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
||||
{
|
||||
u_long n;
|
||||
@ -958,7 +953,13 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
||||
|
||||
p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);
|
||||
|
||||
while (p < last && (n = ERR_get_error())) {
|
||||
while (p < last) {
|
||||
|
||||
n = ERR_get_error();
|
||||
|
||||
if (n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = ' ';
|
||||
|
||||
|
@ -79,7 +79,7 @@ ssize_t ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl);
|
||||
ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
|
||||
off_t limit);
|
||||
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_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
|
||||
char *fmt, ...);
|
||||
void ngx_ssl_cleanup_ctx(void *data);
|
||||
|
||||
|
@ -407,12 +407,15 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
|
||||
static ngx_int_t
|
||||
ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
||||
{
|
||||
size_t bsize;
|
||||
ngx_uint_t flush;
|
||||
ngx_chain_t *out, **ll, *cl;
|
||||
size_t bsize;
|
||||
ngx_uint_t flush;
|
||||
ngx_chain_t *out, **ll, *cl;
|
||||
ngx_connection_t *downstream;
|
||||
|
||||
downstream = p->downstream;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||
"pipe write downstream: %d", p->downstream->write->ready);
|
||||
"pipe write downstream: %d", downstream->write->ready);
|
||||
|
||||
for ( ;; ) {
|
||||
if (p->downstream_error) {
|
||||
@ -452,6 +455,11 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
||||
}
|
||||
|
||||
if (p->output_filter(p->output_ctx, p->in) == NGX_ERROR) {
|
||||
|
||||
if (downstream->destroyed) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
||||
p->downstream_error = 1;
|
||||
return ngx_event_pipe_drain_chains(p);
|
||||
}
|
||||
@ -468,9 +476,9 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p->downstream->data != p->output_ctx
|
||||
|| !p->downstream->write->ready
|
||||
|| p->downstream->write->delayed)
|
||||
if (downstream->data != p->output_ctx
|
||||
|| !downstream->write->ready
|
||||
|| downstream->write->delayed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -379,6 +379,8 @@ ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data)
|
||||
if (ngx_strcmp(realm->data, "off") == 0) {
|
||||
realm->len = 0;
|
||||
realm->data = (u_char *) "";
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
len = sizeof("Basic realm=\"") - 1 + realm->len + 1;
|
||||
|
@ -1419,7 +1419,8 @@ ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var;
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name, 0);
|
||||
var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
|
||||
NGX_HTTP_VAR_NOHASH);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -130,18 +130,14 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
var->handler = ngx_http_geo_variable;
|
||||
var->data = (uintptr_t) tree;
|
||||
|
||||
/*
|
||||
* create the temporary pool of a huge initial size
|
||||
* to process quickly a large number of geo lines
|
||||
*/
|
||||
|
||||
pool = ngx_create_pool(512 * 1024, cf->log);
|
||||
pool = ngx_create_pool(16384, cf->log);
|
||||
if (pool == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&geo.values, pool, 512,
|
||||
sizeof(ngx_http_variable_value_t *)) == NGX_ERROR)
|
||||
sizeof(ngx_http_variable_value_t *))
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
|
@ -961,7 +961,7 @@ ngx_http_gzip_add_variables(ngx_conf_t *cf)
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_log_op_name_t *op;
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, 0);
|
||||
var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, NGX_HTTP_VAR_NOHASH);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -359,20 +359,20 @@ static ngx_table_elt_t ngx_http_proxy_headers[] = {
|
||||
static ngx_http_variable_t ngx_http_proxy_vars[] = {
|
||||
|
||||
{ ngx_string("proxy_host"), ngx_http_proxy_host_variable, 0,
|
||||
NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_string("proxy_port"), ngx_http_proxy_port_variable, 0,
|
||||
NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_string("proxy_add_x_forwarded_for"),
|
||||
ngx_http_proxy_add_x_forwarded_for_variable, 0, 0, 0 },
|
||||
ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
#if 0
|
||||
{ ngx_string("proxy_add_via"), NULL, 0, 0, 0 },
|
||||
{ ngx_string("proxy_add_via"), NULL, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||
#endif
|
||||
|
||||
{ ngx_string("proxy_internal_body_length"),
|
||||
ngx_http_proxy_internal_body_length_variable, 0, 0, 0 },
|
||||
ngx_http_proxy_internal_body_length_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
@ -217,7 +217,8 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
name.len = sizeof("invalid_referer") - 1;
|
||||
name.data = (u_char *) "invalid_referer";
|
||||
|
||||
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
|
||||
var = ngx_http_add_variable(cf, &name,
|
||||
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH);
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -648,13 +648,17 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
|
||||
rc = cmd->handler(r, ctx, params);
|
||||
|
||||
if (c->closed) {
|
||||
if (c->destroyed) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -244,6 +244,12 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->allow_ranges = 1;
|
||||
|
||||
if (r->header_only || (r->main != r && ngx_file_size(&fi) == 0)) {
|
||||
return ngx_http_send_header(r);
|
||||
}
|
||||
|
||||
/* we need to allocate all before the header would be sent */
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
@ -256,11 +262,9 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->allow_ranges = 1;
|
||||
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
|
||||
if (rc == NGX_ERROR || rc > NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -554,7 +554,7 @@ ngx_http_userid_add_variables(ngx_conf_t *cf)
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_log_op_name_t *op;
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0);
|
||||
var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -562,7 +562,7 @@ ngx_http_userid_add_variables(ngx_conf_t *cf)
|
||||
var->handler = ngx_http_userid_variable;
|
||||
var->data = offsetof(ngx_http_userid_ctx_t, uid_got);
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_userid_set, 0);
|
||||
var = ngx_http_add_variable(cf, &ngx_http_userid_set, NGX_HTTP_VAR_NOHASH);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -70,11 +70,15 @@ static ngx_http_output_body_filter_pt ngx_http_next_filter;
|
||||
static ngx_int_t
|
||||
ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *c;
|
||||
ngx_output_chain_ctx_t *ctx;
|
||||
ngx_http_copy_filter_conf_t *conf;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"copy filter: \"%V\"", &r->uri);
|
||||
c = r->connection;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"copy filter: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
|
||||
|
||||
@ -88,7 +92,7 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module);
|
||||
|
||||
ctx->sendfile = r->connection->sendfile;
|
||||
ctx->sendfile = c->sendfile;
|
||||
ctx->need_in_memory = r->main_filter_need_in_memory
|
||||
|| r->filter_need_in_memory;
|
||||
ctx->need_in_temp = r->filter_need_temporary;
|
||||
@ -102,9 +106,16 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
|
||||
}
|
||||
|
||||
/* the request pool may be already destroyed after ngx_output_chain()*/
|
||||
rc = ngx_output_chain(ctx, in);
|
||||
|
||||
return ngx_output_chain(ctx, in);
|
||||
#if (NGX_DEBUG)
|
||||
if (!c->destroyed) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -966,14 +966,14 @@ ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http output filter \"%V\"", &r->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http output filter \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
rc = ngx_http_top_body_filter(r, in);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
/* NGX_ERROR may be returned by any filter */
|
||||
r->connection->closed = 1;
|
||||
r->connection->error = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -1080,6 +1080,7 @@ ngx_int_t
|
||||
ngx_http_subrequest(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args, ngx_uint_t flags)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *sr;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_postponed_request_t *pr, *p;
|
||||
@ -1090,7 +1091,9 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
sr->signature = NGX_HTTP_MODULE;
|
||||
sr->connection = r->connection;
|
||||
|
||||
c = r->connection;
|
||||
sr->connection = c;
|
||||
|
||||
sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
|
||||
if (sr->ctx == NULL) {
|
||||
@ -1128,16 +1131,13 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
sr->request_line = r->request_line;
|
||||
sr->uri = *uri;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest \"%V\"", uri);
|
||||
|
||||
if (args) {
|
||||
sr->args = *args;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest args \"%V\"", args);
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http subrequest \"%V?%V\"", uri, &sr->args);
|
||||
|
||||
if (flags & NGX_HTTP_ZERO_IN_URI) {
|
||||
sr->zero_in_uri = 1;
|
||||
}
|
||||
@ -1155,8 +1155,8 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
sr->read_event_handler = ngx_http_request_empty_handler;
|
||||
sr->write_event_handler = ngx_http_request_empty_handler;
|
||||
|
||||
if (r->connection->data == r) {
|
||||
sr->connection->data = sr;
|
||||
if (c->data == r) {
|
||||
c->data = sr;
|
||||
}
|
||||
|
||||
sr->in_addr = r->in_addr;
|
||||
@ -1192,7 +1192,12 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
|
||||
ngx_http_handler(sr);
|
||||
|
||||
/* the request pool may be already destroyed */
|
||||
#if (NGX_LOG_DEBUG)
|
||||
if (!c->destroyed) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http subrequest done \"%V?%V\"", uri, &sr->args);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -1204,22 +1209,19 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
{
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"internal redirect: \"%V\"", uri);
|
||||
|
||||
r->uri = *uri;
|
||||
|
||||
if (args) {
|
||||
r->args = *args;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"internal redirect args: \"%V\"", args);
|
||||
|
||||
} else {
|
||||
r->args.len = 0;
|
||||
r->args.data = NULL;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"internal redirect: \"%V?%V\"", uri, &r->args);
|
||||
|
||||
if (ngx_http_set_exten(r) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_postpone_filter_init(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
@ -53,8 +55,8 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
ngx_chain_t *out;
|
||||
ngx_http_postponed_request_t *pr, **ppr;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter \"%V\" %p", &r->uri, in);
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
|
||||
|
||||
if (r != r->connection->data || (r->postponed && in)) {
|
||||
|
||||
@ -104,20 +106,80 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter out \"%V\"", &r->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter out \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
rc = ngx_http_next_filter(r->main, out);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
/* NGX_ERROR may be returned by any filter */
|
||||
r->connection->closed = 1;
|
||||
r->connection->error = 1;
|
||||
}
|
||||
|
||||
if (r->postponed == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ngx_http_postpone_filter_output_postponed_request(r);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
/* NGX_ERROR may be returned by any filter */
|
||||
r->connection->error = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_http_postponed_request_t *pr;
|
||||
|
||||
for ( ;; ) {
|
||||
pr = r->postponed;
|
||||
|
||||
if (pr == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (pr->request) {
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter handle \"%V?%V\"",
|
||||
&pr->request->uri, &pr->request->args);
|
||||
|
||||
if (!pr->request->done) {
|
||||
r->connection->data = pr->request;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
rc = ngx_http_postpone_filter_output_postponed_request(pr->request);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
r->postponed = r->postponed->next;
|
||||
pr = r->postponed;
|
||||
}
|
||||
|
||||
if (pr->out) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter out postponed \"%V?%V\"",
|
||||
&r->uri, &r->args);
|
||||
|
||||
if (ngx_http_next_filter(r->main, pr->out) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
r->postponed = r->postponed->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
|
@ -30,7 +30,6 @@ static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r);
|
||||
static void ngx_http_request_handler(ngx_event_t *ev);
|
||||
static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
|
||||
static void ngx_http_writer(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_postponed_handler(ngx_http_request_t *r);
|
||||
|
||||
static void ngx_http_block_read(ngx_http_request_t *r);
|
||||
static void ngx_http_read_discarded_body_handler(ngx_http_request_t *r);
|
||||
@ -404,6 +403,8 @@ void ngx_http_init_request(ngx_event_t *rev)
|
||||
}
|
||||
|
||||
c->single_connection = 1;
|
||||
c->destroyed = 0;
|
||||
|
||||
r->connection = c;
|
||||
|
||||
r->main = r;
|
||||
@ -455,7 +456,7 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
n = recv(c->fd, buf, 1, MSG_PEEK);
|
||||
n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
|
||||
|
||||
if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
|
||||
return;
|
||||
@ -1448,10 +1449,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http finalize request: %d, \"%V\"", rc, &r->uri);
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http finalize request: %d, \"%V?%V\"",
|
||||
rc, &r->uri, &r->args);
|
||||
|
||||
if (rc == NGX_ERROR || r->connection->closed) {
|
||||
if (rc == NGX_ERROR || r->connection->error) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
@ -1482,8 +1484,9 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
r->done = 1;
|
||||
|
||||
if (r != r->connection->data) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http finalize non-active request: \"%V\"", &r->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http finalize non-active request: \"%V?%V\"",
|
||||
&r->uri, &r->args);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1491,8 +1494,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
|
||||
pr = r->parent;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http parent request: \"%V\"", &pr->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http parent request: \"%V?%V\"", &pr->uri, &pr->args);
|
||||
|
||||
if (rc != NGX_AGAIN) {
|
||||
pr->connection->data = pr;
|
||||
@ -1500,8 +1503,9 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
|
||||
if (pr->postponed) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http request: \"%V\" has postponed", &pr->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http request: \"%V?%V\" has postponed",
|
||||
&pr->uri, &pr->args);
|
||||
|
||||
if (rc != NGX_AGAIN && pr->postponed->request == r) {
|
||||
pr->postponed = pr->postponed->next;
|
||||
@ -1511,13 +1515,14 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http request: \"%V\" still has postponed",
|
||||
&pr->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http request: \"%V?%V\" still has postponed",
|
||||
&pr->uri, &pr->args);
|
||||
|
||||
if (pr->done) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http wake parent request: \"%V\"", &pr->uri);
|
||||
if (pr->done || pr->postponed->out) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http wake parent request: \"%V?%V\"",
|
||||
&pr->uri, &pr->args);
|
||||
|
||||
pr->write_event_handler(pr);
|
||||
}
|
||||
@ -1619,8 +1624,8 @@ ngx_http_writer(ngx_http_request_t *r)
|
||||
c = r->connection;
|
||||
wev = c->write;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, wev->log, 0,
|
||||
"http writer handler: \"%V\"", &r->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
|
||||
"http writer handler: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
if (wev->timedout) {
|
||||
if (!wev->delayed) {
|
||||
@ -1661,21 +1666,15 @@ ngx_http_writer(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
if (r->postponed) {
|
||||
rc = ngx_http_postponed_handler(r);
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
/* the request pool may be already destroyed */
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
rc = ngx_http_output_filter(r, NULL);
|
||||
rc = ngx_http_output_filter(r, NULL);
|
||||
|
||||
if (c->destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http writer output filter: %d, \"%V\"", rc, &r->uri);
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http writer output filter: %d, \"%V?%V\"",
|
||||
rc, &r->uri, &r->args);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
|
||||
@ -1690,67 +1689,13 @@ ngx_http_writer(ngx_http_request_t *r)
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, wev->log, 0,
|
||||
"http writer done: \"%V\"", &r->uri);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
|
||||
"http writer done: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
ngx_http_finalize_request(r, rc);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postponed_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_http_postponed_request_t *pr;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone handler \"%V\"", &r->uri);
|
||||
|
||||
pr = r->postponed;
|
||||
|
||||
if (pr->request == NULL) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postponed data \"%V\" %p", &r->uri, pr->out);
|
||||
|
||||
rc = ngx_http_output_filter(r, NULL);
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
/* the request pool is already destroyed */
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postponed output filter: %d", rc);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
pr = r->postponed;
|
||||
|
||||
if (pr == NULL) {
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
r = pr->request;
|
||||
r->connection->data = r;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http wake child request \"%V\"", &r->uri);
|
||||
|
||||
r->write_event_handler(r);
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_block_read(ngx_http_request_t *r)
|
||||
{
|
||||
@ -1862,7 +1807,7 @@ ngx_http_read_discarded_body(ngx_http_request_t *r)
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
|
||||
r->connection->closed = 1;
|
||||
r->connection->error = 1;
|
||||
|
||||
/*
|
||||
* if a client request body is discarded then we already set
|
||||
@ -2029,20 +1974,10 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
|
||||
rev->handler = ngx_http_keepalive_handler;
|
||||
|
||||
if (wev->active) {
|
||||
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2224,20 +2159,10 @@ ngx_http_set_lingering_close(ngx_http_request_t *r)
|
||||
wev = c->write;
|
||||
wev->handler = ngx_http_empty_handler;
|
||||
|
||||
if (wev->active) {
|
||||
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2324,7 +2249,7 @@ void
|
||||
ngx_http_request_empty_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http requets empty handler");
|
||||
"http request empty handler");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2442,6 +2367,8 @@ ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error)
|
||||
|
||||
r->request_line.len = 0;
|
||||
|
||||
r->connection->destroyed = 1;
|
||||
|
||||
ngx_destroy_pool(r->pool);
|
||||
}
|
||||
|
||||
@ -2469,6 +2396,8 @@ ngx_http_close_connection(ngx_connection_t *c)
|
||||
ngx_atomic_fetch_add(ngx_stat_active, -1);
|
||||
#endif
|
||||
|
||||
c->destroyed = 1;
|
||||
|
||||
pool = c->pool;
|
||||
|
||||
ngx_close_connection(c);
|
||||
|
@ -230,7 +230,7 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
if (n == 0 || n == NGX_ERROR) {
|
||||
c->closed = 1;
|
||||
c->error = 1;
|
||||
return NGX_HTTP_BAD_REQUEST;
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ ngx_module_t ngx_http_upstream_module = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = {
|
||||
static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = {
|
||||
{ ngx_string("upstream_status"), 0, NULL,
|
||||
ngx_http_upstream_log_status_getlen,
|
||||
ngx_http_upstream_log_status },
|
||||
@ -248,10 +248,10 @@ static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = {
|
||||
static ngx_http_variable_t ngx_http_upstream_vars[] = {
|
||||
|
||||
{ ngx_string("upstream_status"),
|
||||
ngx_http_upstream_status_variable, 0, 0, 0 },
|
||||
ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_string("upstream_response_time"),
|
||||
ngx_http_upstream_response_time_variable, 0, 0, 0 },
|
||||
ngx_http_upstream_response_time_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0, 0 }
|
||||
};
|
||||
@ -387,7 +387,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
||||
c = r->connection;
|
||||
u = r->upstream;
|
||||
|
||||
if (c->closed) {
|
||||
if (c->error) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_CLIENT_CLOSED_REQUEST);
|
||||
return;
|
||||
@ -406,7 +406,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
ev->eof = 1;
|
||||
c->closed = 1;
|
||||
c->error = 1;
|
||||
|
||||
if (ev->kq_errno) {
|
||||
ev->error = 1;
|
||||
@ -473,7 +473,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
ev->eof = 1;
|
||||
c->closed = 1;
|
||||
c->error = 1;
|
||||
|
||||
if (!u->cachable && u->peer.connection) {
|
||||
ngx_log_error(NGX_LOG_INFO, ev->log, err,
|
||||
@ -1125,12 +1125,14 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
||||
static void
|
||||
ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ssize_t size;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, key;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_event_pipe_t *p;
|
||||
ngx_connection_t *c;
|
||||
ngx_pool_cleanup_t *cl;
|
||||
ngx_pool_cleanup_file_t *clf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
@ -1209,6 +1211,8 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
}
|
||||
}
|
||||
|
||||
c = r->connection;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (u->pipe == NULL) {
|
||||
@ -1231,6 +1235,23 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
return;
|
||||
}
|
||||
|
||||
if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
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_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
}
|
||||
|
||||
size = u->buffer.last - u->buffer.pos;
|
||||
|
||||
if (size) {
|
||||
@ -1241,7 +1262,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_upstream_process_non_buffered_body(r->connection->write);
|
||||
ngx_http_upstream_process_non_buffered_body(c->write);
|
||||
|
||||
} else {
|
||||
u->buffer.pos = u->buffer.start;
|
||||
@ -1262,7 +1283,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) {
|
||||
if (ngx_close_file(u->cache->ctx.file.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
ngx_close_file_n " \"%s\" failed",
|
||||
u->cache->ctx.file.name.data);
|
||||
}
|
||||
@ -1292,9 +1313,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
p->bufs = u->conf->bufs;
|
||||
p->busy_size = u->conf->busy_buffers_size;
|
||||
p->upstream = u->peer.connection;
|
||||
p->downstream = r->connection;
|
||||
p->downstream = c;
|
||||
p->pool = r->pool;
|
||||
p->log = r->connection->log;
|
||||
p->log = c->log;
|
||||
|
||||
p->cachable = u->cachable;
|
||||
|
||||
@ -1305,7 +1326,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
}
|
||||
|
||||
p->temp_file->file.fd = NGX_INVALID_FILE;
|
||||
p->temp_file->file.log = r->connection->log;
|
||||
p->temp_file->file.log = c->log;
|
||||
p->temp_file->path = u->conf->temp_path;
|
||||
p->temp_file->pool = r->pool;
|
||||
|
||||
@ -1364,7 +1385,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
*/
|
||||
|
||||
p->cyclic_temp_file = 1;
|
||||
r->connection->sendfile = 0;
|
||||
c->sendfile = 0;
|
||||
|
||||
} else {
|
||||
p->cyclic_temp_file = 0;
|
||||
@ -1394,8 +1415,9 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_buf_t *b;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t do_write;
|
||||
ngx_connection_t *c;
|
||||
ngx_connection_t *c, *client;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
@ -1426,6 +1448,7 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
||||
|
||||
r = c->data;
|
||||
u = r->upstream;
|
||||
client = r->connection;
|
||||
|
||||
b = &u->buffer;
|
||||
|
||||
@ -1438,7 +1461,13 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
||||
if (do_write) {
|
||||
|
||||
if (u->out_bufs || u->busy_bufs) {
|
||||
if (ngx_http_output_filter(r, u->out_bufs) == NGX_ERROR) {
|
||||
rc = ngx_http_output_filter(r, u->out_bufs);
|
||||
|
||||
if (client->destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
@ -1490,18 +1519,20 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(r->connection->write, clcf->send_lowat)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
if (client->data == r) {
|
||||
if (ngx_handle_write_event(client->write, clcf->send_lowat)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->connection->write->active) {
|
||||
ngx_add_timer(r->connection->write, clcf->send_timeout);
|
||||
if (client->write->active) {
|
||||
ngx_add_timer(client->write, clcf->send_timeout);
|
||||
|
||||
} else if (r->connection->write->timer_set) {
|
||||
ngx_del_timer(r->connection->write);
|
||||
} else if (client->write->timer_set) {
|
||||
ngx_del_timer(client->write);
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) {
|
||||
@ -1512,8 +1543,8 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
||||
if (u->peer.connection->read->active) {
|
||||
ngx_add_timer(u->peer.connection->read, u->conf->read_timeout);
|
||||
|
||||
} else if (r->connection->read->timer_set) {
|
||||
ngx_del_timer(r->connection->read);
|
||||
} else if (u->peer.connection->read->timer_set) {
|
||||
ngx_del_timer(u->peer.connection->read);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1577,13 +1608,14 @@ static void
|
||||
ngx_http_upstream_process_body(ngx_event_t *ev)
|
||||
{
|
||||
ngx_event_pipe_t *p;
|
||||
ngx_connection_t *c;
|
||||
ngx_connection_t *c, *downstream;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
c = ev->data;
|
||||
r = c->data;
|
||||
u = r->upstream;
|
||||
downstream = r->connection;
|
||||
|
||||
if (ev->write) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
@ -1618,6 +1650,11 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
|
||||
}
|
||||
|
||||
if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
|
||||
|
||||
if (downstream->destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
@ -1648,6 +1685,11 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
|
||||
}
|
||||
|
||||
if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
|
||||
|
||||
if (downstream->destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
@ -1761,7 +1803,7 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
||||
}
|
||||
}
|
||||
|
||||
if (r->connection->closed) {
|
||||
if (r->connection->error) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_CLIENT_CLOSED_REQUEST);
|
||||
return;
|
||||
|
@ -843,6 +843,13 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
"http variables: %ui", cmcf->variables.nelts);
|
||||
|
||||
|
||||
for (n = 0; n < cmcf->all_variables.nelts; n++) {
|
||||
if (av[n].flags & NGX_HTTP_VAR_NOHASH) {
|
||||
av[n].name.data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* init the all http variables hash */
|
||||
|
||||
cmcf->variables_hash.max_size = 500;
|
||||
|
@ -35,6 +35,7 @@ typedef ngx_int_t (*ngx_http_get_variable_pt) (ngx_http_request_t *r,
|
||||
#define NGX_HTTP_VAR_CHANGABLE 1
|
||||
#define NGX_HTTP_VAR_NOCACHABLE 2
|
||||
#define NGX_HTTP_VAR_INDEXED 4
|
||||
#define NGX_HTTP_VAR_NOHASH 8
|
||||
|
||||
|
||||
struct ngx_http_variable_s {
|
||||
|
@ -55,7 +55,7 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
|
||||
c = r->connection;
|
||||
|
||||
if (c->closed) {
|
||||
if (c->error) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
}
|
||||
|
||||
if (chain == NGX_CHAIN_ERROR) {
|
||||
c->closed = 1;
|
||||
c->error = 1;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
void **main_conf;
|
||||
void **srv_conf;
|
||||
void **main_conf;
|
||||
void **srv_conf;
|
||||
} ngx_imap_conf_ctx_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t servers; /* ngx_imap_core_srv_conf_t */
|
||||
ngx_array_t servers; /* ngx_imap_core_srv_conf_t */
|
||||
} ngx_imap_core_main_conf_t;
|
||||
|
||||
|
||||
@ -34,17 +34,20 @@ typedef struct {
|
||||
#define NGX_IMAP_IMAP_PROTOCOL 1
|
||||
|
||||
typedef struct {
|
||||
ngx_msec_t timeout;
|
||||
ngx_msec_t timeout;
|
||||
|
||||
size_t imap_client_buffer_size;
|
||||
size_t imap_client_buffer_size;
|
||||
|
||||
ngx_uint_t protocol;
|
||||
ngx_uint_t protocol;
|
||||
|
||||
ngx_buf_t *pop3_capability;
|
||||
ngx_buf_t *imap_capability;
|
||||
ngx_str_t pop3_capability;
|
||||
ngx_str_t pop3_starttls_capability;
|
||||
ngx_str_t imap_capability;
|
||||
ngx_str_t imap_starttls_capability;
|
||||
ngx_str_t imap_starttls_only_capability;
|
||||
|
||||
ngx_array_t pop3_capabilities;
|
||||
ngx_array_t imap_capabilities;
|
||||
ngx_array_t pop3_capabilities;
|
||||
ngx_array_t imap_capabilities;
|
||||
|
||||
/* server ctx */
|
||||
ngx_imap_conf_ctx_t *ctx;
|
||||
@ -52,11 +55,12 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
void *(*create_main_conf)(ngx_conf_t *cf);
|
||||
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
|
||||
void *(*create_main_conf)(ngx_conf_t *cf);
|
||||
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
|
||||
|
||||
void *(*create_srv_conf)(ngx_conf_t *cf);
|
||||
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
|
||||
void *(*create_srv_conf)(ngx_conf_t *cf);
|
||||
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
|
||||
void *conf);
|
||||
} ngx_imap_module_t;
|
||||
|
||||
|
||||
@ -126,8 +130,8 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t *client;
|
||||
ngx_imap_session_t *session;
|
||||
ngx_str_t *client;
|
||||
ngx_imap_session_t *session;
|
||||
} ngx_imap_log_ctx_t;
|
||||
|
||||
|
||||
@ -136,22 +140,24 @@ typedef struct {
|
||||
#define NGX_POP3_CAPA 3
|
||||
#define NGX_POP3_QUIT 4
|
||||
#define NGX_POP3_NOOP 5
|
||||
#define NGX_POP3_APOP 6
|
||||
#define NGX_POP3_STAT 7
|
||||
#define NGX_POP3_LIST 8
|
||||
#define NGX_POP3_RETR 9
|
||||
#define NGX_POP3_DELE 10
|
||||
#define NGX_POP3_RSET 11
|
||||
#define NGX_POP3_TOP 12
|
||||
#define NGX_POP3_UIDL 13
|
||||
#define NGX_POP3_STLS 6
|
||||
#define NGX_POP3_APOP 7
|
||||
#define NGX_POP3_STAT 8
|
||||
#define NGX_POP3_LIST 9
|
||||
#define NGX_POP3_RETR 10
|
||||
#define NGX_POP3_DELE 11
|
||||
#define NGX_POP3_RSET 12
|
||||
#define NGX_POP3_TOP 13
|
||||
#define NGX_POP3_UIDL 14
|
||||
|
||||
|
||||
#define NGX_IMAP_LOGIN 1
|
||||
#define NGX_IMAP_LOGOUT 2
|
||||
#define NGX_IMAP_CAPABILITY 3
|
||||
#define NGX_IMAP_NOOP 4
|
||||
#define NGX_IMAP_STARTTLS 5
|
||||
|
||||
#define NGX_IMAP_NEXT 5
|
||||
#define NGX_IMAP_NEXT 6
|
||||
|
||||
|
||||
#define NGX_IMAP_PARSE_INVALID_COMMAND 20
|
||||
|
@ -727,7 +727,7 @@ ngx_imap_auth_sleep_handler(ngx_event_t *rev)
|
||||
|
||||
ngx_imap_send(s->connection->write);
|
||||
|
||||
if (c->closed) {
|
||||
if (c->destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1181,6 +1181,8 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ahcf->peers->number = 1;
|
||||
|
||||
ahcf->host_header = inet_upstream.host_header;
|
||||
ahcf->uri = inet_upstream.uri;
|
||||
}
|
||||
|
@ -181,8 +181,8 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_imap_core_srv_conf_t *prev = parent;
|
||||
ngx_imap_core_srv_conf_t *conf = child;
|
||||
|
||||
u_char *p;
|
||||
size_t size;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *c, *d;
|
||||
ngx_uint_t i;
|
||||
|
||||
@ -218,22 +218,40 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
size += c[i].len + sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
b = ngx_create_temp_buf(cf->pool, size);
|
||||
if (b == NULL) {
|
||||
p = ngx_palloc(cf->pool, size);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, "+OK Capability list follows" CRLF,
|
||||
sizeof("+OK Capability list follows" CRLF) - 1);
|
||||
conf->pop3_capability.len = size;
|
||||
conf->pop3_capability.data = p;
|
||||
|
||||
p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
|
||||
sizeof("+OK Capability list follows" CRLF) - 1);
|
||||
|
||||
for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
|
||||
b->last = ngx_cpymem(b->last, c[i].data, c[i].len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
p = ngx_cpymem(p, c[i].data, c[i].len);
|
||||
*p++ = CR; *p++ = LF;
|
||||
}
|
||||
|
||||
*b->last++ = '.'; *b->last++ = CR; *b->last++ = LF;
|
||||
*p++ = '.'; *p++ = CR; *p = LF;
|
||||
|
||||
conf->pop3_capability = b;
|
||||
|
||||
size += sizeof("STLS" CRLF) - 1;
|
||||
|
||||
p = ngx_palloc(cf->pool, size);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->pop3_starttls_capability.len = size;
|
||||
conf->pop3_starttls_capability.data = p;
|
||||
|
||||
p = ngx_cpymem(p, conf->pop3_capability.data,
|
||||
conf->pop3_capability.len - (sizeof("." CRLF) - 1));
|
||||
|
||||
p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
|
||||
*p++ = '.'; *p++ = CR; *p = LF;
|
||||
|
||||
|
||||
if (conf->imap_capabilities.nelts == 0) {
|
||||
@ -259,21 +277,55 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
size += 1 + c[i].len;
|
||||
}
|
||||
|
||||
b = ngx_create_temp_buf(cf->pool, size);
|
||||
if (b == NULL) {
|
||||
p = ngx_palloc(cf->pool, size);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
|
||||
conf->imap_capability.len = size;
|
||||
conf->imap_capability.data = p;
|
||||
|
||||
p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
|
||||
|
||||
for (i = 0; i < conf->imap_capabilities.nelts; i++) {
|
||||
*b->last++ = ' ';
|
||||
b->last = ngx_cpymem(b->last, c[i].data, c[i].len);
|
||||
*p++ = ' ';
|
||||
p = ngx_cpymem(p, c[i].data, c[i].len);
|
||||
}
|
||||
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
*p++ = CR; *p = LF;
|
||||
|
||||
|
||||
size += sizeof(" STARTTLS") - 1;
|
||||
|
||||
p = ngx_palloc(cf->pool, size);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->imap_starttls_capability.len = size;
|
||||
conf->imap_starttls_capability.data = p;
|
||||
|
||||
p = ngx_cpymem(p, conf->imap_capability.data,
|
||||
conf->imap_capability.len - (sizeof(CRLF) - 1));
|
||||
p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
|
||||
*p++ = CR; *p = LF;
|
||||
|
||||
|
||||
size += sizeof(" LOGINDISABLED") - 1;
|
||||
|
||||
p = ngx_palloc(cf->pool, size);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->imap_starttls_only_capability.len = size;
|
||||
conf->imap_starttls_only_capability.data = p;
|
||||
|
||||
p = ngx_cpymem(p, conf->imap_starttls_capability.data,
|
||||
conf->imap_starttls_capability.len - (sizeof(CRLF) - 1));
|
||||
p = ngx_cpymem(p, " LOGINDISABLED", sizeof(" LOGINDISABLED") - 1);
|
||||
*p++ = CR; *p = LF;
|
||||
|
||||
conf->imap_capability = b;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s);
|
||||
static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
static void ngx_imap_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
|
||||
static void ngx_imap_ssl_handshake_handler(ngx_connection_t *c);
|
||||
#endif
|
||||
|
||||
@ -43,11 +44,10 @@ static u_char imap_invalid_command[] = "BAD invalid command" CRLF;
|
||||
void
|
||||
ngx_imap_init_connection(ngx_connection_t *c)
|
||||
{
|
||||
ngx_imap_log_ctx_t *lctx;
|
||||
ngx_imap_log_ctx_t *lctx;
|
||||
#if (NGX_IMAP_SSL)
|
||||
ngx_imap_conf_ctx_t *ctx;
|
||||
ngx_imap_ssl_conf_t *sslcf;
|
||||
ngx_imap_core_srv_conf_t *cscf;
|
||||
ngx_imap_conf_ctx_t *ctx;
|
||||
ngx_imap_ssl_conf_t *sslcf;
|
||||
#endif
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%ui client %V connected to %V",
|
||||
@ -75,23 +75,7 @@ ngx_imap_init_connection(ngx_connection_t *c)
|
||||
sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module);
|
||||
|
||||
if (sslcf->enable) {
|
||||
if (ngx_ssl_create_connection(&sslcf->ssl, c, 0) == NGX_ERROR) {
|
||||
ngx_imap_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_ssl_handshake(c) == NGX_AGAIN) {
|
||||
|
||||
cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module);
|
||||
|
||||
ngx_add_timer(c->read, cscf->timeout);
|
||||
|
||||
c->ssl->handler = ngx_imap_ssl_handshake_handler;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_imap_ssl_handshake_handler(c);
|
||||
ngx_imap_ssl_init_connection(&sslcf->ssl, c);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -103,16 +87,70 @@ ngx_imap_init_connection(ngx_connection_t *c)
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
|
||||
static void
|
||||
ngx_imap_starttls_handler(ngx_event_t *rev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_imap_session_t *s;
|
||||
ngx_imap_ssl_conf_t *sslcf;
|
||||
|
||||
c = rev->data;
|
||||
s = c->data;
|
||||
|
||||
c->log->action = "in starttls state";
|
||||
|
||||
sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
|
||||
|
||||
ngx_imap_ssl_init_connection(&sslcf->ssl, c);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_imap_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
|
||||
{
|
||||
ngx_imap_conf_ctx_t *ctx;
|
||||
ngx_imap_core_srv_conf_t *cscf;
|
||||
|
||||
if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
|
||||
ngx_imap_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_ssl_handshake(c) == NGX_AGAIN) {
|
||||
|
||||
ctx = c->ctx;
|
||||
cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module);
|
||||
|
||||
ngx_add_timer(c->read, cscf->timeout);
|
||||
|
||||
c->ssl->handler = ngx_imap_ssl_handshake_handler;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_imap_ssl_handshake_handler(c);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_imap_ssl_handshake_handler(ngx_connection_t *c)
|
||||
{
|
||||
if (c->ssl->handshaked) {
|
||||
|
||||
if (c->data) {
|
||||
c->read->handler = ngx_imap_init_protocol;
|
||||
c->write->handler = ngx_imap_send;
|
||||
|
||||
ngx_imap_init_protocol(c->read);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_imap_init_session(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_imap_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -253,11 +291,6 @@ ngx_imap_init_protocol(ngx_event_t *rev)
|
||||
|
||||
s = c->data;
|
||||
|
||||
if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) {
|
||||
ngx_imap_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->protocol == NGX_IMAP_POP3_PROTOCOL) {
|
||||
size = 128;
|
||||
s->imap_state = ngx_pop3_start;
|
||||
@ -270,10 +303,19 @@ ngx_imap_init_protocol(ngx_event_t *rev)
|
||||
c->read->handler = ngx_imap_auth_state;
|
||||
}
|
||||
|
||||
s->buffer = ngx_create_temp_buf(c->pool, size);
|
||||
if (s->buffer == NULL) {
|
||||
ngx_imap_session_internal_server_error(s);
|
||||
return;
|
||||
if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t))
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_imap_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->buffer = ngx_create_temp_buf(c->pool, size);
|
||||
if (s->buffer == NULL) {
|
||||
ngx_imap_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
c->read->handler(rev);
|
||||
@ -291,6 +333,9 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
||||
ngx_connection_t *c;
|
||||
ngx_imap_session_t *s;
|
||||
ngx_imap_core_srv_conf_t *cscf;
|
||||
#if (NGX_IMAP_SSL)
|
||||
ngx_imap_ssl_conf_t *sslcf;
|
||||
#endif
|
||||
|
||||
c = rev->data;
|
||||
s = c->data;
|
||||
@ -357,6 +402,19 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
||||
switch (s->command) {
|
||||
|
||||
case NGX_IMAP_LOGIN:
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
|
||||
if (c->ssl == NULL) {
|
||||
sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
|
||||
|
||||
if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) {
|
||||
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
arg = s->args.elts;
|
||||
|
||||
if (s->args.nelts == 2 && arg[0].len) {
|
||||
@ -410,8 +468,28 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
||||
|
||||
case NGX_IMAP_CAPABILITY:
|
||||
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
|
||||
text = cscf->imap_capability->pos;
|
||||
text_len = cscf->imap_capability->last - cscf->imap_capability->pos;
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
|
||||
if (c->ssl == NULL) {
|
||||
sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
|
||||
|
||||
if (sslcf->starttls == NGX_IMAP_STARTTLS_ON) {
|
||||
text_len = cscf->imap_starttls_capability.len;
|
||||
text = cscf->imap_starttls_capability.data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) {
|
||||
text_len = cscf->imap_starttls_only_capability.len;
|
||||
text = cscf->imap_starttls_only_capability.data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
text_len = cscf->imap_capability.len;
|
||||
text = cscf->imap_capability.data;
|
||||
break;
|
||||
|
||||
case NGX_IMAP_LOGOUT:
|
||||
@ -423,6 +501,21 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
||||
case NGX_IMAP_NOOP:
|
||||
break;
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
|
||||
case NGX_IMAP_STARTTLS:
|
||||
if (c->ssl == NULL) {
|
||||
sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
|
||||
if (sslcf->starttls) {
|
||||
c->read->handler = ngx_imap_starttls_handler;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
|
||||
break;
|
||||
@ -492,6 +585,9 @@ ngx_pop3_auth_state(ngx_event_t *rev)
|
||||
ngx_connection_t *c;
|
||||
ngx_imap_session_t *s;
|
||||
ngx_imap_core_srv_conf_t *cscf;
|
||||
#if (NGX_IMAP_SSL)
|
||||
ngx_imap_ssl_conf_t *sslcf;
|
||||
#endif
|
||||
|
||||
c = rev->data;
|
||||
s = c->data;
|
||||
@ -554,8 +650,22 @@ ngx_pop3_auth_state(ngx_event_t *rev)
|
||||
|
||||
case NGX_POP3_CAPA:
|
||||
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
|
||||
text = cscf->pop3_capability->pos;
|
||||
size = cscf->pop3_capability->last - cscf->pop3_capability->pos;
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
|
||||
if (c->ssl == NULL) {
|
||||
sslcf = ngx_imap_get_module_srv_conf(s,
|
||||
ngx_imap_ssl_module);
|
||||
if (sslcf->starttls) {
|
||||
size = cscf->pop3_starttls_capability.len;
|
||||
text = cscf->pop3_starttls_capability.data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
size = cscf->pop3_capability.len;
|
||||
text = cscf->pop3_capability.data;
|
||||
break;
|
||||
|
||||
case NGX_POP3_QUIT:
|
||||
@ -565,6 +675,22 @@ ngx_pop3_auth_state(ngx_event_t *rev)
|
||||
case NGX_POP3_NOOP:
|
||||
break;
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
|
||||
case NGX_POP3_STLS:
|
||||
if (c->ssl == NULL) {
|
||||
sslcf = ngx_imap_get_module_srv_conf(s,
|
||||
ngx_imap_ssl_module);
|
||||
if (sslcf->starttls) {
|
||||
c->read->handler = ngx_imap_starttls_handler;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
s->imap_state = ngx_pop3_start;
|
||||
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
|
||||
@ -616,8 +742,8 @@ ngx_pop3_auth_state(ngx_event_t *rev)
|
||||
|
||||
case NGX_POP3_CAPA:
|
||||
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
|
||||
text = cscf->pop3_capability->pos;
|
||||
size = cscf->pop3_capability->last - cscf->pop3_capability->pos;
|
||||
size = cscf->pop3_capability.len;
|
||||
text = cscf->pop3_capability.data;
|
||||
break;
|
||||
|
||||
case NGX_POP3_QUIT:
|
||||
@ -735,7 +861,7 @@ ngx_imap_close_connection(ngx_connection_t *c)
|
||||
|
||||
#endif
|
||||
|
||||
c->closed = 1;
|
||||
c->destroyed = 1;
|
||||
|
||||
pool = c->pool;
|
||||
|
||||
|
@ -119,6 +119,25 @@ ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s)
|
||||
}
|
||||
break;
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
case 8:
|
||||
if ((c[0] == 'S'|| c[0] == 's')
|
||||
&& (c[1] == 'T'|| c[1] == 't')
|
||||
&& (c[2] == 'A'|| c[2] == 'a')
|
||||
&& (c[3] == 'R'|| c[3] == 'r')
|
||||
&& (c[4] == 'T'|| c[4] == 't')
|
||||
&& (c[5] == 'T'|| c[5] == 't')
|
||||
&& (c[6] == 'L'|| c[6] == 'l')
|
||||
&& (c[7] == 'S'|| c[7] == 's'))
|
||||
{
|
||||
s->command = NGX_IMAP_STARTTLS;
|
||||
|
||||
} else {
|
||||
goto invalid;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 10:
|
||||
if ((c[0] == 'C'|| c[0] == 'c')
|
||||
&& (c[1] == 'A'|| c[1] == 'a')
|
||||
@ -421,7 +440,11 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
|
||||
} else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
|
||||
{
|
||||
s->command = NGX_POP3_NOOP;
|
||||
|
||||
#if (NGX_IMAP_SSL)
|
||||
} else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S')
|
||||
{
|
||||
s->command = NGX_POP3_STLS;
|
||||
#endif
|
||||
} else {
|
||||
goto invalid;
|
||||
}
|
||||
|
@ -286,8 +286,6 @@ ngx_imap_proxy_imap_handler(ngx_event_t *rev)
|
||||
|
||||
c->log->action = NULL;
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
|
||||
|
||||
c->log->action = "proxying";
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,16 +403,24 @@ ngx_imap_proxy_pop3_handler(ngx_event_t *rev)
|
||||
|
||||
c->log->action = NULL;
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
|
||||
|
||||
c->log->action = "proxying";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_imap_proxy_dummy_handler(ngx_event_t *ev)
|
||||
ngx_imap_proxy_dummy_handler(ngx_event_t *wev)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, ev->log, 0, "imap proxy dummy handler");
|
||||
ngx_connection_t *c;
|
||||
ngx_imap_session_t *s;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, wev->log, 0, "imap proxy dummy handler");
|
||||
|
||||
if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {
|
||||
c = wev->data;
|
||||
s = c->data;
|
||||
|
||||
ngx_imap_proxy_close_session(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -487,11 +493,11 @@ ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t what)
|
||||
static void
|
||||
ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
{
|
||||
char *action;
|
||||
char *action, *recv_action, *send_action;
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_buf_t *b;
|
||||
ngx_uint_t again, do_write;
|
||||
ngx_uint_t do_write;
|
||||
ngx_connection_t *c, *src, *dst;
|
||||
ngx_imap_session_t *s;
|
||||
ngx_imap_proxy_conf_t *pcf;
|
||||
@ -500,6 +506,8 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
s = c->data;
|
||||
|
||||
if (ev->timedout) {
|
||||
c->log->action = "proxying";
|
||||
|
||||
if (c == s->connection) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
|
||||
"client timed out");
|
||||
@ -516,11 +524,15 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
|
||||
if (c == s->connection) {
|
||||
if (ev->write) {
|
||||
recv_action = "proxying and reading from upstream";
|
||||
send_action = "proxying and sending to client";
|
||||
src = s->proxy->upstream.connection;
|
||||
dst = c;
|
||||
b = s->proxy->buffer;
|
||||
|
||||
} else {
|
||||
recv_action = "proxying and reading from client";
|
||||
send_action = "proxying and sending to upstream";
|
||||
src = c;
|
||||
dst = s->proxy->upstream.connection;
|
||||
b = s->buffer;
|
||||
@ -528,11 +540,15 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
|
||||
} else {
|
||||
if (ev->write) {
|
||||
recv_action = "proxying and reading from upstream";
|
||||
send_action = "proxying and sending to client";
|
||||
src = s->connection;
|
||||
dst = c;
|
||||
b = s->buffer;
|
||||
|
||||
} else {
|
||||
recv_action = "proxying and reading from client";
|
||||
send_action = "proxying and sending to upstream";
|
||||
src = c;
|
||||
dst = s->connection;
|
||||
b = s->proxy->buffer;
|
||||
@ -545,14 +561,15 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
"imap proxy handler: %d, #%d > #%d",
|
||||
do_write, src->fd, dst->fd);
|
||||
|
||||
do {
|
||||
again = 0;
|
||||
for ( ;; ) {
|
||||
|
||||
if (do_write == 1) {
|
||||
if (do_write) {
|
||||
|
||||
size = b->last - b->pos;
|
||||
|
||||
if (size && dst->write->ready) {
|
||||
c->log->action = send_action;
|
||||
|
||||
n = dst->send(dst, b->pos, size);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
@ -561,7 +578,6 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
again = 1;
|
||||
b->pos += n;
|
||||
|
||||
if (b->pos == b->last) {
|
||||
@ -569,58 +585,74 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
|
||||
b->last = b->start;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == NGX_AGAIN || n < (ssize_t) size) {
|
||||
if (ngx_handle_write_event(dst->write, /* TODO: LOWAT */ 0)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size = b->end - b->last;
|
||||
|
||||
if (size && src->read->ready) {
|
||||
c->log->action = recv_action;
|
||||
|
||||
n = src->recv(src, b->last, size);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
action = c->log->action;
|
||||
c->log->action = NULL;
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done");
|
||||
c->log->action = action;
|
||||
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
if (n == NGX_AGAIN || n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
again = 1;
|
||||
do_write = 1;
|
||||
b->last += n;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == NGX_AGAIN || n < (ssize_t) size) {
|
||||
if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) {
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == s->connection) {
|
||||
pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
|
||||
ngx_add_timer(c->read, pcf->timeout);
|
||||
if (n == NGX_ERROR) {
|
||||
src->read->eof = 1;
|
||||
}
|
||||
}
|
||||
|
||||
} while (again);
|
||||
break;
|
||||
}
|
||||
|
||||
c->log->action = "proxying";
|
||||
|
||||
if ((s->connection->read->eof || s->proxy->upstream.connection->read->eof)
|
||||
&& s->buffer->pos == s->buffer->last
|
||||
&& s->proxy->buffer->pos == s->proxy->buffer->last)
|
||||
{
|
||||
action = c->log->action;
|
||||
c->log->action = NULL;
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done");
|
||||
c->log->action = action;
|
||||
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(dst->write, 0) == NGX_ERROR) {
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(dst->read, 0) == NGX_ERROR) {
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(src->write, 0) == NGX_ERROR) {
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) {
|
||||
ngx_imap_proxy_close_session(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == s->connection) {
|
||||
pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
|
||||
ngx_add_timer(c->read, pcf->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,6 +27,15 @@ static char ngx_imap_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_http_starttls_state[] = {
|
||||
{ ngx_string("off"), NGX_IMAP_STARTTLS_OFF },
|
||||
{ ngx_string("on"), NGX_IMAP_STARTTLS_ON },
|
||||
{ ngx_string("only"), NGX_IMAP_STARTTLS_ONLY },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static ngx_conf_bitmask_t ngx_imap_ssl_protocols[] = {
|
||||
{ ngx_string("SSLv2"), NGX_SSL_SSLv2 },
|
||||
{ ngx_string("SSLv3"), NGX_SSL_SSLv3 },
|
||||
@ -44,6 +53,13 @@ static ngx_command_t ngx_imap_ssl_commands[] = {
|
||||
offsetof(ngx_imap_ssl_conf_t, enable),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("starttls"),
|
||||
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_enum_slot,
|
||||
NGX_IMAP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_imap_ssl_conf_t, starttls),
|
||||
ngx_http_starttls_state },
|
||||
|
||||
{ ngx_string("ssl_certificate"),
|
||||
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
@ -146,6 +162,7 @@ ngx_imap_ssl_create_conf(ngx_conf_t *cf)
|
||||
*/
|
||||
|
||||
scf->enable = NGX_CONF_UNSET;
|
||||
scf->starttls = NGX_CONF_UNSET;
|
||||
scf->session_timeout = NGX_CONF_UNSET;
|
||||
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||
|
||||
@ -162,8 +179,9 @@ ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_pool_cleanup_t *cln;
|
||||
|
||||
ngx_conf_merge_value(conf->enable, prev->enable, 0);
|
||||
ngx_conf_merge_value(conf->starttls, prev->starttls, NGX_IMAP_STARTTLS_OFF);
|
||||
|
||||
if (conf->enable == 0) {
|
||||
if (conf->enable == 0 && conf->starttls == NGX_IMAP_STARTTLS_OFF) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,18 @@
|
||||
#include <ngx_imap.h>
|
||||
|
||||
|
||||
#define NGX_IMAP_STARTTLS_OFF 0
|
||||
#define NGX_IMAP_STARTTLS_ON 1
|
||||
#define NGX_IMAP_STARTTLS_ONLY 2
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_flag_t enable;
|
||||
|
||||
ngx_ssl_t ssl;
|
||||
|
||||
ngx_flag_t prefer_server_ciphers;
|
||||
ngx_flag_t starttls;
|
||||
|
||||
ngx_uint_t protocols;
|
||||
|
||||
|
@ -60,7 +60,7 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
|
||||
rev->available -= n;
|
||||
|
||||
/*
|
||||
* rev->available can be negative here because some additional
|
||||
* rev->available may be negative here because some additional
|
||||
* bytes can be received between kevent() and recv()
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user