Compare commits
164 commits
quic
...
stable-1.2
Author | SHA1 | Date | |
---|---|---|---|
|
c48f20f8e1 | ||
|
fd23ea994f | ||
|
f0a27ab36b | ||
|
a1c31e0478 | ||
|
59cd30a63c | ||
|
b2c279cbd3 | ||
|
8a93bc9885 | ||
|
f413543bd7 | ||
|
d8df7da54f | ||
|
2d197a9d39 | ||
|
76f856f25c | ||
|
d67e76612e | ||
|
335b5f73e7 | ||
|
f7b63912de | ||
|
ec0e4cae5f | ||
|
1a3988af90 | ||
|
b90ec1b1a2 | ||
|
f121aa193d | ||
|
50d44774c9 | ||
|
afd35712b2 | ||
|
8aa292d874 | ||
|
9b39f14093 | ||
|
d46e5d23bc | ||
|
2b5c4f50a5 | ||
|
58def725c3 | ||
|
c751f174f5 | ||
|
aaf45df542 | ||
|
f0ddd86389 | ||
|
5b114fb135 | ||
|
c03f5f6e9d | ||
|
52a3d34650 | ||
|
0672b092b5 | ||
|
471fb4c2bd | ||
|
328b544313 | ||
|
0a74b1021d | ||
|
7cc223cc54 | ||
|
203cbb1be3 | ||
|
7523ea7129 | ||
|
1b90454245 | ||
|
ff0b21baff | ||
|
b404c3bbbb | ||
|
a618295c0e | ||
|
f2d783ed9e | ||
|
b8a75f4268 | ||
|
91692bed55 | ||
|
6b356b1d1b | ||
|
aecf7f8171 | ||
|
18429a3d73 | ||
|
13351e7337 | ||
|
756bbd758d | ||
|
3fb9abaf6e | ||
|
1c191e08c3 | ||
|
6c09adb37b | ||
|
087012ee7e | ||
|
abebd71985 | ||
|
6c47f561ba | ||
|
089dd2f9ba | ||
|
3428ae9ab1 | ||
|
6bb2bf4cf6 | ||
|
572153c4a4 | ||
|
ae14505582 | ||
|
aa94ea5dea | ||
|
02615df1bb | ||
|
032c4f2425 | ||
|
4be8258166 | ||
|
8bf9560e56 | ||
|
e487de6fa9 | ||
|
071831dc3d | ||
|
e1fd544763 | ||
|
41b2b12346 | ||
|
5e727f5775 | ||
|
c6276b4150 | ||
|
a07ab9ad54 | ||
|
f4fd2d59a3 | ||
|
1c640c946f | ||
|
7988f4aca5 | ||
|
8541966db2 | ||
|
3cf301db77 | ||
|
3676939732 | ||
|
7965a30a78 | ||
|
ee1acd5389 | ||
|
3cc0fe30d8 | ||
|
8a90b57fc9 | ||
|
917a5c0a6f | ||
|
8831af3698 | ||
|
2b64e62233 | ||
|
8cc4f6248a | ||
|
6286f9c062 | ||
|
be844866bb | ||
|
e1e56351f1 | ||
|
38df2aa726 | ||
|
b22f4fb6f0 | ||
|
cc1bb6ebdf | ||
|
97047b74c5 | ||
|
ad80992b26 | ||
|
083596dbb0 | ||
|
05b8ccb52b | ||
|
17a5184e3a | ||
|
ffe8787e23 | ||
|
f20d1bae3f | ||
|
52df349abc | ||
|
5ff6b77a01 | ||
|
77dc045e9e | ||
|
af87c31654 | ||
|
726a071b0f | ||
|
201d0da810 | ||
|
d833679582 | ||
|
09e0f2a76e | ||
|
f03effbc47 | ||
|
26960680e4 | ||
|
9e518898de | ||
|
41e1ea0222 | ||
|
ff331a2988 | ||
|
f3d9aa2da4 | ||
|
9fff8c5dcb | ||
|
5fa264d72a | ||
|
e119c8f3cf | ||
|
73f3836c3c | ||
|
dbb1cff8cf | ||
|
a42b00b2a7 | ||
|
4cf4cdb56c | ||
|
d39b505182 | ||
|
cbdfd188c8 | ||
|
dc9d9c6cd3 | ||
|
083c85ab73 | ||
|
683fa7f420 | ||
|
9c9360a7b5 | ||
|
1e7eedc24f | ||
|
38f17f5d60 | ||
|
ac21ef1276 | ||
|
2523334c94 | ||
|
3bf1461a8f | ||
|
09b92ff5bb | ||
|
d1c053b9b8 | ||
|
a9cc91bacf | ||
|
5eb5790e06 | ||
|
7f911295fa | ||
|
8f1738a9df | ||
|
1dec0cfafb | ||
|
da29cd1feb | ||
|
747599d1f9 | ||
|
3356787783 | ||
|
fefcbf1738 | ||
|
541f213465 | ||
|
36a18fdd06 | ||
|
f01e1b9226 | ||
|
f8448034d4 | ||
|
e8b9c34064 | ||
|
da99f76591 | ||
|
5924995822 | ||
|
62b2d07640 | ||
|
2ae26f4d08 | ||
|
42a882727b | ||
|
e28d5925d1 | ||
|
27c1abba1a | ||
|
11d364307b | ||
|
8340edcb7e | ||
|
4e320f9b77 | ||
|
333be9fe57 | ||
|
75dbcedba1 | ||
|
65107cfd1c | ||
|
87b4323b47 | ||
|
0af9b00afa | ||
|
68e599aca7 |
145 changed files with 4965 additions and 1527 deletions
98
auto/cc/clang
Normal file
98
auto/cc/clang
Normal file
|
@ -0,0 +1,98 @@
|
|||
|
||||
# Copyright (C) Nginx, Inc.
|
||||
|
||||
|
||||
# clang
|
||||
|
||||
|
||||
NGX_CLANG_VER=`$CC -v 2>&1 | grep 'clang version' 2>&1 \
|
||||
| sed -e 's/^.*clang version \(.*\)/\1/'`
|
||||
|
||||
echo " + clang version: $NGX_CLANG_VER"
|
||||
|
||||
have=NGX_COMPILER value="\"clang $NGX_CLANG_VER\"" . auto/define
|
||||
|
||||
|
||||
CC_TEST_FLAGS="-pipe"
|
||||
|
||||
|
||||
# optimizations
|
||||
|
||||
#NGX_CLANG_OPT="-O2"
|
||||
#NGX_CLANG_OPT="-Oz"
|
||||
NGX_CLANG_OPT="-O"
|
||||
|
||||
case $CPU in
|
||||
pentium)
|
||||
# optimize for Pentium
|
||||
CPU_OPT="-march=pentium"
|
||||
NGX_CPU_CACHE_LINE=32
|
||||
;;
|
||||
|
||||
pentiumpro | pentium3)
|
||||
# optimize for Pentium Pro, Pentium II and Pentium III
|
||||
CPU_OPT="-march=pentiumpro"
|
||||
NGX_CPU_CACHE_LINE=32
|
||||
;;
|
||||
|
||||
pentium4)
|
||||
# optimize for Pentium 4
|
||||
CPU_OPT="-march=pentium4"
|
||||
NGX_CPU_CACHE_LINE=128
|
||||
;;
|
||||
|
||||
athlon)
|
||||
# optimize for Athlon
|
||||
CPU_OPT="-march=athlon"
|
||||
NGX_CPU_CACHE_LINE=64
|
||||
;;
|
||||
|
||||
opteron)
|
||||
# optimize for Opteron
|
||||
CPU_OPT="-march=opteron"
|
||||
NGX_CPU_CACHE_LINE=64
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT"
|
||||
|
||||
|
||||
CFLAGS="$CFLAGS -pipe $CPU_OPT"
|
||||
|
||||
if [ ".$PCRE_OPT" = "." ]; then
|
||||
PCRE_OPT="-O2 -pipe $CPU_OPT"
|
||||
else
|
||||
PCRE_OPT="$PCRE_OPT -pipe"
|
||||
fi
|
||||
|
||||
if [ ".$MD5_OPT" = "." ]; then
|
||||
MD5_OPT="-O2 -pipe $CPU_OPT"
|
||||
else
|
||||
MD5_OPT="$MD5_OPT -pipe"
|
||||
fi
|
||||
|
||||
if [ ".$ZLIB_OPT" = "." ]; then
|
||||
ZLIB_OPT="-O2 -pipe $CPU_OPT"
|
||||
else
|
||||
ZLIB_OPT="$ZLIB_OPT -pipe"
|
||||
fi
|
||||
|
||||
|
||||
# warnings
|
||||
|
||||
CFLAGS="$CFLAGS $NGX_CLANG_OPT -Wall -Wextra -Wpointer-arith"
|
||||
#CFLAGS="$CFLAGS -Wmissing-prototypes"
|
||||
|
||||
# we have a lot of unused function arguments
|
||||
CFLAGS="$CFLAGS -Wno-unused-parameter"
|
||||
|
||||
# stop on warning
|
||||
#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
|
||||
if [ ".$CPP" = "." ]; then
|
||||
CPP="$CC -E"
|
||||
fi
|
|
@ -56,6 +56,12 @@ else
|
|||
. auto/cc/gcc
|
||||
;;
|
||||
|
||||
clang)
|
||||
# Clang C compiler
|
||||
|
||||
. auto/cc/clang
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel C++ compiler 7.1, 8.0, 8.1
|
||||
|
||||
|
|
|
@ -149,15 +149,13 @@ CFLAGS="$CFLAGS ${NGX_GCC_OPT:--O} -W"
|
|||
CFLAGS="$CFLAGS -Wall -Wpointer-arith"
|
||||
#CFLAGS="$CFLAGS -Wconversion"
|
||||
#CFLAGS="$CFLAGS -Winline"
|
||||
#CFLAGS="$CFLAGS -Wmissing-prototypes"
|
||||
|
||||
|
||||
case "$NGX_GCC_VER" in
|
||||
3.* | 4.* )
|
||||
# we have a lot of the unused function arguments
|
||||
CFLAGS="$CFLAGS -Wno-unused-parameter"
|
||||
CFLAGS="$CFLAGS -Wunused-function"
|
||||
CFLAGS="$CFLAGS -Wunused-variable"
|
||||
CFLAGS="$CFLAGS -Wunused-value"
|
||||
# 4.2.1 shows the warning in wrong places
|
||||
#CFLAGS="$CFLAGS -Wunreachable-code"
|
||||
;;
|
||||
|
|
|
@ -73,9 +73,6 @@ CFLAGS="$CFLAGS -WX"
|
|||
# disable logo
|
||||
CFLAGS="$CFLAGS -nologo"
|
||||
|
||||
|
||||
LINK="\$(CC)"
|
||||
|
||||
# the link flags
|
||||
CORE_LINK="$CORE_LINK -link -verbose:lib"
|
||||
|
||||
|
|
40
auto/cc/name
40
auto/cc/name
|
@ -32,14 +32,14 @@ if [ "$CC" = cl ]; then
|
|||
NGX_CC_NAME=msvc10
|
||||
echo " + using Microsoft Visual C++ 10 compiler"
|
||||
|
||||
else if `$NGX_WINE $CC -v 2>&1 \
|
||||
elif `$NGX_WINE $CC -v 2>&1 \
|
||||
| grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14' \
|
||||
>/dev/null 2>&1`; then
|
||||
|
||||
NGX_CC_NAME=msvc8
|
||||
echo " + using Microsoft Visual C++ 8 compiler"
|
||||
|
||||
else if `$NGX_WINE $CC -v 2>&1 \
|
||||
elif `$NGX_WINE $CC -v 2>&1 \
|
||||
| grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13' \
|
||||
>/dev/null 2>&1`; then
|
||||
|
||||
|
@ -50,52 +50,40 @@ if [ "$CC" = cl ]; then
|
|||
NGX_CC_NAME=msvc
|
||||
echo " + using Microsoft Visual C++ compiler"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$CC" = wcl386 ]; then
|
||||
elif [ "$CC" = wcl386 ]; then
|
||||
NGX_CC_NAME=owc
|
||||
echo " + using Open Watcom C compiler"
|
||||
|
||||
else
|
||||
if [ "$CC" = bcc32 ]; then
|
||||
elif [ "$CC" = bcc32 ]; then
|
||||
NGX_CC_NAME=bcc
|
||||
echo " + using Borland C++ compiler"
|
||||
|
||||
else
|
||||
if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
|
||||
elif `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
|
||||
NGX_CC_NAME=icc
|
||||
echo " + using Intel C++ compiler"
|
||||
|
||||
else
|
||||
if `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
|
||||
elif `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
|
||||
NGX_CC_NAME=gcc
|
||||
echo " + using GNU C compiler"
|
||||
|
||||
else
|
||||
if `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
|
||||
elif `$CC -v 2>&1 | grep 'clang version' >/dev/null 2>&1`; then
|
||||
NGX_CC_NAME=clang
|
||||
echo " + using Clang C compiler"
|
||||
|
||||
elif `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
|
||||
NGX_CC_NAME=sunc
|
||||
echo " + using Sun C compiler"
|
||||
|
||||
else
|
||||
if `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
|
||||
elif `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
|
||||
NGX_CC_NAME=ccc
|
||||
echo " + using Compaq C compiler"
|
||||
|
||||
else
|
||||
if `$CC -V 2>&1 | grep '^aCC: ' >/dev/null 2>&1`; then
|
||||
elif `$CC -V 2>&1 | grep '^aCC: ' >/dev/null 2>&1`; then
|
||||
NGX_CC_NAME=acc
|
||||
echo " + using HP aC++ compiler"
|
||||
|
||||
else
|
||||
NGX_CC_NAME=unknown
|
||||
|
||||
fi # acc
|
||||
fi # ccc
|
||||
fi # sunc
|
||||
fi # icc
|
||||
fi # gcc
|
||||
fi # bcc
|
||||
fi # owc
|
||||
fi # msvc
|
||||
fi
|
||||
|
|
3
auto/configure
vendored
3
auto/configure
vendored
|
@ -4,6 +4,9 @@
|
|||
# Copyright (C) Nginx, Inc.
|
||||
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
. auto/options
|
||||
. auto/init
|
||||
. auto/sources
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# Copyright (C) Nginx, Inc.
|
||||
|
||||
|
||||
echo $ngx_n "checking for system endianess ...$ngx_c"
|
||||
echo $ngx_n "checking for system byte ordering ...$ngx_c"
|
||||
echo >> $NGX_ERR
|
||||
echo "checking for system endianess" >> $NGX_ERR
|
||||
echo "checking for system byte ordering" >> $NGX_ERR
|
||||
|
||||
|
||||
cat << END > $NGX_AUTOTEST.c
|
||||
|
@ -28,10 +28,10 @@ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
|
|||
|
||||
if [ -x $NGX_AUTOTEST ]; then
|
||||
if $NGX_AUTOTEST >/dev/null 2>&1; then
|
||||
echo " little endianess"
|
||||
echo " little endian"
|
||||
have=NGX_HAVE_LITTLE_ENDIAN . auto/have
|
||||
else
|
||||
echo " big endianess"
|
||||
echo " big endian"
|
||||
fi
|
||||
|
||||
rm $NGX_AUTOTEST*
|
||||
|
@ -40,6 +40,6 @@ else
|
|||
rm $NGX_AUTOTEST*
|
||||
|
||||
echo
|
||||
echo "$0: error: can not detect system endianess"
|
||||
echo "$0: error: cannot detect system byte ordering"
|
||||
exit 1
|
||||
fi
|
|
@ -8,7 +8,7 @@ if [ $USE_PERL = YES ]; then
|
|||
cat << END >> $NGX_MAKEFILE
|
||||
|
||||
install_perl_modules:
|
||||
cd $NGX_OBJS/src/http/modules/perl && make install
|
||||
cd $NGX_OBJS/src/http/modules/perl && \$(MAKE) install
|
||||
END
|
||||
|
||||
NGX_INSTALL_PERL_MODULES=install_perl_modules
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
ngx_feature="GeoIP library"
|
||||
ngx_feature_name=
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs=
|
||||
ngx_feature_incs="#include <GeoIP.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs="-lGeoIP"
|
||||
ngx_feature_test="GeoIP_open(NULL, 0)"
|
||||
|
@ -18,6 +18,7 @@ if [ $ngx_found = no ]; then
|
|||
# FreeBSD port
|
||||
|
||||
ngx_feature="GeoIP library in /usr/local/"
|
||||
ngx_feature_path="/usr/local/include"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
|
||||
|
@ -34,7 +35,7 @@ if [ $ngx_found = no ]; then
|
|||
# NetBSD port
|
||||
|
||||
ngx_feature="GeoIP library in /usr/pkg/"
|
||||
ngx_feature_path="/usr/pkg/include/"
|
||||
ngx_feature_path="/usr/pkg/include"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
|
||||
|
@ -64,8 +65,22 @@ fi
|
|||
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
|
||||
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||
|
||||
if [ $NGX_IPV6 = YES ]; then
|
||||
ngx_feature="GeoIP IPv6 support"
|
||||
ngx_feature_name="NGX_HAVE_GEOIP_V6"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <stdio.h>
|
||||
#include <GeoIP.h>"
|
||||
#ngx_feature_path=
|
||||
#ngx_feature_libs=
|
||||
ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
cat << END
|
||||
|
|
|
@ -29,6 +29,22 @@ if [ $ngx_found = no ]; then
|
|||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
# MacPorts
|
||||
|
||||
ngx_feature="Google perftools in /opt/local/"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lprofiler"
|
||||
else
|
||||
ngx_feature_libs="-L/opt/local/lib -lprofiler"
|
||||
fi
|
||||
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
cat << END >> $NGX_MAKEFILE
|
||||
|
||||
$NGX_LIBATOMIC/src/libatomic_ops.a: $NGX_LIBATOMIC/Makefile
|
||||
cd $NGX_LIBATOMIC && make
|
||||
cd $NGX_LIBATOMIC && \$(MAKE)
|
||||
|
||||
$NGX_LIBATOMIC/Makefile: $NGX_MAKEFILE
|
||||
cd $NGX_LIBATOMIC && ./configure
|
||||
|
|
|
@ -35,7 +35,7 @@ if [ $ngx_found = no ]; then
|
|||
# NetBSD port
|
||||
|
||||
ngx_feature="GD library in /usr/pkg/"
|
||||
ngx_feature_path="/usr/pkg/include/"
|
||||
ngx_feature_path="/usr/pkg/include"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd"
|
||||
|
|
|
@ -172,6 +172,7 @@ else
|
|||
ngx_feature="PCRE JIT support"
|
||||
ngx_feature_name="NGX_HAVE_PCRE_JIT"
|
||||
ngx_feature_test="int jit = 0;
|
||||
pcre_free_study(NULL);
|
||||
pcre_config(PCRE_CONFIG_JIT, &jit);
|
||||
if (jit != 1) return 1;"
|
||||
. auto/feature
|
||||
|
|
|
@ -12,7 +12,7 @@ NGX_PERL_VER=`$NGX_PERL -v 2>&1 | grep '^This is perl' 2>&1 \
|
|||
if test -n "$NGX_PERL_VER"; then
|
||||
echo " + perl version: $NGX_PERL_VER"
|
||||
|
||||
if [ "`echo 'use 5.006001; print "OK"' | $NGX_PERL 2>&1`" != OK ]; then
|
||||
if [ "`$NGX_PERL -e 'use 5.006001; print "OK"'`" != "OK" ]; then
|
||||
echo
|
||||
echo "$0: error: perl 5.6.1 or higher is required"
|
||||
echo
|
||||
|
@ -20,6 +20,14 @@ if test -n "$NGX_PERL_VER"; then
|
|||
exit 1;
|
||||
fi
|
||||
|
||||
if [ "`$NGX_PERL -MExtUtils::Embed -e 'print "OK"'`" != "OK" ]; then
|
||||
echo
|
||||
echo "$0: error: perl module ExtUtils::Embed is required"
|
||||
echo
|
||||
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
NGX_PERL_CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`"
|
||||
NGX_PM_CFLAGS=`$NGX_PERL -MExtUtils::Embed -e ccopts`
|
||||
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
cat << END >> $NGX_MAKEFILE
|
||||
|
||||
$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.so: \
|
||||
\$(CORE_DEPS) \$(HTTP_DEPS) \
|
||||
src/http/modules/perl/nginx.pm \
|
||||
src/http/modules/perl/nginx.xs \
|
||||
src/http/modules/perl/ngx_http_perl_module.h \
|
||||
$NGX_OBJS/src/http/modules/perl/Makefile
|
||||
cp -p src/http/modules/perl/nginx.* $NGX_OBJS/src/http/modules/perl/
|
||||
cp src/http/modules/perl/nginx.* $NGX_OBJS/src/http/modules/perl/
|
||||
|
||||
cd $NGX_OBJS/src/http/modules/perl && make
|
||||
cd $NGX_OBJS/src/http/modules/perl && \$(MAKE)
|
||||
|
||||
rm -rf $NGX_OBJS/install_perl
|
||||
|
||||
|
@ -26,9 +27,7 @@ $NGX_OBJS/src/http/modules/perl/Makefile: \
|
|||
|
||||
cd $NGX_OBJS/src/http/modules/perl \
|
||||
&& NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \
|
||||
NGX_PCRE=$PCRE \
|
||||
NGX_OBJS=$NGX_OBJS \
|
||||
NGX_OPENSSL=$OPENSSL \
|
||||
NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \
|
||||
$NGX_PERL Makefile.PL \
|
||||
LIB=$NGX_PERL_MODULES \
|
||||
INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
|
||||
|
|
|
@ -9,11 +9,13 @@ if [ $ZLIB != NONE ]; then
|
|||
case "$NGX_CC_NAME" in
|
||||
|
||||
msvc* | owc* | bcc)
|
||||
have=NGX_ZLIB . auto/have
|
||||
LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib"
|
||||
CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib"
|
||||
;;
|
||||
|
||||
icc*)
|
||||
have=NGX_ZLIB . auto/have
|
||||
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
|
||||
|
||||
# to allow -ipo optimization we link with the *.o but not library
|
||||
|
@ -30,6 +32,7 @@ if [ $ZLIB != NONE ]; then
|
|||
;;
|
||||
|
||||
*)
|
||||
have=NGX_ZLIB . auto/have
|
||||
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
|
||||
CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
|
||||
#CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
|
||||
|
@ -45,7 +48,7 @@ else
|
|||
# FreeBSD, Solaris, Linux
|
||||
|
||||
ngx_feature="zlib library"
|
||||
ngx_feature_name=
|
||||
ngx_feature_name="NGX_ZLIB"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <zlib.h>"
|
||||
ngx_feature_path=
|
||||
|
|
|
@ -8,8 +8,10 @@ CFLAGS = -q -O2 -tWM -w-8004 -w-8012 $(CPU_OPT)
|
|||
zlib.lib:
|
||||
cd $(ZLIB)
|
||||
|
||||
bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c \
|
||||
compress.c
|
||||
bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c \
|
||||
trees.c zutil.c compress.c \
|
||||
inflate.c inffast.c inftrees.c
|
||||
|
||||
tlib zlib.lib +adler32.obj +crc32.obj +deflate.obj \
|
||||
+trees.obj +zutil.obj +compress.obj
|
||||
+trees.obj +zutil.obj +compress.obj \
|
||||
+inflate.obj +inffast.obj +inftrees.obj
|
||||
|
|
|
@ -8,7 +8,10 @@ CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT)
|
|||
zlib.lib:
|
||||
cd $(ZLIB)
|
||||
|
||||
cl -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c compress.c
|
||||
cl -c $(CFLAGS) adler32.c crc32.c deflate.c \
|
||||
trees.c zutil.c compress.c \
|
||||
inflate.c inffast.c inftrees.c
|
||||
|
||||
link -lib -out:zlib.lib adler32.obj crc32.obj deflate.obj \
|
||||
trees.obj zutil.obj compress.obj
|
||||
trees.obj zutil.obj compress.obj \
|
||||
inflate.obj inffast.obj inftrees.obj
|
||||
|
|
|
@ -9,6 +9,6 @@ zlib.lib:
|
|||
cd $(ZLIB)
|
||||
|
||||
wcl386 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c &
|
||||
compress.c
|
||||
compress.c inflate.c inffast.c inftrees.c
|
||||
wlib -n zlib.lib adler32.obj crc32.obj deflate.obj trees.obj &
|
||||
zutil.obj compress.obj
|
||||
zutil.obj compress.obj inflate.obj inffast.obj inftrees.obj
|
||||
|
|
|
@ -49,7 +49,7 @@ END
|
|||
ngx_all_srcs="$CORE_SRCS"
|
||||
|
||||
|
||||
# the core dependences and include pathes
|
||||
# the core dependences and include paths
|
||||
|
||||
ngx_deps=`echo $CORE_DEPS $NGX_AUTO_CONFIG_H $NGX_PCH \
|
||||
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
|
||||
|
@ -69,7 +69,7 @@ CORE_INCS = $ngx_include_opt$ngx_incs
|
|||
END
|
||||
|
||||
|
||||
# the http dependences and include pathes
|
||||
# the http dependences and include paths
|
||||
|
||||
if [ $HTTP = YES ]; then
|
||||
|
||||
|
@ -95,7 +95,7 @@ END
|
|||
fi
|
||||
|
||||
|
||||
# the mail dependences and include pathes
|
||||
# the mail dependences and include paths
|
||||
|
||||
if [ $MAIL = YES ]; then
|
||||
|
||||
|
|
10
auto/modules
10
auto/modules
|
@ -223,6 +223,7 @@ fi
|
|||
|
||||
if [ $HTTP_REALIP = YES ]; then
|
||||
have=NGX_HTTP_REALIP . auto/have
|
||||
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_REALIP_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_REALIP_SRCS"
|
||||
fi
|
||||
|
@ -234,11 +235,13 @@ fi
|
|||
|
||||
if [ $HTTP_GEO = YES ]; then
|
||||
have=NGX_HTTP_GEO . auto/have
|
||||
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_GEO_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_GEOIP = YES ]; then
|
||||
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_GEOIP_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS"
|
||||
fi
|
||||
|
@ -274,6 +277,7 @@ fi
|
|||
|
||||
if [ $HTTP_PROXY = YES ]; then
|
||||
have=NGX_HTTP_PROXY . auto/have
|
||||
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
|
||||
#USE_MD5=YES
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE"
|
||||
HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS"
|
||||
|
@ -345,6 +349,11 @@ if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
|
|||
HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_LEAST_CONN_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_LEAST_CONN_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_KEEPALIVE_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS"
|
||||
|
@ -458,6 +467,7 @@ fi
|
|||
|
||||
if [ $NGX_CPP_TEST = YES ]; then
|
||||
NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_CPP_TEST_SRCS"
|
||||
CORE_LIBS="$CORE_LIBS -lstdc++"
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ HTTP_FLV=NO
|
|||
HTTP_MP4=NO
|
||||
HTTP_GZIP_STATIC=NO
|
||||
HTTP_UPSTREAM_IP_HASH=YES
|
||||
HTTP_UPSTREAM_LEAST_CONN=YES
|
||||
HTTP_UPSTREAM_KEEPALIVE=YES
|
||||
|
||||
# STUB
|
||||
|
@ -243,6 +244,8 @@ use the \"--without-http_limit_conn_module\" option instead"
|
|||
--without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;;
|
||||
--without-http_browser_module) HTTP_BROWSER=NO ;;
|
||||
--without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;;
|
||||
--without-http_upstream_least_conn_module)
|
||||
HTTP_UPSTREAM_LEAST_CONN=NO ;;
|
||||
--without-http_upstream_keepalive_module) HTTP_UPSTREAM_KEEPALIVE=NO ;;
|
||||
|
||||
--with-http_perl_module) HTTP_PERL=YES ;;
|
||||
|
@ -382,6 +385,10 @@ cat << END
|
|||
--without-http_browser_module disable ngx_http_browser_module
|
||||
--without-http_upstream_ip_hash_module
|
||||
disable ngx_http_upstream_ip_hash_module
|
||||
--without-http_upstream_least_conn_module
|
||||
disable ngx_http_upstream_least_conn_module
|
||||
--without-http_upstream_keepalive_module
|
||||
disable ngx_http_upstream_keepalive_module
|
||||
|
||||
--with-http_perl_module enable ngx_http_perl_module
|
||||
--with-perl_modules_path=PATH set Perl modules path
|
||||
|
|
|
@ -48,6 +48,7 @@ case "$NGX_PLATFORM" in
|
|||
CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
|
||||
CORE_SRCS="$UNIX_SRCS"
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS -D_HPUX_ALT_XOPEN_SOCKET_API"
|
||||
;;
|
||||
|
||||
OSF1:*)
|
||||
|
@ -93,6 +94,7 @@ case "$NGX_MACHINE" in
|
|||
;;
|
||||
|
||||
*)
|
||||
have=NGX_ALIGNMENT value=16 . auto/define
|
||||
NGX_MACH_CACHE_LINE=32
|
||||
;;
|
||||
|
||||
|
|
|
@ -479,6 +479,11 @@ HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module
|
|||
HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c
|
||||
|
||||
|
||||
HTTP_UPSTREAM_LEAST_CONN_MODULE=ngx_http_upstream_least_conn_module
|
||||
HTTP_UPSTREAM_LEAST_CONN_SRCS=" \
|
||||
src/http/modules/ngx_http_upstream_least_conn_module.c"
|
||||
|
||||
|
||||
HTTP_UPSTREAM_KEEPALIVE_MODULE=ngx_http_upstream_keepalive_module
|
||||
HTTP_UPSTREAM_KEEPALIVE_SRCS=" \
|
||||
src/http/modules/ngx_http_upstream_keepalive_module.c"
|
||||
|
|
|
@ -464,7 +464,7 @@ ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
|
|||
|
||||
. auto/types/uintptr_t
|
||||
|
||||
. auto/endianess
|
||||
. auto/endianness
|
||||
|
||||
ngx_type="size_t"; . auto/types/sizeof
|
||||
ngx_param=NGX_MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
|
||||
|
|
|
@ -5,24 +5,6 @@ NGINX= nginx-$(VER)
|
|||
TEMP= tmp
|
||||
CP= $(HOME)/java
|
||||
|
||||
define XSLScript
|
||||
java -cp $(CP)/xsls/saxon.jar:$(CP)/xsls/xsls.jar \
|
||||
com.pault.StyleSheet \
|
||||
-x com.pault.XX -y com.pault.XX \
|
||||
$(1) docs/xsls/dump.xsls \
|
||||
| sed 's/ *$$//;/^ *$$/N;/\n *$$/D' > $(2)
|
||||
|
||||
if [ ! -s $(2) ]; then rm $(2); fi; test -s $(2)
|
||||
endef
|
||||
|
||||
define XSLT
|
||||
xmllint --noout --valid $2
|
||||
xsltproc -o $3 \
|
||||
$(shell echo $4 \\
|
||||
| sed -e "s/\([^= ]*\)=\([^= ]*\)/--param \1 \"'\2'\"/g") \
|
||||
$1 $2
|
||||
endef
|
||||
|
||||
|
||||
all: changes
|
||||
|
||||
|
@ -30,28 +12,36 @@ changes: $(TEMP)/$(NGINX)/CHANGES.ru \
|
|||
$(TEMP)/$(NGINX)/CHANGES
|
||||
|
||||
|
||||
$(TEMP)/$(NGINX)/CHANGES.ru: docs/xml/nginx/changes.xml \
|
||||
$(TEMP)/$(NGINX)/CHANGES.ru: docs/dtd/changes.dtd \
|
||||
docs/xml/nginx/changes.xml \
|
||||
docs/xml/change_log_conf.xml \
|
||||
docs/xslt/changes.xslt
|
||||
|
||||
test -d $(TEMP)/$(NGINX) || mkdir -p $(TEMP)/$(NGINX)
|
||||
mkdir -p $(TEMP)/$(NGINX)
|
||||
|
||||
xmllint --noout --valid docs/xml/nginx/changes.xml
|
||||
xsltproc --stringparam lang ru \
|
||||
-o $(TEMP)/$(NGINX)/CHANGES.ru \
|
||||
docs/xslt/changes.xslt docs/xml/nginx/changes.xml
|
||||
-o $@ docs/xslt/changes.xslt docs/xml/nginx/changes.xml
|
||||
|
||||
|
||||
$(TEMP)/$(NGINX)/CHANGES: docs/xml/nginx/changes.xml \
|
||||
$(TEMP)/$(NGINX)/CHANGES: docs/dtd/changes.dtd \
|
||||
docs/xml/nginx/changes.xml \
|
||||
docs/xml/change_log_conf.xml \
|
||||
docs/xslt/changes.xslt
|
||||
|
||||
test -d $(TEMP)/$(NGINX) || mkdir -p $(TEMP)/$(NGINX)
|
||||
mkdir -p $(TEMP)/$(NGINX)
|
||||
|
||||
xmllint --noout --valid docs/xml/nginx/changes.xml
|
||||
xsltproc --stringparam lang en \
|
||||
-o $(TEMP)/$(NGINX)/CHANGES \
|
||||
docs/xslt/changes.xslt docs/xml/nginx/changes.xml
|
||||
-o $@ docs/xslt/changes.xslt docs/xml/nginx/changes.xml
|
||||
|
||||
|
||||
docs/xslt/changes.xslt: docs/xsls/changes.xsls
|
||||
docs/xslt/changes.xslt: docs/xsls/changes.xsls docs/xsls/dump.xsls
|
||||
|
||||
$(call XSLScript, docs/xsls/changes.xsls, $@)
|
||||
java -cp $(CP)/xsls/saxon.jar:$(CP)/xsls/xsls.jar \
|
||||
com.pault.StyleSheet \
|
||||
-x com.pault.XX -y com.pault.XX \
|
||||
$< docs/xsls/dump.xsls \
|
||||
| sed 's/ *$$//;/^ *$$/N;/\n *$$/D' > $@
|
||||
|
||||
if [ ! -s $@ ]; then rm $@; fi; test -s $@
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
>
|
||||
|
||||
<!ELEMENT change (para)* >
|
||||
<!ATTLIST change type (bugfix | feature | change | workaround) #IMPLIED >
|
||||
<!ATTLIST change type (bugfix | feature | change | security | workaround) #IMPLIED >
|
||||
|
||||
<!ELEMENT para (#PCDATA | at | br | nobr)* >
|
||||
<!ATTLIST para lang (ru | en) #IMPLIED >
|
||||
<!ATTLIST para lang (ru | en) #REQUIRED >
|
||||
|
||||
<!ELEMENT at EMPTY >
|
||||
<!ELEMENT br EMPTY >
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>The page is temporarily unavailable</title>
|
||||
<title>Error</title>
|
||||
<style>
|
||||
body { font-family: Tahoma, Verdana, Arial, sans-serif; }
|
||||
body {
|
||||
width: 35em;
|
||||
margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="white" text="black">
|
||||
<table width="100%" height="100%">
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
The page you are looking for is temporarily unavailable.<br/>
|
||||
Please try again later.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<body>
|
||||
<h1>An error occurred.</h1>
|
||||
<p>Sorry, the page you are looking for is currently unavailable.<br/>
|
||||
Please try again later.</p>
|
||||
<p>If you are the system administrator of this resource then you should check
|
||||
the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
|
||||
<p><em>Faithfully yours, nginx.</em></p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to nginx!</title>
|
||||
<style>
|
||||
body {
|
||||
width: 35em;
|
||||
margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="white" text="black">
|
||||
<center><h1>Welcome to nginx!</h1></center>
|
||||
<body>
|
||||
<h1>Welcome to nginx!</h1>
|
||||
<p>If you see this page, the nginx web server is successfully installed and
|
||||
working. Further configuration is required.</p>
|
||||
|
||||
<p>For online documentation and support please refer to
|
||||
<a href="http://nginx.org/">nginx.org</a>.<br/>
|
||||
Commercial support is available at
|
||||
<a href="http://nginx.com/">nginx.com</a>.</p>
|
||||
|
||||
<p><em>Thank you for using nginx.</em></p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\"
|
||||
.\" Copyright (c) 2010 Sergey A. Osokin
|
||||
.\" Copyright (c) 2011,2012 Nginx, Inc.
|
||||
.\" Copyright (C) 2010 Sergey A. Osokin
|
||||
.\" Copyright (C) Nginx, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2012 Igor Sysoev
|
||||
* Copyright (C) 2011,2012 Nginx, Inc.
|
||||
* Copyright (C) 2002-2013 Igor Sysoev
|
||||
* Copyright (C) 2011-2013 Nginx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -11,10 +12,10 @@
|
|||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
|
|
|
@ -2,11 +2,965 @@
|
|||
<!DOCTYPE change_log SYSTEM "../../dtd/changes.dtd" >
|
||||
|
||||
|
||||
<change_log link="/nginx/changes.html" path="/nginx/" root=".."
|
||||
title="nginx">
|
||||
<change_log title="nginx">
|
||||
|
||||
<title lang="ru">Изменения в nginx</title>
|
||||
<title lang="en">nginx changelog</title>
|
||||
|
||||
<changes ver="1.2.9" date="13.05.2013">
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
содержимое памяти рабочего процесса могло быть отправлено клиенту,
|
||||
если HTTP-бэкенд возвращал специально созданный ответ (CVE-2013-2070);
|
||||
ошибка появилась в 1.1.4.
|
||||
</para>
|
||||
<para lang="en">
|
||||
contents of worker process memory might be sent to a client
|
||||
if HTTP backend returned specially crafted response (CVE-2013-2070);
|
||||
the bug had appeared in 1.1.4.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.8" date="02.04.2013">
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании директивы "ssl_session_cache shared"
|
||||
новые сессии могли не сохраняться,
|
||||
если заканчивалось место в разделяемой памяти.<br/>
|
||||
Спасибо Piotr Sikora.
|
||||
</para>
|
||||
<para lang="en">
|
||||
new sessions were not always stored
|
||||
if the "ssl_session_cache shared" directive was used
|
||||
and there was no free space in shared memory.<br/>
|
||||
Thanks to Piotr Sikora.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ответы могли зависать,
|
||||
если использовались подзапросы
|
||||
и при обработке подзапроса происходила DNS-ошибка.<br/>
|
||||
Спасибо Lanshun Zhou.
|
||||
</para>
|
||||
<para lang="en">
|
||||
responses might hang
|
||||
if subrequests were used
|
||||
and a DNS error happened during subrequest processing.<br/>
|
||||
Thanks to Lanshun Zhou.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в модуле ngx_http_mp4_module.<br/>
|
||||
Спасибо Gernot Vormayr.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the ngx_http_mp4_module.<br/>
|
||||
Thanks to Gernot Vormayr.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в процедуре учёта использования бэкендов.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in backend usage accounting.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.7" date="12.02.2013">
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
теперь при использовании директивы include с маской на Unix-системах
|
||||
включаемые файлы сортируются в алфавитном порядке.
|
||||
</para>
|
||||
<para lang="en">
|
||||
now if the "include" directive with mask is used on Unix systems,
|
||||
included files are sorted in alphabetical order.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
директива add_header добавляет строки в ответы с кодом 201.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "add_header" directive adds headers to 201 responses.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директива geo теперь поддерживает IPv6 адреса в формате CIDR.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "geo" directive now supports IPv6 addresses in CIDR notation.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
параметры flush и gzip в директиве access_log.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "flush" and "gzip" parameters of the "access_log" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директива auth_basic поддерживает переменные.
|
||||
</para>
|
||||
<para lang="en">
|
||||
variables support in the "auth_basic" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
переменные $pipe, $request_length, $time_iso8601 и $time_local
|
||||
теперь можно использовать не только в директиве log_format.<br/>
|
||||
Спасибо Kiril Kalchev.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the $pipe, $request_length, $time_iso8601, and $time_local variables
|
||||
can now be used not only in the "log_format" directive.
|
||||
Thanks to Kiril Kalchev.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
поддержка IPv6 в модуле ngx_http_geoip_module.<br/>
|
||||
Спасибо Gregor Kališnik.
|
||||
</para>
|
||||
<para lang="en">
|
||||
IPv6 support in the ngx_http_geoip_module.<br/>
|
||||
Thanks to Gregor Kališnik.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx в некоторых случаях не собирался с модулем ngx_http_perl_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx could not be built with the ngx_http_perl_module in some cases.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовался модуль ngx_http_xslt_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the ngx_http_xslt_module was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx мог не собираться на MacOSX.<br/>
|
||||
Спасибо Piotr Sikora.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx could not be built on MacOSX in some cases.<br/>
|
||||
Thanks to Piotr Sikora.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании директивы limit_rate с большими значениями скорости
|
||||
на 32-битных системах ответ мог возвращаться не целиком.<br/>
|
||||
Спасибо Алексею Антропову.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "limit_rate" directive with high rates
|
||||
might result in truncated responses on 32-bit platforms.<br/>
|
||||
Thanks to Alexey Antropov.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовалась директива if.<br/>
|
||||
Спасибо Piotr Sikora.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "if" directive was used.<br/>
|
||||
Thanks to Piotr Sikora.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ответ "100 Continue" выдавался
|
||||
вместе с ответом "413 Request Entity Too Large".
|
||||
</para>
|
||||
<para lang="en">
|
||||
a "100 Continue" response was issued
|
||||
with "413 Request Entity Too Large" responses.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
директивы image_filter, image_filter_jpeg_quality и image_filter_sharpen
|
||||
могли наследоваться некорректно.<br/>
|
||||
Спасибо Ивану Боброву.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "image_filter", "image_filter_jpeg_quality"
|
||||
and "image_filter_sharpen" directives
|
||||
might be inherited incorrectly.<br/>
|
||||
Thanks to Ian Babrou.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании директивы auth_basic под Linux
|
||||
могли возникать ошибки "crypt_r() failed".
|
||||
</para>
|
||||
<para lang="en">
|
||||
"crypt_r() failed" errors might appear
|
||||
if the "auth_basic" directive was used on Linux.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в обработке backup-серверов.<br/>
|
||||
Спасибо Thomas Chen.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in backup servers handling.<br/>
|
||||
Thanks to Thomas Chen.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при проксировании HEAD-запросов мог возвращаться некорректный ответ,
|
||||
если использовалась директива gzip.
|
||||
</para>
|
||||
<para lang="en">
|
||||
proxied HEAD requests might return incorrect response
|
||||
if the "gzip" directive was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
на старте или во время переконфигурации происходил segmentation fault,
|
||||
если директива keepalive была указана несколько раз
|
||||
в одном блоке upstream.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault occurred on start or during reconfiguration
|
||||
if the "keepalive" directive was specified more than once
|
||||
in a single upstream block.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
директива proxy_method работала неверно, если была указана на уровне http.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the "proxy_method" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовался resolver и метод poll.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if resolver was used with the poll method.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx мог нагружать процессор во время SSL handshake с бэкендом
|
||||
при использовании методов обработки соединений select, poll и /dev/poll.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx might hog CPU during SSL handshake with a backend
|
||||
if the select, poll, or /dev/poll methods were used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ошибка "[crit] SSL_write() failed (SSL:)".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "[crit] SSL_write() failed (SSL:)" error.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в директиве fastcgi_keep_conn.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the "fastcgi_keep_conn" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.6" date="11.12.2012">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
переменные $request_time и $msec
|
||||
теперь можно использовать не только в директиве log_format.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the $request_time and $msec variables
|
||||
can now be used not only in the "log_format" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
cache manager и cache loader могли не запускаться,
|
||||
если использовалось более 512 listen-сокетов.
|
||||
</para>
|
||||
<para lang="en">
|
||||
cache manager and cache loader processes might not be able to start
|
||||
if more than 512 listen sockets were used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в модуле ngx_http_dav_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the ngx_http_dav_module.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.5" date="13.11.2012">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
параметр optional_no_ca директивы ssl_verify_client.<br/>
|
||||
Спасибо Михаилу Казанцеву и Eric O'Connor.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "optional_no_ca" parameter of the "ssl_verify_client" directive.<br/>
|
||||
Thanks to Mike Kazantsev and Eric O'Connor.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
переменные $bytes_sent, $connection и $connection_requests
|
||||
теперь можно использовать не только в директиве log_format.<br/>
|
||||
Спасибо Benjamin Grössing.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the $bytes_sent, $connection, and $connection_requests variables
|
||||
can now be used not only in the "log_format" directive.<br/>
|
||||
Thanks to Benjamin Grössing.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
теперь resolver случайным образом меняет порядок
|
||||
возвращаемых закэшированных адресов.<br/>
|
||||
Спасибо Антону Жулину.
|
||||
</para>
|
||||
<para lang="en">
|
||||
resolver now randomly rotates addresses
|
||||
returned from cache.<br/>
|
||||
Thanks to Anton Jouline.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
параметр auto директивы worker_processes.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "auto" parameter of the "worker_processes" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
сообщения "cache file ... has md5 collision".
|
||||
</para>
|
||||
<para lang="en">
|
||||
"cache file ... has md5 collision" alert.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
совместимость с OpenSSL 0.9.7.
|
||||
</para>
|
||||
<para lang="en">
|
||||
OpenSSL 0.9.7 compatibility.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.4" date="25.09.2012">
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в директиве "limit_req";
|
||||
ошибка появилась в 1.1.14.<br/>
|
||||
Спасибо Charles Chen.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the "limit_req" directive;
|
||||
the bug had appeared in 1.1.14.<br/>
|
||||
Thanks to Charles Chen.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx не собирался gcc 4.7 с оптимизацией -O2
|
||||
если использовался параметр --with-ipv6.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx could not be built by gcc 4.7 with -O2 optimization
|
||||
if the --with-ipv6 option was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если в директиве map в качестве значений использовались переменные.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "map" directive was used with variables as values.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault
|
||||
при использовании директивы geo с параметром ranges,
|
||||
но без параметра default; ошибка появилась в 0.8.43.<br/>
|
||||
Спасибо Zhen Chen и Weibin Yao.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "geo" directive was used with the "ranges" parameter
|
||||
but without the "default" parameter; the bug had appeared in 0.8.43.<br/>
|
||||
Thanks to Zhen Chen and Weibin Yao.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в обработке параметра командной строки -p.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the -p command-line parameter handling.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в почтовом прокси-сервере.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the mail proxy server.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
незначительных потенциальных ошибок.<br/>
|
||||
Спасибо Coverity.
|
||||
</para>
|
||||
<para lang="en">
|
||||
of minor potential bugs.<br/>
|
||||
Thanks to Coverity.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx/Windows не собирался с Visual Studio 2005 Express.<br/>
|
||||
Спасибо HAYASHI Kentaro.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx/Windows could not be built with Visual Studio 2005 Express.<br/>
|
||||
Thanks to HAYASHI Kentaro.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.3" date="07.08.2012">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
поддержка компилятора Clang.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the Clang compiler support.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
могли создаваться лишние слушающие сокеты.<br/>
|
||||
Спасибо Роману Одайскому.
|
||||
</para>
|
||||
<para lang="en">
|
||||
extra listening sockets might be created.<br/>
|
||||
Thanks to Roman Odaisky.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx/Windows мог нагружать процессор, если при запуске рабочего процесса
|
||||
происходила ошибка.<br/>
|
||||
Спасибо Ricardo Villalobos Guevara.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx/Windows might hog CPU if a worker process failed to start.<br/>
|
||||
Thanks to Ricardo Villalobos Guevara.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
директивы proxy_pass_header, fastcgi_pass_header, scgi_pass_header,
|
||||
uwsgi_pass_header, proxy_hide_header, fastcgi_hide_header,
|
||||
scgi_hide_header и uwsgi_hide_header
|
||||
могли наследоваться некорректно.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_pass_header", "fastcgi_pass_header", "scgi_pass_header",
|
||||
"uwsgi_pass_header", "proxy_hide_header", "fastcgi_hide_header",
|
||||
"scgi_hide_header", and "uwsgi_hide_header" directives
|
||||
might be inherited incorrectly.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании директивы map с параметром hostnames
|
||||
не игнорировалась конечная точка в исходном значении.
|
||||
</para>
|
||||
<para lang="en">
|
||||
trailing dot in a source value was not ignored
|
||||
if the "map" directive was used with the "hostnames" parameter.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
для обработки запроса мог использоваться неверный location,
|
||||
если переход в именованный location происходил
|
||||
после изменения URI с помощью директивы rewrite.
|
||||
</para>
|
||||
<para lang="en">
|
||||
incorrect location might be used to process a request
|
||||
if a URI was changed via a "rewrite" directive
|
||||
before an internal redirect to a named location.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.2" date="03.07.2012">
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
параметр single директивы keepalive теперь игнорируется.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "single" parameter of the "keepalive" directive is now ignored.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
сжатие SSL теперь отключено
|
||||
в том числе при использовании OpenSSL cтарее 1.0.0.
|
||||
</para>
|
||||
<para lang="en">
|
||||
SSL compression is now disabled when using all versions of OpenSSL,
|
||||
including ones prior to 1.0.0.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директивы proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass и
|
||||
директива server в блоке upstream
|
||||
теперь поддерживают IPv6-адреса.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_pass", "fastcgi_pass", "scgi_pass", "uwsgi_pass" directives, and
|
||||
the "server" directive inside the "upstream" block,
|
||||
now support IPv6 addresses.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
в директиве resolver теперь можно указывать порт и
|
||||
задавать IPv6-адреса DNS-серверов.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "resolver" directive now supports IPv6 addresses and
|
||||
an optional port specification.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директива least_conn в блоке upstream.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "least_conn" directive inside the "upstream" block.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
при использовании директивы ip_hash
|
||||
теперь можно задавать веса серверов.
|
||||
</para>
|
||||
<para lang="en">
|
||||
it is now possible to specify a weight for servers
|
||||
while using the "ip_hash" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директиву "ip_hash" теперь можно использовать для балансировки IPv6 клиентов.
|
||||
</para>
|
||||
<para lang="en">
|
||||
it is now possible to use the "ip_hash" directive to balance IPv6 clients.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
переменную $status теперь можно использовать не только в директиве log_format.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the $status variable can now be used not only in the "log_format" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx не собирался с модулем ngx_cpp_test_module;
|
||||
ошибка появилась в 1.1.12.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx could not be built with ngx_cpp_test_module;
|
||||
the bug had appeared in 1.1.12.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
доступ к переменным из SSI и встроенного перла мог не работать после
|
||||
переконфигурации.<br/>
|
||||
Спасибо Yichun Zhang.
|
||||
</para>
|
||||
<para lang="en">
|
||||
access to variables from SSI and embedded perl module might not work after
|
||||
reconfiguration.<br/>
|
||||
Thanks to Yichun Zhang.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в модуле ngx_http_xslt_filter_module.<br/>
|
||||
Спасибо Kuramoto Eiji.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the ngx_http_xslt_filter_module.<br/>
|
||||
Thanks to Kuramoto Eiji.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
утечки памяти при использовании переменной $geoip_org.<br/>
|
||||
Спасибо Денису Латыпову.
|
||||
</para>
|
||||
<para lang="en">
|
||||
memory leak if $geoip_org variable was used.<br/>
|
||||
Thanks to Denis F. Latypoff.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в директивах proxy_cookie_domain и proxy_cookie_path.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the "proxy_cookie_domain" and "proxy_cookie_path" directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при завершении рабочего процесса мог произойти segmentation fault,
|
||||
если использовалась директива resolver.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process on shutdown
|
||||
if the "resolver" directive was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовался модуль ngx_http_mp4_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the ngx_http_mp4_module was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в модуле ngx_http_mp4_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the ngx_http_mp4_module.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовались конфликтующие имена серверов с масками.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if conflicting wildcard server names were used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
на платформе ARM nginx мог аварийно завершаться по сигналу SIGBUS.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx might be terminated abnormally on a SIGBUS signal on ARM platform.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
во время переконфигурации на HP-UX в лог
|
||||
записывался alert "sendmsg() failed (9: Bad file number)".
|
||||
</para>
|
||||
<para lang="en">
|
||||
an alert "sendmsg() failed (9: Bad file number)" on HP-UX
|
||||
while reconfiguration.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.1" date="05.06.2012">
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
теперь nginx/Windows игнорирует точку в конце компонента URI
|
||||
и не разрешает URI, содержащие последовательность ":$".<br/>
|
||||
Спасибо Владимиру Кочеткову, Positive Research Center.
|
||||
</para>
|
||||
<para lang="en">
|
||||
now nginx/Windows ignores trailing dot in URI path component, and
|
||||
does not allow URIs with ":$" in it.<br/>
|
||||
Thanks to Vladimir Kochetkov, Positive Research Center.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директива debug_connection теперь поддерживает IPv6-адреса
|
||||
и параметр "unix:".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "debug_connection" directive now supports IPv6 addresses
|
||||
and the "unix:" parameter.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директива set_real_ip_from и параметр proxy
|
||||
директивы geo теперь поддерживают IPv6-адреса.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "set_real_ip_from" directive and the "proxy" parameter
|
||||
of the "geo" directive now support IPv6 addresses.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
директивы real_ip_recursive, geoip_proxy и geoip_proxy_recursive.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "real_ip_recursive", "geoip_proxy", and "geoip_proxy_recursive" directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
параметр proxy_recursive директивы geo.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_recursive" parameter of the "geo" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовалась директива resolver.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "resolver" directive was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовались директивы fastcgi_pass, scgi_pass или uwsgi_pass
|
||||
и бэкенд возвращал некорректный ответ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "fastcgi_pass", "scgi_pass", or "uwsgi_pass" directives were used
|
||||
and backend returned incorrect response.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в рабочем процессе мог произойти segmentation fault,
|
||||
если использовалась директива rewrite и в новых аргументах запроса в строке
|
||||
замены использовались переменные.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "rewrite" directive was used and new request arguments
|
||||
in a replacement used variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx мог нагружать процессор,
|
||||
если было достигнуто ограничение на количество открытых файлов.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx might hog CPU
|
||||
if the open file resource limit was reached.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании директивы proxy_next_upstream с параметром http_404
|
||||
nginx мог бесконечно перебирать бэкенды, если в блоке upstream был
|
||||
хотя бы один сервер с флагом backup.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx might loop infinitely over backends
|
||||
if the "proxy_next_upstream" directive with the "http_404" parameter was used
|
||||
and there were backup servers specified in an upstream block.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании директивы ip_hash
|
||||
установка параметра down директивы server
|
||||
могла приводить к ненужному перераспределению клиентов между бэкендами.
|
||||
</para>
|
||||
<para lang="en">
|
||||
adding the "down" parameter of the "server" directive
|
||||
might cause unneeded client redistribution among backend servers
|
||||
if the "ip_hash" directive was used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
утечки сокетов.<br/>
|
||||
Спасибо Yichun Zhang.
|
||||
</para>
|
||||
<para lang="en">
|
||||
socket leak.<br/>
|
||||
Thanks to Yichun Zhang.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в модуле ngx_http_fastcgi_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the ngx_http_fastcgi_module.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.2.0" date="23.04.2012">
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
X:stylesheet {
|
||||
|
||||
X:output method="xml"
|
||||
X:param indent-increment="' '";
|
||||
|
||||
X:template noname(indent="'
'") = "*" {
|
||||
!{$indent}
|
||||
|
||||
X:if "name()='xsl:template'" {
|
||||
!{$indent}
|
||||
}
|
||||
|
||||
X:copy {
|
||||
X:copy-of "@*"
|
||||
!!( indent = "concat($indent, $indent-increment)" );
|
||||
X:if "./* " { !{$indent} }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
X:template = "comment()|processing-instruction()" {
|
||||
X:copy;
|
||||
}
|
||||
|
||||
<!--
|
||||
X:template ="text()[normalize-space(.)='']" {}
|
||||
-->
|
||||
|
||||
}
|
||||
X:stylesheet {
|
||||
|
||||
X:output method="xml"
|
||||
X:param indent-increment="' '";
|
||||
|
||||
X:template noname(indent="'
'") = "*" {
|
||||
!{$indent}
|
||||
|
||||
X:if "name()='xsl:template'" {
|
||||
!{$indent}
|
||||
}
|
||||
|
||||
X:copy {
|
||||
X:copy-of "@*"
|
||||
!!( indent = "concat($indent, $indent-increment)" );
|
||||
X:if "./* " { !{$indent} }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
X:template = "comment()|processing-instruction()" {
|
||||
X:copy;
|
||||
}
|
||||
|
||||
<!--
|
||||
X:template ="text()[normalize-space(.)='']" {}
|
||||
-->
|
||||
|
||||
}
|
||||
|
|
131
misc/GNUmakefile
131
misc/GNUmakefile
|
@ -6,15 +6,12 @@ TEMP = tmp
|
|||
REPO = $(shell svn info | sed -n 's/^Repository Root: //p')
|
||||
|
||||
OBJS = objs.msvc8
|
||||
OPENSSL = openssl-1.0.0i
|
||||
ZLIB = zlib-1.2.5
|
||||
PCRE = pcre-8.30
|
||||
OPENSSL = openssl-1.0.1e
|
||||
ZLIB = zlib-1.2.7
|
||||
PCRE = pcre-8.32
|
||||
|
||||
|
||||
release:
|
||||
rm -rf $(TEMP)
|
||||
|
||||
svn export -rHEAD . $(TEMP)/$(NGINX)
|
||||
release: export
|
||||
|
||||
mv $(TEMP)/$(NGINX)/auto/configure $(TEMP)/$(NGINX)
|
||||
|
||||
|
@ -39,70 +36,102 @@ release:
|
|||
tar -c -z -f $(NGINX).tar.gz --directory $(TEMP) $(NGINX)
|
||||
|
||||
|
||||
export:
|
||||
rm -rf $(TEMP)
|
||||
|
||||
if [ -d .svn ]; then \
|
||||
svn export -rHEAD . $(TEMP)/$(NGINX); \
|
||||
else \
|
||||
hg archive -X '.hg*' $(TEMP)/$(NGINX); \
|
||||
fi
|
||||
|
||||
|
||||
RELEASE:
|
||||
if [ -d .svn ]; then \
|
||||
$(MAKE) -f misc/GNUmakefile RELEASE.svn; \
|
||||
else \
|
||||
$(MAKE) -f misc/GNUmakefile RELEASE.hg; \
|
||||
fi
|
||||
|
||||
$(MAKE) -f misc/GNUmakefile release
|
||||
|
||||
|
||||
RELEASE.hg:
|
||||
hg ci -m nginx-$(VER)-RELEASE
|
||||
hg tag -m "release-$(VER) tag" release-$(VER)
|
||||
|
||||
|
||||
RELEASE.svn:
|
||||
test -d $(TEMP) || mkdir -p $(TEMP)
|
||||
|
||||
echo "nginx-$(VER)-RELEASE" > $(TEMP)/message
|
||||
svn ci -F $(TEMP)/message
|
||||
|
||||
echo "release-$(VER) tag" > $(TEMP)/message
|
||||
svn copy $(REPO)/trunk $(REPO)/tags/release-$(VER) \
|
||||
svn copy $(REPO)/branches/stable-1.2 \
|
||||
$(REPO)/tags/release-$(VER) \
|
||||
-F $(TEMP)/message
|
||||
|
||||
svn up
|
||||
|
||||
$(MAKE) -f misc/GNUmakefile release
|
||||
|
||||
win32:
|
||||
./auto/configure \
|
||||
--with-cc=cl \
|
||||
--builddir=$(OBJS) \
|
||||
--with-debug \
|
||||
--prefix= \
|
||||
--conf-path=conf/nginx.conf \
|
||||
--pid-path=logs/nginx.pid \
|
||||
--http-log-path=logs/access.log \
|
||||
--error-log-path=logs/error.log \
|
||||
--sbin-path=nginx.exe \
|
||||
--http-client-body-temp-path=temp/client_body_temp \
|
||||
--http-proxy-temp-path=temp/proxy_temp \
|
||||
--http-fastcgi-temp-path=temp/fastcgi_temp \
|
||||
--http-scgi-temp-path=temp/scgi_temp \
|
||||
--http-uwsgi-temp-path=temp/uwsgi_temp \
|
||||
--with-cc-opt=-DFD_SETSIZE=1024 \
|
||||
--with-pcre=$(OBJS)/lib/$(PCRE) \
|
||||
--with-zlib=$(OBJS)/lib/$(ZLIB) \
|
||||
--with-select_module \
|
||||
--with-http_realip_module \
|
||||
--with-http_addition_module \
|
||||
--with-http_sub_module \
|
||||
--with-http_dav_module \
|
||||
--with-http_stub_status_module \
|
||||
--with-http_flv_module \
|
||||
--with-http_mp4_module \
|
||||
--with-http_gzip_static_module \
|
||||
--with-http_random_index_module \
|
||||
--with-http_secure_link_module \
|
||||
--with-mail \
|
||||
--with-openssl=$(OBJS)/lib/$(OPENSSL) \
|
||||
--with-openssl-opt=enable-tlsext \
|
||||
--with-http_ssl_module \
|
||||
--with-mail_ssl_module \
|
||||
--with-ipv6
|
||||
|
||||
|
||||
snapshot:
|
||||
rm -rf $(TEMP)
|
||||
|
||||
mkdir -p $(TEMP)
|
||||
svn export . $(TEMP)/$(NGINX)
|
||||
|
||||
mv $(TEMP)/$(NGINX)/auto/configure $(TEMP)/$(NGINX)
|
||||
|
||||
# delete incomplete sources
|
||||
rm $(TEMP)/$(NGINX)/src/event/ngx_event_acceptex.c
|
||||
rm $(TEMP)/$(NGINX)/src/event/ngx_event_connectex.c
|
||||
rm $(TEMP)/$(NGINX)/src/event/modules/ngx_iocp_module.*
|
||||
rm -r $(TEMP)/$(NGINX)/src/os/win32
|
||||
|
||||
rm -r $(TEMP)/$(NGINX)/src/mysql
|
||||
|
||||
mv $(TEMP)/$(NGINX)/docs/text/LICENSE $(TEMP)/$(NGINX)
|
||||
mv $(TEMP)/$(NGINX)/docs/text/README $(TEMP)/$(NGINX)
|
||||
mv $(TEMP)/$(NGINX)/docs/html $(TEMP)/$(NGINX)
|
||||
mv $(TEMP)/$(NGINX)/docs/man $(TEMP)/$(NGINX)
|
||||
|
||||
$(MAKE) -f docs/GNUmakefile changes
|
||||
|
||||
rm -r $(TEMP)/$(NGINX)/docs
|
||||
rm -r $(TEMP)/$(NGINX)/misc
|
||||
|
||||
tar -c -z -f $(NGINX).tar.gz --directory $(TEMP) $(NGINX)
|
||||
|
||||
|
||||
zip:
|
||||
rm -rf $(TEMP)
|
||||
zip: export
|
||||
rm -f $(NGINX).zip
|
||||
|
||||
mkdir -p $(TEMP)/$(NGINX)/docs
|
||||
mkdir -p $(TEMP)/$(NGINX)/docs.new
|
||||
mkdir -p $(TEMP)/$(NGINX)/logs
|
||||
mkdir -p $(TEMP)/$(NGINX)/temp
|
||||
|
||||
svn export -rHEAD conf $(TEMP)/$(NGINX)/conf/
|
||||
perl -pi -e 's/$$/\r/' $(TEMP)/$(NGINX)/conf/*
|
||||
sed -i '' -e "s/$$/`printf '\r'`/" $(TEMP)/$(NGINX)/conf/*
|
||||
|
||||
svn export -rHEAD contrib $(TEMP)/$(NGINX)/contrib/
|
||||
svn export -rHEAD docs/html $(TEMP)/$(NGINX)/html/
|
||||
mv $(TEMP)/$(NGINX)/docs/text/LICENSE $(TEMP)/$(NGINX)/docs.new
|
||||
mv $(TEMP)/$(NGINX)/docs/text/README $(TEMP)/$(NGINX)/docs.new
|
||||
mv $(TEMP)/$(NGINX)/docs/html $(TEMP)/$(NGINX)
|
||||
|
||||
$(MAKE) -f docs/GNUmakefile changes
|
||||
rm -r $(TEMP)/$(NGINX)/docs
|
||||
mv $(TEMP)/$(NGINX)/docs.new $(TEMP)/$(NGINX)/docs
|
||||
|
||||
cp -p $(OBJS)/nginx.exe $(TEMP)/$(NGINX)
|
||||
|
||||
cp -p docs/text/LICENSE $(TEMP)/$(NGINX)/docs/
|
||||
cp -p docs/text/README $(TEMP)/$(NGINX)/docs/
|
||||
$(MAKE) -f docs/GNUmakefile changes
|
||||
mv $(TEMP)/$(NGINX)/CHANGES* $(TEMP)/$(NGINX)/docs/
|
||||
|
||||
cp -p $(OBJS)/lib/$(OPENSSL)/LICENSE \
|
||||
|
@ -111,13 +140,17 @@ zip:
|
|||
cp -p $(OBJS)/lib/$(PCRE)/LICENCE \
|
||||
$(TEMP)/$(NGINX)/docs/PCRE.LICENCE
|
||||
|
||||
perl -ne 'print if /^ \(C\) 1995-20/ .. /^ jloup\@gzip.org/' \
|
||||
sed -ne '/^ (C) 1995-20/,/^ jloup@gzip\.org/p' \
|
||||
$(OBJS)/lib/$(ZLIB)/README \
|
||||
> $(TEMP)/$(NGINX)/docs/zlib.LICENSE
|
||||
|
||||
touch -r $(OBJS)/lib/$(ZLIB)/README \
|
||||
$(TEMP)/$(NGINX)/docs/zlib.LICENSE
|
||||
|
||||
rm -r $(TEMP)/$(NGINX)/auto
|
||||
rm -r $(TEMP)/$(NGINX)/misc
|
||||
rm -r $(TEMP)/$(NGINX)/src
|
||||
|
||||
cd $(TEMP) && zip -r ../$(NGINX).zip $(NGINX)
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ static char *ngx_set_env(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 char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_debug_points[] = {
|
||||
|
@ -69,9 +71,9 @@ static ngx_command_t ngx_core_commands[] = {
|
|||
|
||||
{ ngx_string("worker_processes"),
|
||||
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
ngx_set_worker_processes,
|
||||
0,
|
||||
0,
|
||||
offsetof(ngx_core_conf_t, worker_processes),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("debug_points"),
|
||||
|
@ -592,6 +594,10 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
|
|||
var = ngx_alloc(sizeof(NGINX_VAR)
|
||||
+ cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
|
||||
cycle->log);
|
||||
if (var == NULL) {
|
||||
ngx_free(env);
|
||||
return NGX_INVALID_PID;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR));
|
||||
|
||||
|
@ -631,7 +637,7 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
|
|||
|
||||
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
||||
|
||||
if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) != NGX_OK) {
|
||||
if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
ngx_rename_file_n " %s to %s failed "
|
||||
"before executing new binary process \"%s\"",
|
||||
|
@ -646,7 +652,9 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
|
|||
pid = ngx_execute(cycle, &ctx);
|
||||
|
||||
if (pid == NGX_INVALID_PID) {
|
||||
if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) != NGX_OK) {
|
||||
if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
|
||||
== NGX_FILE_ERROR)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
ngx_rename_file_n " %s back to %s failed after "
|
||||
"an attempt to execute new binary process \"%s\"",
|
||||
|
@ -836,7 +844,7 @@ ngx_process_options(ngx_cycle_t *cycle)
|
|||
len = ngx_strlen(ngx_prefix);
|
||||
p = ngx_prefix;
|
||||
|
||||
if (!ngx_path_separator(*p)) {
|
||||
if (len && !ngx_path_separator(p[len - 1])) {
|
||||
p = ngx_pnalloc(cycle->pool, len + 1);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
@ -1329,3 +1337,32 @@ ngx_get_cpu_affinity(ngx_uint_t n)
|
|||
|
||||
return ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_str_t *value;
|
||||
ngx_core_conf_t *ccf;
|
||||
|
||||
ccf = (ngx_core_conf_t *) conf;
|
||||
|
||||
if (ccf->worker_processes != NGX_CONF_UNSET) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = (ngx_str_t *) cf->args->elts;
|
||||
|
||||
if (ngx_strcmp(value[1].data, "auto") == 0) {
|
||||
ccf->worker_processes = ngx_ncpu;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ccf->worker_processes = ngx_atoi(value[1].data, value[1].len);
|
||||
|
||||
if (ccf->worker_processes == NGX_ERROR) {
|
||||
return "invalid value";
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1002000
|
||||
#define NGINX_VERSION "1.2.0"
|
||||
#define nginx_version 1002009
|
||||
#define NGINX_VERSION "1.2.9"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
|
||||
static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
|
||||
static char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static ngx_int_t ngx_conf_test_full_name(ngx_str_t *name);
|
||||
static void ngx_conf_flush_files(ngx_cycle_t *cycle);
|
||||
|
||||
|
@ -134,7 +133,7 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
|
|||
|
||||
cf->conf_file = &conf_file;
|
||||
|
||||
if (ngx_fd_info(fd, &cf->conf_file->file.info) == -1) {
|
||||
if (ngx_fd_info(fd, &cf->conf_file->file.info) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
|
||||
ngx_fd_info_n " \"%s\" failed", filename->data);
|
||||
}
|
||||
|
@ -282,24 +281,16 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
|
|||
{
|
||||
char *rv;
|
||||
void *conf, **confp;
|
||||
ngx_uint_t i, multi;
|
||||
ngx_uint_t i, found;
|
||||
ngx_str_t *name;
|
||||
ngx_command_t *cmd;
|
||||
|
||||
name = cf->args->elts;
|
||||
|
||||
multi = 0;
|
||||
found = 0;
|
||||
|
||||
for (i = 0; ngx_modules[i]; i++) {
|
||||
|
||||
/* look up the directive in the appropriate modules */
|
||||
|
||||
if (ngx_modules[i]->type != NGX_CONF_MODULE
|
||||
&& ngx_modules[i]->type != cf->module_type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd = ngx_modules[i]->commands;
|
||||
if (cmd == NULL) {
|
||||
continue;
|
||||
|
@ -315,16 +306,18 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
|
|||
continue;
|
||||
}
|
||||
|
||||
found = 1;
|
||||
|
||||
if (ngx_modules[i]->type != NGX_CONF_MODULE
|
||||
&& ngx_modules[i]->type != cf->module_type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* is the directive's location right ? */
|
||||
|
||||
if (!(cmd->type & cf->cmd_type)) {
|
||||
if (cmd->type & NGX_CONF_MULTI) {
|
||||
multi = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
goto not_allowed;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
|
||||
|
@ -408,17 +401,16 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
|
|||
}
|
||||
}
|
||||
|
||||
if (multi == 0) {
|
||||
if (found) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown directive \"%s\"", name->data);
|
||||
"\"%s\" directive is not allowed here", name->data);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
not_allowed:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"%s\" directive is not allowed here", name->data);
|
||||
"unknown directive \"%s\"", name->data);
|
||||
|
||||
return NGX_ERROR;
|
||||
|
||||
invalid:
|
||||
|
@ -738,7 +730,7 @@ ngx_conf_read_token(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
char *
|
||||
ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *rv;
|
||||
|
@ -953,7 +945,8 @@ ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
|
|||
file->name = *name;
|
||||
}
|
||||
|
||||
file->buffer = NULL;
|
||||
file->flush = NULL;
|
||||
file->data = NULL;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
@ -962,7 +955,6 @@ ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
|
|||
static void
|
||||
ngx_conf_flush_files(ngx_cycle_t *cycle)
|
||||
{
|
||||
ssize_t n, len;
|
||||
ngx_uint_t i;
|
||||
ngx_list_part_t *part;
|
||||
ngx_open_file_t *file;
|
||||
|
@ -983,23 +975,8 @@ ngx_conf_flush_files(ngx_cycle_t *cycle)
|
|||
i = 0;
|
||||
}
|
||||
|
||||
len = file[i].pos - file[i].buffer;
|
||||
|
||||
if (file[i].buffer == NULL || len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
n = ngx_write_fd(file[i].fd, file[i].buffer, len);
|
||||
|
||||
if (n == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
ngx_write_fd_n " to \"%s\" failed",
|
||||
file[i].name.data);
|
||||
|
||||
} else if (n != len) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
|
||||
file[i].name.data, n, len);
|
||||
if (file[i].flush) {
|
||||
file[i].flush(&file[i], cycle->log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1448,12 +1425,16 @@ ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
char *
|
||||
ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
return "unsupported on this platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data)
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define NGX_CONF_ANY 0x00000400
|
||||
#define NGX_CONF_1MORE 0x00000800
|
||||
#define NGX_CONF_2MORE 0x00001000
|
||||
#define NGX_CONF_MULTI 0x00002000
|
||||
#define NGX_CONF_MULTI 0x00000000 /* compatibility */
|
||||
|
||||
#define NGX_DIRECT_CONF 0x00010000
|
||||
|
||||
|
@ -91,17 +91,8 @@ struct ngx_open_file_s {
|
|||
ngx_fd_t fd;
|
||||
ngx_str_t name;
|
||||
|
||||
u_char *buffer;
|
||||
u_char *pos;
|
||||
u_char *last;
|
||||
|
||||
#if 0
|
||||
/* e.g. append mode, error_log */
|
||||
ngx_uint_t flags;
|
||||
/* e.g. reopen db file */
|
||||
ngx_uint_t (*handler)(void *data, ngx_open_file_t *file);
|
||||
void (*flush)(ngx_open_file_t *file, ngx_log_t *log);
|
||||
void *data;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -317,6 +308,7 @@ char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
|
|||
|
||||
char *ngx_conf_param(ngx_conf_t *cf);
|
||||
char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
|
||||
char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
|
||||
ngx_int_t ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name,
|
||||
|
|
|
@ -412,7 +412,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
if (ngx_test_config) {
|
||||
if (ngx_delete_file(name) == -1) {
|
||||
if (ngx_delete_file(name) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
|
||||
ngx_delete_file_n " %s failed", name);
|
||||
}
|
||||
|
@ -739,7 +739,7 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|||
{
|
||||
u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
|
||||
|
||||
if (ngx_delete_file(name) == -1) {
|
||||
if (ngx_delete_file(name) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
|
||||
ngx_delete_file_n " %s failed", name);
|
||||
}
|
||||
|
@ -749,6 +749,8 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|||
|
||||
ls[i].fd = (ngx_socket_t) -1;
|
||||
}
|
||||
|
||||
cycle->listening.nelts = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_crypt.h>
|
||||
#include <ngx_md5.h>
|
||||
#if (NGX_HAVE_SHA1)
|
||||
#include <ngx_sha1.h>
|
||||
|
@ -193,6 +194,7 @@ static ngx_int_t
|
|||
ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
|
||||
{
|
||||
size_t len;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t encoded, decoded;
|
||||
ngx_sha1_t sha1;
|
||||
|
||||
|
@ -203,12 +205,18 @@ ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
|
|||
encoded.data = salt + sizeof("{SSHA}") - 1;
|
||||
encoded.len = ngx_strlen(encoded.data);
|
||||
|
||||
decoded.data = ngx_pnalloc(pool, ngx_base64_decoded_length(encoded.len));
|
||||
len = ngx_max(ngx_base64_decoded_length(encoded.len), 20);
|
||||
|
||||
decoded.data = ngx_pnalloc(pool, len);
|
||||
if (decoded.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_decode_base64(&decoded, &encoded);
|
||||
rc = ngx_decode_base64(&decoded, &encoded);
|
||||
|
||||
if (rc != NGX_OK || decoded.len < 20) {
|
||||
decoded.len = 20;
|
||||
}
|
||||
|
||||
/* update SHA1 from key and salt */
|
||||
|
||||
|
|
|
@ -118,18 +118,18 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
}
|
||||
|
||||
|
||||
n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10;
|
||||
n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
|
||||
|
||||
cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
|
||||
if (cycle->pathes.elts == NULL) {
|
||||
cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
|
||||
if (cycle->paths.elts == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cycle->pathes.nelts = 0;
|
||||
cycle->pathes.size = sizeof(ngx_path_t *);
|
||||
cycle->pathes.nalloc = n;
|
||||
cycle->pathes.pool = pool;
|
||||
cycle->paths.nelts = 0;
|
||||
cycle->paths.size = sizeof(ngx_path_t *);
|
||||
cycle->paths.nalloc = n;
|
||||
cycle->paths.pool = pool;
|
||||
|
||||
|
||||
if (old_cycle->open_files.part.nelts) {
|
||||
|
@ -334,7 +334,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
}
|
||||
|
||||
|
||||
if (ngx_create_pathes(cycle, ccf->user) != NGX_OK) {
|
||||
if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (shm_zone[i].shm.size == oshm_zone[n].shm.size) {
|
||||
if (shm_zone[i].tag == oshm_zone[n].tag
|
||||
&& shm_zone[i].shm.size == oshm_zone[n].shm.size)
|
||||
{
|
||||
shm_zone[i].shm.addr = oshm_zone[n].shm.addr;
|
||||
|
||||
if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
|
||||
|
@ -677,7 +679,7 @@ old_shm_zone_done:
|
|||
ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
|
||||
"deleting socket %s", name);
|
||||
|
||||
if (ngx_delete_file(name) == -1) {
|
||||
if (ngx_delete_file(name) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
|
||||
ngx_delete_file_n " %s failed", name);
|
||||
}
|
||||
|
@ -1038,6 +1040,8 @@ ngx_signal_process(ngx_cycle_t *cycle, char *sig)
|
|||
|
||||
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
||||
|
||||
ngx_memzero(&file, sizeof(ngx_file_t));
|
||||
|
||||
file.name = ccf->pid;
|
||||
file.log = cycle->log;
|
||||
|
||||
|
@ -1111,7 +1115,6 @@ ngx_test_lockfile(u_char *file, ngx_log_t *log)
|
|||
void
|
||||
ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
|
||||
{
|
||||
ssize_t n, len;
|
||||
ngx_fd_t fd;
|
||||
ngx_uint_t i;
|
||||
ngx_list_part_t *part;
|
||||
|
@ -1135,24 +1138,8 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
|
|||
continue;
|
||||
}
|
||||
|
||||
len = file[i].pos - file[i].buffer;
|
||||
|
||||
if (file[i].buffer && len != 0) {
|
||||
|
||||
n = ngx_write_fd(file[i].fd, file[i].buffer, len);
|
||||
|
||||
if (n == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
ngx_write_fd_n " to \"%s\" failed",
|
||||
file[i].name.data);
|
||||
|
||||
} else if (n != len) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
|
||||
file[i].name.data, n, len);
|
||||
}
|
||||
|
||||
file[i].pos = file[i].buffer;
|
||||
if (file[i].flush) {
|
||||
file[i].flush(&file[i], cycle->log);
|
||||
}
|
||||
|
||||
fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
|
||||
|
@ -1285,14 +1272,6 @@ ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (size && size != shm_zone[i].shm.size) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the size %uz of shared memory zone \"%V\" "
|
||||
"conflicts with already declared size %uz",
|
||||
size, &shm_zone[i].shm.name, shm_zone[i].shm.size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tag != shm_zone[i].tag) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the shared memory zone \"%V\" is "
|
||||
|
@ -1301,6 +1280,14 @@ ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (size && size != shm_zone[i].shm.size) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the size %uz of shared memory zone \"%V\" "
|
||||
"conflicts with already declared size %uz",
|
||||
size, &shm_zone[i].shm.name, shm_zone[i].shm.size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &shm_zone[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ struct ngx_cycle_s {
|
|||
ngx_queue_t reusable_connections_queue;
|
||||
|
||||
ngx_array_t listening;
|
||||
ngx_array_t pathes;
|
||||
ngx_array_t paths;
|
||||
ngx_list_t open_files;
|
||||
ngx_list_t shared_memory;
|
||||
|
||||
|
|
|
@ -412,8 +412,8 @@ ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
|
|||
|
||||
path = *slot;
|
||||
|
||||
p = cf->cycle->pathes.elts;
|
||||
for (i = 0; i < cf->cycle->pathes.nelts; i++) {
|
||||
p = cf->cycle->paths.elts;
|
||||
for (i = 0; i < cf->cycle->paths.nelts; i++) {
|
||||
if (p[i]->name.len == path->name.len
|
||||
&& ngx_strcmp(p[i]->name.data, path->name.data) == 0)
|
||||
{
|
||||
|
@ -457,7 +457,7 @@ ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
|
|||
}
|
||||
}
|
||||
|
||||
p = ngx_array_push(&cf->cycle->pathes);
|
||||
p = ngx_array_push(&cf->cycle->paths);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -469,14 +469,14 @@ ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
|
||||
ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user)
|
||||
{
|
||||
ngx_err_t err;
|
||||
ngx_uint_t i;
|
||||
ngx_path_t **path;
|
||||
|
||||
path = cycle->pathes.elts;
|
||||
for (i = 0; i < cycle->pathes.nelts; i++) {
|
||||
path = cycle->paths.elts;
|
||||
for (i = 0; i < cycle->paths.nelts; i++) {
|
||||
|
||||
if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) {
|
||||
err = ngx_errno;
|
||||
|
@ -732,14 +732,14 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
|
|||
|
||||
n = ngx_read_fd(fd, buf, len);
|
||||
|
||||
if (n == NGX_FILE_ERROR) {
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
|
||||
ngx_read_fd_n " \"%s\" failed", from);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if ((size_t) n != len) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
|
||||
ngx_read_fd_n " has read only %z of %uz from %s",
|
||||
n, size, from);
|
||||
goto failed;
|
||||
|
@ -747,14 +747,14 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
|
|||
|
||||
n = ngx_write_fd(nfd, buf, len);
|
||||
|
||||
if (n == NGX_FILE_ERROR) {
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
|
||||
ngx_write_fd_n " \"%s\" failed", to);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if ((size_t) n != len) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
|
||||
ngx_write_fd_n " has written only %z of %uz to %s",
|
||||
n, size, to);
|
||||
goto failed;
|
||||
|
|
|
@ -130,7 +130,7 @@ void ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len);
|
|||
ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path);
|
||||
ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access);
|
||||
ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
|
||||
ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user);
|
||||
ngx_int_t ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user);
|
||||
ngx_int_t ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to,
|
||||
ngx_ext_rename_file_t *ext);
|
||||
ngx_int_t ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf);
|
||||
|
|
|
@ -924,17 +924,6 @@ wildcard:
|
|||
}
|
||||
|
||||
|
||||
hk = ngx_array_push(hwc);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key.len = last - 1;
|
||||
hk->key.data = p;
|
||||
hk->key_hash = 0;
|
||||
hk->value = value;
|
||||
|
||||
|
||||
/* check conflicts in wildcard hash */
|
||||
|
||||
name = keys->elts;
|
||||
|
@ -972,5 +961,18 @@ wildcard:
|
|||
|
||||
ngx_memcpy(name->data, key->data + skip, name->len);
|
||||
|
||||
|
||||
/* add to wildcard hash */
|
||||
|
||||
hk = ngx_array_push(hwc);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key.len = last - 1;
|
||||
hk->key.data = p;
|
||||
hk->key_hash = 0;
|
||||
hk->value = value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
@ -465,7 +465,7 @@ ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
|
|||
* prevent MSVC8 warning:
|
||||
* potentially uninitialized local variable 'inaddr6' used
|
||||
*/
|
||||
ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
|
||||
ngx_memzero(&inaddr6, sizeof(struct in6_addr));
|
||||
#endif
|
||||
|
||||
inaddr = ngx_inet_addr(text, len);
|
||||
|
@ -522,11 +522,6 @@ ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
return ngx_parse_unix_domain_url(pool, u);
|
||||
}
|
||||
|
||||
if ((p[0] == ':' || p[0] == '/') && !u->listen) {
|
||||
u->err = "invalid host";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (p[0] == '[') {
|
||||
return ngx_parse_inet6_url(pool, u);
|
||||
}
|
||||
|
@ -639,10 +634,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
args = ngx_strlchr(host, last, '?');
|
||||
|
||||
if (args) {
|
||||
if (uri == NULL) {
|
||||
uri = args;
|
||||
|
||||
} else if (args < uri) {
|
||||
if (uri == NULL || args < uri) {
|
||||
uri = args;
|
||||
}
|
||||
}
|
||||
|
@ -668,11 +660,6 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
|
||||
len = last - port;
|
||||
|
||||
if (len == 0) {
|
||||
u->err = "invalid port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
n = ngx_atoi(port, len);
|
||||
|
||||
if (n < 1 || n > 65535) {
|
||||
|
@ -779,11 +766,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
return ngx_inet_resolve_host(pool, u);
|
||||
}
|
||||
|
||||
|
||||
|
@ -825,6 +808,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
|
||||
u->uri.len = last - uri;
|
||||
u->uri.data = uri;
|
||||
|
||||
last = uri;
|
||||
}
|
||||
|
||||
if (*port == ':') {
|
||||
|
@ -832,11 +817,6 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
|
||||
len = last - port;
|
||||
|
||||
if (len == 0) {
|
||||
u->err = "invalid port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
n = ngx_atoi(port, len);
|
||||
|
||||
if (n < 1 || n > 65535) {
|
||||
|
@ -862,8 +842,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->host.len = len;
|
||||
u->host.data = host;
|
||||
u->host.len = len + 2;
|
||||
u->host.data = host - 1;
|
||||
|
||||
if (ngx_inet6_addr(host, len, sin6->sin6_addr.s6_addr) != NGX_OK) {
|
||||
u->err = "invalid IPv6 address";
|
||||
|
@ -874,17 +854,38 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||
u->wildcard = 1;
|
||||
}
|
||||
|
||||
u->family = AF_INET6;
|
||||
|
||||
if (u->no_resolve) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (u->no_port) {
|
||||
u->port = u->default_port;
|
||||
sin6->sin6_port = htons(u->default_port);
|
||||
}
|
||||
|
||||
u->family = AF_INET6;
|
||||
u->naddrs = 1;
|
||||
|
||||
u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
|
||||
if (u->addrs == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
|
||||
if (sin6 == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(sin6, u->sockaddr, sizeof(struct sockaddr_in6));
|
||||
|
||||
u->addrs[0].sockaddr = (struct sockaddr *) sin6;
|
||||
u->addrs[0].socklen = sizeof(struct sockaddr_in6);
|
||||
|
||||
p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
|
||||
&u->host, u->port) - p;
|
||||
u->addrs[0].name.data = p;
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
#else
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
#define NGX_SOCKADDR_STRLEN (sizeof("unix:") - 1 + NGX_UNIX_ADDRSTRLEN)
|
||||
#else
|
||||
#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1)
|
||||
#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1)
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <ngx_core.h>
|
||||
|
||||
|
||||
static void *ngx_radix_alloc(ngx_radix_tree_t *tree);
|
||||
static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree);
|
||||
|
||||
|
||||
ngx_radix_tree_t *
|
||||
|
@ -60,7 +60,7 @@ ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate)
|
|||
*/
|
||||
|
||||
if (preallocate == -1) {
|
||||
switch (ngx_pagesize / sizeof(ngx_radix_tree_t)) {
|
||||
switch (ngx_pagesize / sizeof(ngx_radix_node_t)) {
|
||||
|
||||
/* amd64 */
|
||||
case 128:
|
||||
|
@ -263,13 +263,210 @@ ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key)
|
|||
}
|
||||
|
||||
|
||||
static void *
|
||||
#if (NGX_HAVE_INET6)
|
||||
|
||||
ngx_int_t
|
||||
ngx_radix128tree_insert(ngx_radix_tree_t *tree, u_char *key, u_char *mask,
|
||||
uintptr_t value)
|
||||
{
|
||||
u_char bit;
|
||||
ngx_uint_t i;
|
||||
ngx_radix_node_t *node, *next;
|
||||
|
||||
i = 0;
|
||||
bit = 0x80;
|
||||
|
||||
node = tree->root;
|
||||
next = tree->root;
|
||||
|
||||
while (bit & mask[i]) {
|
||||
if (key[i] & bit) {
|
||||
next = node->right;
|
||||
|
||||
} else {
|
||||
next = node->left;
|
||||
}
|
||||
|
||||
if (next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
bit >>= 1;
|
||||
node = next;
|
||||
|
||||
if (bit == 0) {
|
||||
if (++i == 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
bit = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
if (next) {
|
||||
if (node->value != NGX_RADIX_NO_VALUE) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
|
||||
node->value = value;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
while (bit & mask[i]) {
|
||||
next = ngx_radix_alloc(tree);
|
||||
if (next == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
next->right = NULL;
|
||||
next->left = NULL;
|
||||
next->parent = node;
|
||||
next->value = NGX_RADIX_NO_VALUE;
|
||||
|
||||
if (key[i] & bit) {
|
||||
node->right = next;
|
||||
|
||||
} else {
|
||||
node->left = next;
|
||||
}
|
||||
|
||||
bit >>= 1;
|
||||
node = next;
|
||||
|
||||
if (bit == 0) {
|
||||
if (++i == 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
bit = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
node->value = value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_radix128tree_delete(ngx_radix_tree_t *tree, u_char *key, u_char *mask)
|
||||
{
|
||||
u_char bit;
|
||||
ngx_uint_t i;
|
||||
ngx_radix_node_t *node;
|
||||
|
||||
i = 0;
|
||||
bit = 0x80;
|
||||
node = tree->root;
|
||||
|
||||
while (node && (bit & mask[i])) {
|
||||
if (key[i] & bit) {
|
||||
node = node->right;
|
||||
|
||||
} else {
|
||||
node = node->left;
|
||||
}
|
||||
|
||||
bit >>= 1;
|
||||
|
||||
if (bit == 0) {
|
||||
if (++i == 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
bit = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
if (node == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (node->right || node->left) {
|
||||
if (node->value != NGX_RADIX_NO_VALUE) {
|
||||
node->value = NGX_RADIX_NO_VALUE;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for ( ;; ) {
|
||||
if (node->parent->right == node) {
|
||||
node->parent->right = NULL;
|
||||
|
||||
} else {
|
||||
node->parent->left = NULL;
|
||||
}
|
||||
|
||||
node->right = tree->free;
|
||||
tree->free = node;
|
||||
|
||||
node = node->parent;
|
||||
|
||||
if (node->right || node->left) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (node->value != NGX_RADIX_NO_VALUE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (node->parent == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
uintptr_t
|
||||
ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key)
|
||||
{
|
||||
u_char bit;
|
||||
uintptr_t value;
|
||||
ngx_uint_t i;
|
||||
ngx_radix_node_t *node;
|
||||
|
||||
i = 0;
|
||||
bit = 0x80;
|
||||
value = NGX_RADIX_NO_VALUE;
|
||||
node = tree->root;
|
||||
|
||||
while (node) {
|
||||
if (node->value != NGX_RADIX_NO_VALUE) {
|
||||
value = node->value;
|
||||
}
|
||||
|
||||
if (key[i] & bit) {
|
||||
node = node->right;
|
||||
|
||||
} else {
|
||||
node = node->left;
|
||||
}
|
||||
|
||||
bit >>= 1;
|
||||
|
||||
if (bit == 0) {
|
||||
i++;
|
||||
bit = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_radix_node_t *
|
||||
ngx_radix_alloc(ngx_radix_tree_t *tree)
|
||||
{
|
||||
char *p;
|
||||
ngx_radix_node_t *p;
|
||||
|
||||
if (tree->free) {
|
||||
p = (char *) tree->free;
|
||||
p = tree->free;
|
||||
tree->free = tree->free->right;
|
||||
return p;
|
||||
}
|
||||
|
@ -283,7 +480,7 @@ ngx_radix_alloc(ngx_radix_tree_t *tree)
|
|||
tree->size = ngx_pagesize;
|
||||
}
|
||||
|
||||
p = tree->start;
|
||||
p = (ngx_radix_node_t *) tree->start;
|
||||
tree->start += sizeof(ngx_radix_node_t);
|
||||
tree->size -= sizeof(ngx_radix_node_t);
|
||||
|
||||
|
|
|
@ -36,11 +36,20 @@ typedef struct {
|
|||
|
||||
ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool,
|
||||
ngx_int_t preallocate);
|
||||
|
||||
ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree,
|
||||
uint32_t key, uint32_t mask, uintptr_t value);
|
||||
ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree,
|
||||
uint32_t key, uint32_t mask);
|
||||
uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key);
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
ngx_int_t ngx_radix128tree_insert(ngx_radix_tree_t *tree,
|
||||
u_char *key, u_char *mask, uintptr_t value);
|
||||
ngx_int_t ngx_radix128tree_delete(ngx_radix_tree_t *tree,
|
||||
u_char *key, u_char *mask);
|
||||
uintptr_t ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_RADIX_TREE_H_INCLUDED_ */
|
||||
|
|
|
@ -152,7 +152,7 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rc->regex->pcre = re;
|
||||
rc->regex->code = re;
|
||||
|
||||
/* do not study at runtime */
|
||||
|
||||
|
@ -367,7 +367,7 @@ ngx_regex_module_init(ngx_cycle_t *cycle)
|
|||
i = 0;
|
||||
}
|
||||
|
||||
elts[i].regex->extra = pcre_study(elts[i].regex->pcre, opt, &errstr);
|
||||
elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
|
||||
|
||||
if (errstr != NULL) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
|
@ -380,7 +380,7 @@ ngx_regex_module_init(ngx_cycle_t *cycle)
|
|||
int jit, n;
|
||||
|
||||
jit = 0;
|
||||
n = pcre_fullinfo(elts[i].regex->pcre, elts[i].regex->extra,
|
||||
n = pcre_fullinfo(elts[i].regex->code, elts[i].regex->extra,
|
||||
PCRE_INFO_JIT, &jit);
|
||||
|
||||
if (n != 0 || jit != 1) {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
pcre *pcre;
|
||||
pcre *code;
|
||||
pcre_extra *extra;
|
||||
} ngx_regex_t;
|
||||
|
||||
|
@ -50,7 +50,7 @@ void ngx_regex_init(void);
|
|||
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
|
||||
|
||||
#define ngx_regex_exec(re, s, captures, size) \
|
||||
pcre_exec(re->pcre, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
|
||||
pcre_exec(re->code, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
|
||||
captures, size)
|
||||
#define ngx_regex_exec_n "pcre_exec()"
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
|
|||
static void ngx_resolver_free(ngx_resolver_t *r, void *p);
|
||||
static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
|
||||
static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
|
||||
static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src,
|
||||
ngx_uint_t n);
|
||||
static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
||||
|
||||
|
||||
|
@ -96,7 +98,7 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|||
{
|
||||
ngx_str_t s;
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i;
|
||||
ngx_uint_t i, j;
|
||||
ngx_resolver_t *r;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_udp_connection_t *uc;
|
||||
|
@ -113,15 +115,6 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
if (ngx_array_init(&r->udp_connections, cf->pool, n,
|
||||
sizeof(ngx_udp_connection_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cln->data = r;
|
||||
|
||||
r->event = ngx_calloc(sizeof(ngx_event_t), cf->log);
|
||||
|
@ -153,6 +146,15 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|||
r->log = &cf->cycle->new_log;
|
||||
r->log_level = NGX_LOG_ERR;
|
||||
|
||||
if (n) {
|
||||
if (ngx_array_init(&r->udp_connections, cf->pool, n,
|
||||
sizeof(ngx_udp_connection_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (ngx_strncmp(names[i].data, "valid=", 6) == 0) {
|
||||
s.len = names[i].len - 6;
|
||||
|
@ -171,24 +173,31 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
|
||||
u.host = names[i];
|
||||
u.port = 53;
|
||||
u.url = names[i];
|
||||
u.default_port = 53;
|
||||
|
||||
if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in resolver \"%V\"",
|
||||
u.err, &u.url);
|
||||
}
|
||||
|
||||
if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uc = ngx_array_push(&r->udp_connections);
|
||||
uc = ngx_array_push_n(&r->udp_connections, u.naddrs);
|
||||
if (uc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngx_memzero(uc, sizeof(ngx_udp_connection_t));
|
||||
ngx_memzero(uc, u.naddrs * sizeof(ngx_udp_connection_t));
|
||||
|
||||
uc->sockaddr = u.addrs->sockaddr;
|
||||
uc->socklen = u.addrs->socklen;
|
||||
uc->server = u.addrs->name;
|
||||
for (j = 0; j < u.naddrs; j++) {
|
||||
uc[j].sockaddr = u.addrs[j].sockaddr;
|
||||
uc[j].socklen = u.addrs[j].socklen;
|
||||
uc[j].server = u.addrs[j].name;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -438,8 +447,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
if (naddrs != 1) {
|
||||
addr = 0;
|
||||
addrs = ngx_resolver_dup(r, rn->u.addrs,
|
||||
naddrs * sizeof(in_addr_t));
|
||||
addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs);
|
||||
if (addrs == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -513,8 +521,10 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
/* lock alloc mutex */
|
||||
|
||||
ngx_resolver_free_locked(r, rn->query);
|
||||
rn->query = NULL;
|
||||
if (rn->query) {
|
||||
ngx_resolver_free_locked(r, rn->query);
|
||||
rn->query = NULL;
|
||||
}
|
||||
|
||||
if (rn->cnlen) {
|
||||
ngx_resolver_free_locked(r, rn->u.cname);
|
||||
|
@ -970,12 +980,11 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
|
|||
|
||||
if (rn->waiting) {
|
||||
|
||||
if (ngx_resolver_send_query(r, rn) == NGX_OK) {
|
||||
(void) ngx_resolver_send_query(r, rn);
|
||||
|
||||
rn->expire = now + r->resend_timeout;
|
||||
rn->expire = now + r->resend_timeout;
|
||||
|
||||
ngx_queue_insert_head(queue, &rn->queue);
|
||||
}
|
||||
ngx_queue_insert_head(queue, q);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -1033,7 +1042,7 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
|
|||
nan = (query->nan_hi << 8) + query->nan_lo;
|
||||
|
||||
ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
|
||||
"resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui",
|
||||
"resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud",
|
||||
ident, flags, nqs, nan,
|
||||
(query->nns_hi << 8) + query->nns_lo,
|
||||
(query->nar_hi << 8) + query->nar_lo);
|
||||
|
@ -1409,6 +1418,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|||
ngx_resolver_free(r, addrs);
|
||||
}
|
||||
|
||||
ngx_resolver_free(r, rn->query);
|
||||
rn->query = NULL;
|
||||
|
||||
return;
|
||||
|
||||
} else if (cname) {
|
||||
|
@ -1441,6 +1453,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|||
(void) ngx_resolve_name_locked(r, ctx);
|
||||
}
|
||||
|
||||
ngx_resolver_free(r, rn->query);
|
||||
rn->query = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1834,6 +1849,10 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
p--;
|
||||
*p-- = '\0';
|
||||
|
||||
if (ctx->name.len == 0) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
|
||||
if (*s != '.') {
|
||||
*p = *s;
|
||||
|
@ -2117,6 +2136,32 @@ ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size)
|
|||
}
|
||||
|
||||
|
||||
static in_addr_t *
|
||||
ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n)
|
||||
{
|
||||
void *dst, *p;
|
||||
ngx_uint_t j;
|
||||
|
||||
dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t));
|
||||
|
||||
if (dst == NULL) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
j = ngx_random() % n;
|
||||
|
||||
if (j == 0) {
|
||||
ngx_memcpy(dst, src, n * sizeof(in_addr_t));
|
||||
return dst;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t));
|
||||
ngx_memcpy(p, src, j * sizeof(in_addr_t));
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_resolver_strerror(ngx_int_t err)
|
||||
{
|
||||
|
@ -2172,7 +2217,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
|
|||
ngx_socket_t s;
|
||||
ngx_connection_t *c;
|
||||
|
||||
s = ngx_socket(AF_INET, SOCK_DGRAM, 0);
|
||||
s = ngx_socket(uc->sockaddr->sa_family, SOCK_DGRAM, 0);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s);
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
|
|||
|
||||
|
||||
void
|
||||
ngx_shmtx_destory(ngx_shmtx_t *mtx)
|
||||
ngx_shmtx_destroy(ngx_shmtx_t *mtx)
|
||||
{
|
||||
#if (NGX_HAVE_POSIX_SEM)
|
||||
|
||||
|
@ -117,11 +117,11 @@ ngx_shmtx_lock(ngx_shmtx_t *mtx)
|
|||
"sem_wait() failed while waiting on shmtx");
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
|
||||
"shmtx awoke");
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
|
||||
"shmtx awoke");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_shmtx_destory(mtx);
|
||||
ngx_shmtx_destroy(mtx);
|
||||
}
|
||||
|
||||
mtx->fd = ngx_open_file(name, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
|
||||
|
@ -232,7 +232,7 @@ ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
|
|||
|
||||
|
||||
void
|
||||
ngx_shmtx_destory(ngx_shmtx_t *mtx)
|
||||
ngx_shmtx_destroy(ngx_shmtx_t *mtx)
|
||||
{
|
||||
if (ngx_close_file(mtx->fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef struct {
|
|||
|
||||
ngx_int_t ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr,
|
||||
u_char *name);
|
||||
void ngx_shmtx_destory(ngx_shmtx_t *mtx);
|
||||
void ngx_shmtx_destroy(ngx_shmtx_t *mtx);
|
||||
ngx_uint_t ngx_shmtx_trylock(ngx_shmtx_t *mtx);
|
||||
void ngx_shmtx_lock(ngx_shmtx_t *mtx);
|
||||
void ngx_shmtx_unlock(ngx_shmtx_t *mtx);
|
||||
|
|
|
@ -45,9 +45,7 @@
|
|||
|
||||
#define ngx_slab_junk(p, size) ngx_memset(p, 0xA5, size)
|
||||
|
||||
#else
|
||||
|
||||
#if (NGX_HAVE_DEBUG_MALLOC)
|
||||
#elif (NGX_HAVE_DEBUG_MALLOC)
|
||||
|
||||
#define ngx_slab_junk(p, size) \
|
||||
if (ngx_debug_malloc) ngx_memset(p, 0xA5, size)
|
||||
|
@ -58,8 +56,6 @@
|
|||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool,
|
||||
ngx_uint_t pages);
|
||||
static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
|
@ -166,8 +162,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
|
|||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
|
||||
"slab alloc: %uz", size);
|
||||
|
||||
page = ngx_slab_alloc_pages(pool, (size + ngx_pagesize - 1)
|
||||
>> ngx_pagesize_shift);
|
||||
page = ngx_slab_alloc_pages(pool, (size >> ngx_pagesize_shift)
|
||||
+ ((size % ngx_pagesize) ? 1 : 0));
|
||||
if (page) {
|
||||
p = (page - pool->pages) << ngx_pagesize_shift;
|
||||
p += (uintptr_t) pool->start;
|
||||
|
|
|
@ -1827,7 +1827,7 @@ ngx_sort(void *base, size_t n, size_t size,
|
|||
#if (NGX_MEMCPY_LIMIT)
|
||||
|
||||
void *
|
||||
ngx_memcpy(void *dst, void *src, size_t n)
|
||||
ngx_memcpy(void *dst, const void *src, size_t n)
|
||||
{
|
||||
if (n > NGX_MEMCPY_LIMIT) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "memcpy %uz bytes", n);
|
||||
|
|
|
@ -89,7 +89,7 @@ ngx_strlchr(u_char *p, u_char *last, u_char c)
|
|||
|
||||
#if (NGX_MEMCPY_LIMIT)
|
||||
|
||||
void *ngx_memcpy(void *dst, void *src, size_t n);
|
||||
void *ngx_memcpy(void *dst, const void *src, size_t n);
|
||||
#define ngx_cpymem(dst, src, n) (((u_char *) ngx_memcpy(dst, src, n)) + (n))
|
||||
|
||||
#else
|
||||
|
|
|
@ -211,6 +211,10 @@ ngx_time_sigsafe_update(void)
|
|||
slot++;
|
||||
}
|
||||
|
||||
tp = &cached_time[slot];
|
||||
|
||||
tp->sec = 0;
|
||||
|
||||
ngx_gmtime(sec + cached_gmtoff * 60, &tm);
|
||||
|
||||
p = &cached_err_log_time[slot][0];
|
||||
|
|
|
@ -44,16 +44,25 @@ struct epoll_event {
|
|||
epoll_data_t data;
|
||||
};
|
||||
|
||||
|
||||
int epoll_create(int size);
|
||||
|
||||
int epoll_create(int size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
|
||||
|
||||
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout);
|
||||
|
||||
int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout)
|
||||
{
|
||||
return -1;
|
||||
|
@ -76,11 +85,6 @@ struct io_event {
|
|||
};
|
||||
|
||||
|
||||
int eventfd(u_int initval)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
#define ushort_t u_short
|
||||
#define uint_t u_int
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
typedef int clockid_t;
|
||||
typedef void * timer_t;
|
||||
#endif
|
||||
|
||||
/* Solaris declarations */
|
||||
|
||||
#define PORT_SOURCE_AIO 1
|
||||
|
@ -24,7 +30,9 @@
|
|||
#define PORT_SOURCE_ALERT 5
|
||||
#define PORT_SOURCE_MQ 6
|
||||
|
||||
#ifndef ETIME
|
||||
#define ETIME 64
|
||||
#endif
|
||||
|
||||
#define SIGEV_PORT 4
|
||||
|
||||
|
@ -50,39 +58,62 @@ typedef struct itimerspec { /* definition per POSIX.4 */
|
|||
|
||||
#endif
|
||||
|
||||
int port_create(void);
|
||||
|
||||
int port_create(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int port_associate(int port, int source, uintptr_t object, int events,
|
||||
void *user);
|
||||
|
||||
int port_associate(int port, int source, uintptr_t object, int events,
|
||||
void *user)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int port_dissociate(int port, int source, uintptr_t object);
|
||||
|
||||
int port_dissociate(int port, int source, uintptr_t object)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
|
||||
struct timespec *timeout);
|
||||
|
||||
int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
|
||||
struct timespec *timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid);
|
||||
|
||||
int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
|
||||
struct itimerspec *ovalue);
|
||||
|
||||
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
|
||||
struct itimerspec *ovalue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int timer_delete(timer_t timerid);
|
||||
|
||||
int timer_delete(timer_t timerid)
|
||||
{
|
||||
return -1;
|
||||
|
|
|
@ -371,7 +371,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|||
|
||||
found = 0;
|
||||
|
||||
if (revents & POLLIN) {
|
||||
if ((revents & POLLIN) && c->read->active) {
|
||||
found = 1;
|
||||
|
||||
ev = c->read;
|
||||
|
@ -388,7 +388,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|||
ngx_locked_post_event(ev, queue);
|
||||
}
|
||||
|
||||
if (revents & POLLOUT) {
|
||||
if ((revents & POLLOUT) && c->write->active) {
|
||||
found = 1;
|
||||
ev = c->write;
|
||||
|
||||
|
|
|
@ -12,6 +12,13 @@
|
|||
|
||||
#if (NGX_TEST_BUILD_RTSIG)
|
||||
|
||||
#if (NGX_DARWIN)
|
||||
|
||||
#define SIGRTMIN 33
|
||||
#define si_fd __pad[0]
|
||||
|
||||
#else
|
||||
|
||||
#ifdef SIGRTMIN
|
||||
#define si_fd _reason.__spare__.__spare2__[0]
|
||||
#else
|
||||
|
@ -19,10 +26,15 @@
|
|||
#define si_fd __spare__[0]
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define F_SETSIG 10
|
||||
#define KERN_RTSIGNR 30
|
||||
#define KERN_RTSIGMAX 31
|
||||
|
||||
int sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
const struct timespec *timeout);
|
||||
|
||||
int sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
const struct timespec *timeout)
|
||||
{
|
||||
|
|
|
@ -567,7 +567,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
|
|||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
void
|
||||
static void
|
||||
ngx_timer_signal_handler(int signo)
|
||||
{
|
||||
ngx_event_timer_alarm = 1;
|
||||
|
@ -892,6 +892,10 @@ ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_conf_t pcf;
|
||||
ngx_event_module_t *m;
|
||||
|
||||
if (*(void **) conf) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
/* count the number of the event modules and set up their indices */
|
||||
|
||||
ngx_event_max_module = 0;
|
||||
|
@ -1062,53 +1066,91 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
#if (NGX_DEBUG)
|
||||
ngx_event_conf_t *ecf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_event_debug_t *dc;
|
||||
struct hostent *h;
|
||||
ngx_cidr_t cidr;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_cidr_t c, *cidr;
|
||||
ngx_uint_t i;
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
dc = ngx_array_push(&ecf->debug_connection);
|
||||
if (dc == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless", &value[1]);
|
||||
rc = NGX_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
if (cidr.family != AF_INET) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"debug_connection\" supports IPv4 only");
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr = ngx_array_push(&ecf->debug_connection);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
dc->mask = cidr.u.in.mask;
|
||||
dc->addr = cidr.u.in.addr;
|
||||
cidr->family = AF_UNIX;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rc = ngx_ptocidr(&value[1], &c);
|
||||
|
||||
if (rc != NGX_ERROR) {
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless",
|
||||
&value[1]);
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(&ecf->debug_connection);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*cidr = c;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
h = gethostbyname((char *) value[1].data);
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
u.host = value[1];
|
||||
|
||||
if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in debug_connection \"%V\"",
|
||||
u.err, &u.host);
|
||||
}
|
||||
|
||||
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"host \"%s\" not found", value[1].data);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
dc->mask = 0xffffffff;
|
||||
dc->addr = *(in_addr_t *)(h->h_addr_list[0]);
|
||||
cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
|
||||
|
||||
for (i = 0; i < u.naddrs; i++) {
|
||||
cidr[i].family = u.addrs[i].sockaddr->sa_family;
|
||||
|
||||
switch (cidr[i].family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in6.addr = sin6->sin6_addr;
|
||||
ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in.addr = sin->sin_addr.s_addr;
|
||||
cidr[i].u.in.mask = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
@ -1142,7 +1184,7 @@ ngx_event_core_create_conf(ngx_cycle_t *cycle)
|
|||
#if (NGX_DEBUG)
|
||||
|
||||
if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
|
||||
sizeof(ngx_event_debug_t)) == NGX_ERROR)
|
||||
sizeof(ngx_cidr_t)) == NGX_ERROR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1176,7 +1218,7 @@ ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
|
|||
fd = epoll_create(100);
|
||||
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
(void) close(fd);
|
||||
module = &ngx_epoll_module;
|
||||
|
||||
} else if (ngx_errno != NGX_ENOSYS) {
|
||||
|
|
|
@ -221,12 +221,6 @@ struct ngx_event_aio_s {
|
|||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
in_addr_t mask;
|
||||
in_addr_t addr;
|
||||
} ngx_event_debug_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
|
||||
ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
|
||||
|
|
|
@ -21,6 +21,7 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
socklen_t socklen;
|
||||
ngx_err_t err;
|
||||
ngx_log_t *log;
|
||||
ngx_uint_t level;
|
||||
ngx_socket_t s;
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_listening_t *ls;
|
||||
|
@ -31,6 +32,14 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
static ngx_uint_t use_accept4 = 1;
|
||||
#endif
|
||||
|
||||
if (ev->timedout) {
|
||||
if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev->timedout = 0;
|
||||
}
|
||||
|
||||
ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
|
||||
|
||||
if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
|
||||
|
@ -70,10 +79,17 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
return;
|
||||
}
|
||||
|
||||
level = NGX_LOG_ALERT;
|
||||
|
||||
if (err == NGX_ECONNABORTED) {
|
||||
level = NGX_LOG_ERR;
|
||||
|
||||
} else if (err == NGX_EMFILE || err == NGX_ENFILE) {
|
||||
level = NGX_LOG_CRIT;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_ACCEPT4)
|
||||
ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ?
|
||||
NGX_LOG_ERR : NGX_LOG_ALERT),
|
||||
ev->log, err,
|
||||
ngx_log_error(level, ev->log, err,
|
||||
use_accept4 ? "accept4() failed" : "accept() failed");
|
||||
|
||||
if (use_accept4 && err == NGX_ENOSYS) {
|
||||
|
@ -82,9 +98,7 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
continue;
|
||||
}
|
||||
#else
|
||||
ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ?
|
||||
NGX_LOG_ERR : NGX_LOG_ALERT),
|
||||
ev->log, err, "accept() failed");
|
||||
ngx_log_error(level, ev->log, err, "accept() failed");
|
||||
#endif
|
||||
|
||||
if (err == NGX_ECONNABORTED) {
|
||||
|
@ -97,6 +111,26 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
}
|
||||
}
|
||||
|
||||
if (err == NGX_EMFILE || err == NGX_ENFILE) {
|
||||
if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_use_accept_mutex) {
|
||||
if (ngx_accept_mutex_held) {
|
||||
ngx_shmtx_unlock(&ngx_accept_mutex);
|
||||
ngx_accept_mutex_held = 0;
|
||||
}
|
||||
|
||||
ngx_accept_disabled = 1;
|
||||
|
||||
} else {
|
||||
ngx_add_timer(ev, ecf->accept_mutex_delay);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,17 +286,56 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
#if (NGX_DEBUG)
|
||||
{
|
||||
|
||||
in_addr_t i;
|
||||
ngx_event_debug_t *dc;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_cidr_t *cidr;
|
||||
ngx_uint_t i;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
ngx_uint_t n;
|
||||
#endif
|
||||
|
||||
sin = (struct sockaddr_in *) sa;
|
||||
dc = ecf->debug_connection.elts;
|
||||
cidr = ecf->debug_connection.elts;
|
||||
for (i = 0; i < ecf->debug_connection.nelts; i++) {
|
||||
if ((sin->sin_addr.s_addr & dc[i].mask) == dc[i].addr) {
|
||||
log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
|
||||
if (cidr[i].family != c->sockaddr->sa_family) {
|
||||
goto next;
|
||||
}
|
||||
|
||||
switch (cidr[i].family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) c->sockaddr;
|
||||
for (n = 0; n < 16; n++) {
|
||||
if ((sin6->sin6_addr.s6_addr[n]
|
||||
& cidr[i].u.in6.mask.s6_addr[n])
|
||||
!= cidr[i].u.in6.addr.s6_addr[n])
|
||||
{
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
case AF_UNIX:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) c->sockaddr;
|
||||
if ((sin->sin_addr.s_addr & cidr[i].u.in.mask)
|
||||
!= cidr[i].u.in.addr)
|
||||
{
|
||||
goto next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
|
||||
break;
|
||||
|
||||
next:
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -344,6 +417,10 @@ ngx_enable_accept_events(ngx_cycle_t *cycle)
|
|||
|
||||
c = ls[i].connection;
|
||||
|
||||
if (c->read->active) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
|
||||
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
|
|
|
@ -94,6 +94,26 @@ ngx_ssl_init(ngx_log_t *log)
|
|||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
|
||||
#ifndef SSL_OP_NO_COMPRESSION
|
||||
{
|
||||
/*
|
||||
* Disable gzip compression in OpenSSL prior to 1.0.0 version,
|
||||
* this saves about 522K per connection.
|
||||
*/
|
||||
int n;
|
||||
STACK_OF(SSL_COMP) *ssl_comp_methods;
|
||||
|
||||
ssl_comp_methods = SSL_COMP_get_compression_methods();
|
||||
n = sk_SSL_COMP_num(ssl_comp_methods);
|
||||
|
||||
while (n--) {
|
||||
(void) sk_SSL_COMP_pop(ssl_comp_methods);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (ngx_ssl_connection_index == -1) {
|
||||
|
@ -508,10 +528,10 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
|
||||
|
||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
|
||||
|
||||
SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
|
||||
|
||||
EC_KEY_free(ecdh);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -673,6 +693,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
|
@ -681,6 +705,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
c->read->handler = ngx_ssl_handshake_handler;
|
||||
c->write->handler = ngx_ssl_handshake_handler;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -990,11 +1018,11 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
c->buffered |= NGX_SSL_BUFFERED;
|
||||
return in;
|
||||
}
|
||||
|
||||
in->buf->pos += n;
|
||||
c->sent += n;
|
||||
|
||||
if (in->buf->pos == in->buf->last) {
|
||||
in = in->next;
|
||||
|
@ -1033,8 +1061,8 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
buf->end = buf->start + NGX_SSL_BUFSIZE;
|
||||
}
|
||||
|
||||
send = 0;
|
||||
flush = (in == NULL) ? 1 : 0;
|
||||
send = buf->last - buf->pos;
|
||||
flush = (in == NULL) ? 1 : buf->flush;
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
|
@ -1056,7 +1084,6 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
|
||||
if (send + size > limit) {
|
||||
size = (ssize_t) (limit - send);
|
||||
flush = 1;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
|
@ -1073,10 +1100,16 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
}
|
||||
}
|
||||
|
||||
if (!flush && send < limit && buf->last < buf->end) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = buf->last - buf->pos;
|
||||
|
||||
if (!flush && buf->last < buf->end && c->ssl->buffer) {
|
||||
break;
|
||||
if (size == 0) {
|
||||
buf->flush = 0;
|
||||
c->buffered &= ~NGX_SSL_BUFFERED;
|
||||
return in;
|
||||
}
|
||||
|
||||
n = ngx_ssl_write(c, buf->pos, size);
|
||||
|
@ -1086,8 +1119,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
c->buffered |= NGX_SSL_BUFFERED;
|
||||
return in;
|
||||
break;
|
||||
}
|
||||
|
||||
buf->pos += n;
|
||||
|
@ -1097,16 +1129,18 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
break;
|
||||
}
|
||||
|
||||
if (buf->pos == buf->last) {
|
||||
buf->pos = buf->start;
|
||||
buf->last = buf->start;
|
||||
}
|
||||
flush = 0;
|
||||
|
||||
buf->pos = buf->start;
|
||||
buf->last = buf->start;
|
||||
|
||||
if (in == NULL || send == limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buf->flush = flush;
|
||||
|
||||
if (buf->pos < buf->last) {
|
||||
c->buffered |= NGX_SSL_BUFFERED;
|
||||
|
||||
|
@ -1682,8 +1716,18 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
|||
}
|
||||
|
||||
sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
|
||||
|
||||
if (sess_id == NULL) {
|
||||
goto failed;
|
||||
|
||||
/* drop the oldest non-expired session and try once more */
|
||||
|
||||
ngx_ssl_expire_sessions(cache, shpool, 0);
|
||||
|
||||
sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
|
||||
|
||||
if (sess_id == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
|
@ -1693,8 +1737,18 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
|||
#else
|
||||
|
||||
id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
|
||||
|
||||
if (id == NULL) {
|
||||
goto failed;
|
||||
|
||||
/* drop the oldest non-expired session and try once more */
|
||||
|
||||
ngx_ssl_expire_sessions(cache, shpool, 0);
|
||||
|
||||
id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
|
||||
|
||||
if (id == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -120,6 +120,13 @@ ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
|
|||
#define ngx_ssl_get_server_conf(ssl_ctx) \
|
||||
SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_server_conf_index)
|
||||
|
||||
#define ngx_ssl_verify_error_optional(n) \
|
||||
(n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT \
|
||||
|| n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN \
|
||||
|| n == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY \
|
||||
|| n == X509_V_ERR_CERT_UNTRUSTED \
|
||||
|| n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)
|
||||
|
||||
|
||||
ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
|
||||
ngx_str_t *s);
|
||||
|
|
|
@ -946,8 +946,15 @@ ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->pos = b->start;
|
||||
b->last = b->start;
|
||||
if (p->buf_to_file && b->start == p->buf_to_file->start) {
|
||||
b->pos = p->buf_to_file->last;
|
||||
b->last = p->buf_to_file->last;
|
||||
|
||||
} else {
|
||||
b->pos = b->start;
|
||||
b->last = b->start;
|
||||
}
|
||||
|
||||
b->shadow = NULL;
|
||||
|
||||
cl->buf = b;
|
||||
|
|
|
@ -20,8 +20,8 @@ typedef struct {
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t realm;
|
||||
ngx_http_complex_value_t user_file;
|
||||
ngx_http_complex_value_t *realm;
|
||||
ngx_http_complex_value_t user_file;
|
||||
} ngx_http_auth_basic_loc_conf_t;
|
||||
|
||||
|
||||
|
@ -35,22 +35,19 @@ static void *ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf);
|
|||
static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf);
|
||||
static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data);
|
||||
static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_conf_post_handler_pt ngx_http_auth_basic_p = ngx_http_auth_basic;
|
||||
|
||||
static ngx_command_t ngx_http_auth_basic_commands[] = {
|
||||
|
||||
{ ngx_string("auth_basic"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
ngx_http_set_complex_value_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_auth_basic_loc_conf_t, realm),
|
||||
&ngx_http_auth_basic_p },
|
||||
NULL },
|
||||
|
||||
{ ngx_string("auth_basic_user_file"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
|
||||
|
@ -103,7 +100,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
ngx_fd_t fd;
|
||||
ngx_int_t rc;
|
||||
ngx_err_t err;
|
||||
ngx_str_t pwd, user_file;
|
||||
ngx_str_t pwd, realm, user_file;
|
||||
ngx_uint_t i, level, login, left, passwd;
|
||||
ngx_file_t file;
|
||||
ngx_http_auth_basic_ctx_t *ctx;
|
||||
|
@ -117,7 +114,15 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
|
||||
alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module);
|
||||
|
||||
if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) {
|
||||
if (alcf->realm == NULL || alcf->user_file.value.data == NULL) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (ngx_http_complex_value(r, alcf->realm, &realm) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (realm.len == 3 && ngx_strncmp(realm.data, "off", 3) == 0) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
@ -125,7 +130,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
|
||||
if (ctx) {
|
||||
return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd,
|
||||
&alcf->realm);
|
||||
&realm);
|
||||
}
|
||||
|
||||
rc = ngx_http_auth_basic_user(r);
|
||||
|
@ -135,7 +140,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"no user/password was provided for basic authentication");
|
||||
|
||||
return ngx_http_auth_basic_set_realm(r, &alcf->realm);
|
||||
return ngx_http_auth_basic_set_realm(r, &realm);
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
|
@ -233,7 +238,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
pwd.data = &buf[passwd];
|
||||
|
||||
return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd,
|
||||
&alcf->realm);
|
||||
&realm);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -271,14 +276,14 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
|
||||
ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
|
||||
|
||||
return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &alcf->realm);
|
||||
return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm);
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"user \"%V\" was not found in \"%V\"",
|
||||
&r->headers_in.user, &user_file);
|
||||
|
||||
return ngx_http_auth_basic_set_realm(r, &alcf->realm);
|
||||
return ngx_http_auth_basic_set_realm(r, &realm);
|
||||
}
|
||||
|
||||
|
||||
|
@ -344,14 +349,29 @@ ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r,
|
|||
static ngx_int_t
|
||||
ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
|
||||
{
|
||||
size_t len;
|
||||
u_char *basic, *p;
|
||||
|
||||
r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.www_authenticate == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
len = sizeof("Basic realm=\"\"") - 1 + realm->len;
|
||||
|
||||
basic = ngx_pnalloc(r->pool, len);
|
||||
if (basic == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
|
||||
p = ngx_cpymem(p, realm->data, realm->len);
|
||||
*p = '"';
|
||||
|
||||
r->headers_out.www_authenticate->hash = 1;
|
||||
ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate");
|
||||
r->headers_out.www_authenticate->value = *realm;
|
||||
r->headers_out.www_authenticate->value.data = basic;
|
||||
r->headers_out.www_authenticate->value.len = len;
|
||||
|
||||
return NGX_HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
@ -386,11 +406,11 @@ ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_http_auth_basic_loc_conf_t *prev = parent;
|
||||
ngx_http_auth_basic_loc_conf_t *conf = child;
|
||||
|
||||
if (conf->realm.data == NULL) {
|
||||
if (conf->realm == NULL) {
|
||||
conf->realm = prev->realm;
|
||||
}
|
||||
|
||||
if (conf->user_file.value.len == 0) {
|
||||
if (conf->user_file.value.data == NULL) {
|
||||
conf->user_file = prev->user_file;
|
||||
}
|
||||
|
||||
|
@ -417,37 +437,6 @@ ngx_http_auth_basic_init(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
ngx_str_t *realm = data;
|
||||
|
||||
size_t len;
|
||||
u_char *basic, *p;
|
||||
|
||||
if (ngx_strcmp(realm->data, "off") == 0) {
|
||||
ngx_str_set(realm, "");
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
len = sizeof("Basic realm=\"") - 1 + realm->len + 1;
|
||||
|
||||
basic = ngx_pnalloc(cf->pool, len);
|
||||
if (basic == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
|
||||
p = ngx_cpymem(p, realm->data, realm->len);
|
||||
*p = '"';
|
||||
|
||||
realm->len = len;
|
||||
realm->data = basic;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -456,7 +445,7 @@ ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_str_t *value;
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (alcf->user_file.value.len) {
|
||||
if (alcf->user_file.value.data) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
|
|
|
@ -489,8 +489,11 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, "</a>", sizeof("</a>") - 1);
|
||||
ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len);
|
||||
b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;
|
||||
|
||||
if (NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {
|
||||
ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len);
|
||||
b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;
|
||||
}
|
||||
}
|
||||
|
||||
*b->last++ = ' ';
|
||||
|
|
|
@ -209,6 +209,11 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
|
|||
ngx_ext_rename_file_t ext;
|
||||
ngx_http_dav_loc_conf_t *dlcf;
|
||||
|
||||
if (r->request_body == NULL || r->request_body->temp_file == NULL) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_map_uri_to_path(r, &path, &root, 0);
|
||||
|
||||
path.len--;
|
||||
|
|
|
@ -619,6 +619,7 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
|
|||
u->process_header = ngx_http_fastcgi_process_header;
|
||||
u->abort_request = ngx_http_fastcgi_abort_request;
|
||||
u->finalize_request = ngx_http_fastcgi_finalize_request;
|
||||
r->state = 0;
|
||||
|
||||
u->buffering = 1;
|
||||
|
||||
|
@ -1194,6 +1195,8 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
|
|||
f->fastcgi_stdout = 0;
|
||||
f->large_stderr = 0;
|
||||
|
||||
r->state = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1356,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
} else {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -1590,11 +1593,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
f->length -= u->buffer.pos - start;
|
||||
|
||||
if (f->length == 0) {
|
||||
if (f->padding) {
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
} else {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
}
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
}
|
||||
|
||||
if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
|
||||
|
@ -1619,6 +1618,9 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
part = ngx_array_push(f->split_parts);
|
||||
if (part == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
part->start = part_start;
|
||||
part->end = part_end;
|
||||
|
@ -1686,7 +1688,7 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
}
|
||||
|
||||
if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
|
||||
if (!flcf->keep_conn) {
|
||||
p->upstream_done = 1;
|
||||
|
@ -1699,23 +1701,40 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
}
|
||||
|
||||
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
p->upstream_done = 1;
|
||||
|
||||
if (flcf->keep_conn) {
|
||||
r->upstream->keepalive = 1;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||
"http fastcgi sent end request");
|
||||
|
||||
break;
|
||||
if (!flcf->keep_conn) {
|
||||
p->upstream_done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (f->state == ngx_http_fastcgi_st_padding) {
|
||||
|
||||
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
|
||||
|
||||
if (f->pos + f->padding < f->last) {
|
||||
p->upstream_done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->pos + f->padding == f->last) {
|
||||
p->upstream_done = 1;
|
||||
r->upstream->keepalive = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
f->padding -= f->last - f->pos;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->pos + f->padding < f->last) {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
f->pos += f->padding;
|
||||
|
@ -1767,17 +1786,27 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
"FastCGI sent in stderr: \"%*s\"",
|
||||
m + 1 - msg, msg);
|
||||
|
||||
if (f->pos == f->last) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
|
||||
|
||||
if (f->pos + f->length <= f->last) {
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
f->pos += f->length;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
f->length -= f->last - f->pos;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* f->type == NGX_HTTP_FASTCGI_STDOUT */
|
||||
|
||||
|
@ -1831,33 +1860,14 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||
"input buf #%d %p", b->num, b->pos);
|
||||
|
||||
if (f->pos + f->length < f->last) {
|
||||
|
||||
if (f->padding) {
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
} else {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
}
|
||||
|
||||
if (f->pos + f->length <= f->last) {
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
f->pos += f->length;
|
||||
b->last = f->pos;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f->pos + f->length == f->last) {
|
||||
|
||||
if (f->padding) {
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
} else {
|
||||
f->state = ngx_http_fastcgi_st_version;
|
||||
}
|
||||
|
||||
b->last = f->last;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
f->length -= f->last - f->pos;
|
||||
|
||||
b->last = f->last;
|
||||
|
@ -2989,7 +2999,7 @@ ngx_http_fastcgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (flcf->cache_key.value.len) {
|
||||
if (flcf->cache_key.value.data) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
|||
b->file_last = of.size;
|
||||
|
||||
b->in_file = b->file_last ? 1: 0;
|
||||
b->last_buf = 1;
|
||||
b->last_buf = (r == r->main) ? 1 : 0;
|
||||
b->last_in_chain = 1;
|
||||
|
||||
b->file->fd = of.fd;
|
||||
|
|
|
@ -17,6 +17,14 @@ typedef struct {
|
|||
} ngx_http_geo_range_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_radix_tree_t *tree;
|
||||
#if (NGX_HAVE_INET6)
|
||||
ngx_radix_tree_t *tree6;
|
||||
#endif
|
||||
} ngx_http_geo_trees_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_geo_range_t **low;
|
||||
ngx_http_variable_value_t *default_value;
|
||||
|
@ -35,6 +43,9 @@ typedef struct {
|
|||
ngx_str_t *net;
|
||||
ngx_http_geo_high_ranges_t high;
|
||||
ngx_radix_tree_t *tree;
|
||||
#if (NGX_HAVE_INET6)
|
||||
ngx_radix_tree_t *tree6;
|
||||
#endif
|
||||
ngx_rbtree_t rbtree;
|
||||
ngx_rbtree_node_t sentinel;
|
||||
ngx_array_t *proxies;
|
||||
|
@ -51,25 +62,27 @@ typedef struct {
|
|||
unsigned outside_entries:1;
|
||||
unsigned allow_binary_include:1;
|
||||
unsigned binary_include:1;
|
||||
unsigned proxy_recursive:1;
|
||||
} ngx_http_geo_conf_ctx_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ngx_radix_tree_t *tree;
|
||||
ngx_http_geo_trees_t trees;
|
||||
ngx_http_geo_high_ranges_t high;
|
||||
} u;
|
||||
|
||||
ngx_array_t *proxies;
|
||||
unsigned proxy_recursive:1;
|
||||
|
||||
ngx_int_t index;
|
||||
} ngx_http_geo_ctx_t;
|
||||
|
||||
|
||||
static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
|
||||
ngx_http_geo_ctx_t *ctx);
|
||||
static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r,
|
||||
ngx_http_geo_ctx_t *ctx);
|
||||
static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r,
|
||||
ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
|
||||
static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r,
|
||||
ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
|
||||
static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
|
||||
static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
||||
|
@ -80,6 +93,8 @@ static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf,
|
|||
ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
|
||||
static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
||||
ngx_str_t *value);
|
||||
static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
||||
ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net);
|
||||
static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
|
||||
ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
|
||||
static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
|
||||
|
@ -143,7 +158,7 @@ typedef struct {
|
|||
u_char GEORNG[6];
|
||||
u_char version;
|
||||
u_char ptr_size;
|
||||
uint32_t endianess;
|
||||
uint32_t endianness;
|
||||
uint32_t crc32;
|
||||
} ngx_http_geo_header_t;
|
||||
|
||||
|
@ -153,7 +168,7 @@ static ngx_http_geo_header_t ngx_http_geo_header = {
|
|||
};
|
||||
|
||||
|
||||
/* AF_INET only */
|
||||
/* geo range is AF_INET only */
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
|
@ -161,10 +176,56 @@ ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
{
|
||||
ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
|
||||
|
||||
in_addr_t inaddr;
|
||||
ngx_addr_t addr;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_variable_value_t *vv;
|
||||
#if (NGX_HAVE_INET6)
|
||||
u_char *p;
|
||||
struct in6_addr *inaddr6;
|
||||
#endif
|
||||
|
||||
vv = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(ctx->u.tree, ngx_http_geo_addr(r, ctx));
|
||||
if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) {
|
||||
vv = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (addr.sockaddr->sa_family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
|
||||
p = inaddr6->s6_addr;
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
|
||||
inaddr = p[12] << 24;
|
||||
inaddr += p[13] << 16;
|
||||
inaddr += p[14] << 8;
|
||||
inaddr += p[15];
|
||||
|
||||
vv = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
|
||||
|
||||
} else {
|
||||
vv = (ngx_http_variable_value_t *)
|
||||
ngx_radix128tree_find(ctx->u.trees.tree6, p);
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) addr.sockaddr;
|
||||
inaddr = ntohl(sin->sin_addr.s_addr);
|
||||
|
||||
vv = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
*v = *vv;
|
||||
|
||||
|
@ -181,25 +242,65 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
{
|
||||
ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
|
||||
|
||||
in_addr_t addr;
|
||||
in_addr_t inaddr;
|
||||
ngx_addr_t addr;
|
||||
ngx_uint_t n;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_geo_range_t *range;
|
||||
#if (NGX_HAVE_INET6)
|
||||
u_char *p;
|
||||
struct in6_addr *inaddr6;
|
||||
#endif
|
||||
|
||||
*v = *ctx->u.high.default_value;
|
||||
|
||||
addr = ngx_http_geo_addr(r, ctx);
|
||||
if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) {
|
||||
|
||||
range = ctx->u.high.low[addr >> 16];
|
||||
switch (addr.sockaddr->sa_family) {
|
||||
|
||||
if (range) {
|
||||
n = addr & 0xffff;
|
||||
do {
|
||||
if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end)
|
||||
{
|
||||
*v = *range->value;
|
||||
break;
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
|
||||
p = inaddr6->s6_addr;
|
||||
|
||||
inaddr = p[12] << 24;
|
||||
inaddr += p[13] << 16;
|
||||
inaddr += p[14] << 8;
|
||||
inaddr += p[15];
|
||||
|
||||
} else {
|
||||
inaddr = INADDR_NONE;
|
||||
}
|
||||
} while ((++range)->value);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) addr.sockaddr;
|
||||
inaddr = ntohl(sin->sin_addr.s_addr);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
inaddr = INADDR_NONE;
|
||||
}
|
||||
|
||||
if (ctx->u.high.low) {
|
||||
range = ctx->u.high.low[inaddr >> 16];
|
||||
|
||||
if (range) {
|
||||
n = inaddr & 0xffff;
|
||||
do {
|
||||
if (n >= (ngx_uint_t) range->start
|
||||
&& n <= (ngx_uint_t) range->end)
|
||||
{
|
||||
*v = *range->value;
|
||||
break;
|
||||
}
|
||||
} while ((++range)->value);
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -209,90 +310,43 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
}
|
||||
|
||||
|
||||
static in_addr_t
|
||||
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
|
||||
static ngx_int_t
|
||||
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
|
||||
ngx_addr_t *addr)
|
||||
{
|
||||
u_char *p, *ip;
|
||||
size_t len;
|
||||
in_addr_t addr;
|
||||
ngx_uint_t i, n;
|
||||
ngx_in_cidr_t *proxies;
|
||||
ngx_table_elt_t *xfwd;
|
||||
|
||||
addr = ngx_http_geo_real_addr(r, ctx);
|
||||
if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
if (xfwd == NULL || ctx->proxies == NULL) {
|
||||
return addr;
|
||||
if (xfwd != NULL && ctx->proxies != NULL) {
|
||||
(void) ngx_http_get_forwarded_addr(r, addr, xfwd->value.data,
|
||||
xfwd->value.len, ctx->proxies,
|
||||
ctx->proxy_recursive);
|
||||
}
|
||||
|
||||
proxies = ctx->proxies->elts;
|
||||
n = ctx->proxies->nelts;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((addr & proxies[i].mask) == proxies[i].addr) {
|
||||
|
||||
len = xfwd->value.len;
|
||||
ip = xfwd->value.data;
|
||||
|
||||
for (p = ip + len - 1; p > ip; p--) {
|
||||
if (*p == ' ' || *p == ',') {
|
||||
p++;
|
||||
len -= p - ip;
|
||||
ip = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ntohl(ngx_inet_addr(ip, len));
|
||||
}
|
||||
}
|
||||
|
||||
return addr;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static in_addr_t
|
||||
ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
|
||||
static ngx_int_t
|
||||
ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
|
||||
ngx_addr_t *addr)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_variable_value_t *v;
|
||||
#if (NGX_HAVE_INET6)
|
||||
u_char *p;
|
||||
in_addr_t addr;
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
if (ctx->index == -1) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo started: %V", &r->connection->addr_text);
|
||||
|
||||
switch (r->connection->sockaddr->sa_family) {
|
||||
addr->sockaddr = r->connection->sockaddr;
|
||||
addr->socklen = r->connection->socklen;
|
||||
/* addr->name = r->connection->addr_text; */
|
||||
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||
return ntohl(sin->sin_addr.s_addr);
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
p = sin6->sin6_addr.s6_addr;
|
||||
addr = p[12] << 24;
|
||||
addr += p[13] << 16;
|
||||
addr += p[14] << 8;
|
||||
addr += p[15];
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return INADDR_NONE;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v = ngx_http_get_flushed_variable(r, ctx->index);
|
||||
|
@ -301,13 +355,17 @@ ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo not found");
|
||||
|
||||
return 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo started: %v", v);
|
||||
|
||||
return ntohl(ngx_inet_addr(v->data, v->len));
|
||||
if (ngx_parse_addr(r->pool, addr, v->data, v->len) == NGX_OK) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -315,7 +373,6 @@ static char *
|
|||
ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *rv;
|
||||
void **p;
|
||||
size_t len;
|
||||
ngx_str_t *value, name;
|
||||
ngx_uint_t i;
|
||||
|
@ -325,6 +382,9 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_http_variable_t *var;
|
||||
ngx_http_geo_ctx_t *geo;
|
||||
ngx_http_geo_conf_ctx_t ctx;
|
||||
#if (NGX_HAVE_INET6)
|
||||
static struct in6_addr zero;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
|
@ -334,6 +394,13 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
name = value[1];
|
||||
|
||||
if (name.data[0] != '$') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid variable name \"%V\"", &name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
name.len--;
|
||||
name.data++;
|
||||
|
||||
|
@ -345,6 +412,13 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
name = value[2];
|
||||
|
||||
if (name.data[0] != '$') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid variable name \"%V\"", &name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
name.len--;
|
||||
name.data++;
|
||||
|
||||
|
@ -388,10 +462,11 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
*cf = save;
|
||||
|
||||
geo->proxies = ctx.proxies;
|
||||
geo->proxy_recursive = ctx.proxy_recursive;
|
||||
|
||||
if (ctx.high.low) {
|
||||
if (ctx.ranges) {
|
||||
|
||||
if (!ctx.binary_include) {
|
||||
if (ctx.high.low && !ctx.binary_include) {
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
a = (ngx_array_t *) ctx.high.low[i];
|
||||
|
||||
|
@ -406,8 +481,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
p = (void **) ngx_cpymem(ctx.high.low[i], a->elts, len);
|
||||
*p = NULL;
|
||||
ngx_memcpy(ctx.high.low[i], a->elts, len);
|
||||
ctx.high.low[i][a->nelts].value = NULL;
|
||||
ctx.data_size += len + sizeof(void *);
|
||||
}
|
||||
|
||||
|
@ -420,15 +495,15 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
}
|
||||
|
||||
if (ctx.high.default_value == NULL) {
|
||||
ctx.high.default_value = &ngx_http_variable_null_value;
|
||||
}
|
||||
|
||||
geo->u.high = ctx.high;
|
||||
|
||||
var->get_handler = ngx_http_geo_range_variable;
|
||||
var->data = (uintptr_t) geo;
|
||||
|
||||
if (ctx.high.default_value == NULL) {
|
||||
ctx.high.default_value = &ngx_http_variable_null_value;
|
||||
}
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
|
@ -440,7 +515,18 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
}
|
||||
|
||||
geo->u.tree = ctx.tree;
|
||||
geo->u.trees.tree = ctx.tree;
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
if (ctx.tree6 == NULL) {
|
||||
ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
|
||||
if (ctx.tree6 == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
geo->u.trees.tree6 = ctx.tree6;
|
||||
#endif
|
||||
|
||||
var->get_handler = ngx_http_geo_cidr_variable;
|
||||
var->data = (uintptr_t) geo;
|
||||
|
@ -448,16 +534,23 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (ngx_radix32tree_insert(ctx.tree, 0, 0,
|
||||
(uintptr_t) &ngx_http_variable_null_value)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/* NGX_BUSY is okay (default was set explicitly) */
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr,
|
||||
(uintptr_t) &ngx_http_variable_null_value)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -480,7 +573,12 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
|
||||
if (ngx_strcmp(value[0].data, "ranges") == 0) {
|
||||
|
||||
if (ctx->tree) {
|
||||
if (ctx->tree
|
||||
#if (NGX_HAVE_INET6)
|
||||
|| ctx->tree6
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the \"ranges\" directive must be "
|
||||
"the first directive inside \"geo\" block");
|
||||
|
@ -493,6 +591,12 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
|
||||
goto done;
|
||||
}
|
||||
|
||||
else if (ngx_strcmp(value[0].data, "proxy_recursive") == 0) {
|
||||
ctx->proxy_recursive = 1;
|
||||
rv = NGX_CONF_OK;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (cf->args->nelts != 2) {
|
||||
|
@ -912,11 +1016,10 @@ static char *
|
|||
ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
ngx_int_t rc, del;
|
||||
ngx_str_t *net;
|
||||
ngx_uint_t i;
|
||||
ngx_cidr_t cidr;
|
||||
ngx_http_variable_value_t *val, *old;
|
||||
char *rv;
|
||||
ngx_int_t rc, del;
|
||||
ngx_str_t *net;
|
||||
ngx_cidr_t cidr;
|
||||
|
||||
if (ctx->tree == NULL) {
|
||||
ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
|
||||
|
@ -925,47 +1028,108 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[0].data, "default") == 0) {
|
||||
cidr.u.in.addr = 0;
|
||||
cidr.u.in.mask = 0;
|
||||
net = &value[0];
|
||||
|
||||
} else {
|
||||
if (ngx_strcmp(value[0].data, "delete") == 0) {
|
||||
net = &value[1];
|
||||
del = 1;
|
||||
|
||||
} else {
|
||||
net = &value[0];
|
||||
del = 0;
|
||||
}
|
||||
|
||||
if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
|
||||
#if (NGX_HAVE_INET6)
|
||||
if (ctx->tree6 == NULL) {
|
||||
ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1);
|
||||
if (ctx->tree6 == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (del) {
|
||||
if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
|
||||
cidr.u.in.mask)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"no network \"%V\" to delete", net);
|
||||
}
|
||||
if (ngx_strcmp(value[0].data, "default") == 0) {
|
||||
cidr.family = AF_INET;
|
||||
cidr.u.in.addr = 0;
|
||||
cidr.u.in.mask = 0;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
|
||||
|
||||
if (rv != NGX_CONF_OK) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
cidr.family = AF_INET6;
|
||||
ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t));
|
||||
|
||||
rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
|
||||
|
||||
if (rv != NGX_CONF_OK) {
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
val = ngx_http_geo_value(cf, ctx, &value[1]);
|
||||
if (ngx_strcmp(value[0].data, "delete") == 0) {
|
||||
net = &value[1];
|
||||
del = 1;
|
||||
|
||||
} else {
|
||||
net = &value[0];
|
||||
del = 0;
|
||||
}
|
||||
|
||||
if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (cidr.family == AF_INET) {
|
||||
cidr.u.in.addr = ntohl(cidr.u.in.addr);
|
||||
cidr.u.in.mask = ntohl(cidr.u.in.mask);
|
||||
}
|
||||
|
||||
if (del) {
|
||||
switch (cidr.family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
rc = ngx_radix128tree_delete(ctx->tree6,
|
||||
cidr.u.in6.addr.s6_addr,
|
||||
cidr.u.in6.mask.s6_addr);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
|
||||
cidr.u.in.mask);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"no network \"%V\" to delete", net);
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
||||
ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_http_variable_value_t *val, *old;
|
||||
|
||||
val = ngx_http_geo_value(cf, ctx, value);
|
||||
|
||||
if (val == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 2; i; i--) {
|
||||
rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
|
||||
(uintptr_t) val);
|
||||
switch (cidr->family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
|
||||
cidr->u.in6.mask.s6_addr,
|
||||
(uintptr_t) val);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -977,18 +1141,66 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||
/* rc == NGX_BUSY */
|
||||
|
||||
old = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
|
||||
ngx_radix128tree_find(ctx->tree6,
|
||||
cidr->u.in6.addr.s6_addr);
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
|
||||
net, val, old);
|
||||
"duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
|
||||
net, val, old);
|
||||
|
||||
rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
|
||||
rc = ngx_radix128tree_delete(ctx->tree6,
|
||||
cidr->u.in6.addr.s6_addr,
|
||||
cidr->u.in6.mask.s6_addr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
|
||||
cidr->u.in6.mask.s6_addr,
|
||||
(uintptr_t) val);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
|
||||
cidr->u.in.mask, (uintptr_t) val);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/* rc == NGX_BUSY */
|
||||
|
||||
old = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(ctx->tree, cidr->u.in.addr);
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
|
||||
net, val, old);
|
||||
|
||||
rc = ngx_radix32tree_delete(ctx->tree,
|
||||
cidr->u.in.addr, cidr->u.in.mask);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
|
||||
cidr->u.in.mask, (uintptr_t) val);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
|
@ -1052,10 +1264,10 @@ static char *
|
|||
ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
||||
ngx_cidr_t *cidr)
|
||||
{
|
||||
ngx_in_cidr_t *c;
|
||||
ngx_cidr_t *c;
|
||||
|
||||
if (ctx->proxies == NULL) {
|
||||
ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t));
|
||||
ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_cidr_t));
|
||||
if (ctx->proxies == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -1066,8 +1278,7 @@ ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
c->addr = cidr->u.in.addr;
|
||||
c->mask = cidr->u.in.mask;
|
||||
*c = *cidr;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -1079,6 +1290,7 @@ ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
|
|||
ngx_int_t rc;
|
||||
|
||||
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
|
||||
cidr->family = AF_INET;
|
||||
cidr->u.in.addr = 0xffffffff;
|
||||
cidr->u.in.mask = 0xffffffff;
|
||||
|
||||
|
@ -1092,19 +1304,11 @@ ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (cidr->family != AF_INET) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless", net);
|
||||
}
|
||||
|
||||
cidr->u.in.addr = ntohl(cidr->u.in.addr);
|
||||
cidr->u.in.mask = ntohl(cidr->u.in.mask);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,20 +13,56 @@
|
|||
#include <GeoIPCity.h>
|
||||
|
||||
|
||||
#define NGX_GEOIP_COUNTRY_CODE 0
|
||||
#define NGX_GEOIP_COUNTRY_CODE3 1
|
||||
#define NGX_GEOIP_COUNTRY_NAME 2
|
||||
|
||||
|
||||
typedef struct {
|
||||
GeoIP *country;
|
||||
GeoIP *org;
|
||||
GeoIP *city;
|
||||
GeoIP *country;
|
||||
GeoIP *org;
|
||||
GeoIP *city;
|
||||
ngx_array_t *proxies; /* array of ngx_cidr_t */
|
||||
ngx_flag_t proxy_recursive;
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
unsigned country_v6:1;
|
||||
unsigned org_v6:1;
|
||||
unsigned city_v6:1;
|
||||
#endif
|
||||
} ngx_http_geoip_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t *name;
|
||||
uintptr_t data;
|
||||
ngx_str_t *name;
|
||||
uintptr_t data;
|
||||
} ngx_http_geoip_var_t;
|
||||
|
||||
|
||||
typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
|
||||
typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *,
|
||||
u_long addr);
|
||||
|
||||
|
||||
ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = {
|
||||
GeoIP_country_code_by_ipnum,
|
||||
GeoIP_country_code3_by_ipnum,
|
||||
GeoIP_country_name_by_ipnum,
|
||||
};
|
||||
|
||||
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
|
||||
typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *,
|
||||
geoipv6_t addr);
|
||||
|
||||
|
||||
ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = {
|
||||
GeoIP_country_code_by_ipnum_v6,
|
||||
GeoIP_country_code3_by_ipnum_v6,
|
||||
GeoIP_country_name_by_ipnum_v6,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
@ -44,12 +80,17 @@ static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r);
|
|||
|
||||
static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
|
||||
static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf);
|
||||
static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static ngx_int_t ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
|
||||
ngx_cidr_t *cidr);
|
||||
static void ngx_http_geoip_cleanup(void *data);
|
||||
|
||||
|
||||
|
@ -76,6 +117,20 @@ static ngx_command_t ngx_http_geoip_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("geoip_proxy"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_geoip_proxy,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("geoip_proxy_recursive"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
offsetof(ngx_http_geoip_conf_t, proxy_recursive),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
@ -85,7 +140,7 @@ static ngx_http_module_t ngx_http_geoip_module_ctx = {
|
|||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_geoip_create_conf, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
ngx_http_geoip_init_conf, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
@ -115,19 +170,19 @@ static ngx_http_variable_t ngx_http_geoip_vars[] = {
|
|||
|
||||
{ ngx_string("geoip_country_code"), NULL,
|
||||
ngx_http_geoip_country_variable,
|
||||
(uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 },
|
||||
NGX_GEOIP_COUNTRY_CODE, 0, 0 },
|
||||
|
||||
{ ngx_string("geoip_country_code3"), NULL,
|
||||
ngx_http_geoip_country_variable,
|
||||
(uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
|
||||
NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
|
||||
|
||||
{ ngx_string("geoip_country_name"), NULL,
|
||||
ngx_http_geoip_country_variable,
|
||||
(uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },
|
||||
NGX_GEOIP_COUNTRY_NAME, 0, 0 },
|
||||
|
||||
{ ngx_string("geoip_org"), NULL,
|
||||
ngx_http_geoip_org_variable,
|
||||
(uintptr_t) GeoIP_name_by_ipnum, 0, 0 },
|
||||
0, 0, 0 },
|
||||
|
||||
{ ngx_string("geoip_city_continent_code"), NULL,
|
||||
ngx_http_geoip_city_variable,
|
||||
|
@ -182,49 +237,118 @@ static ngx_http_variable_t ngx_http_geoip_vars[] = {
|
|||
|
||||
|
||||
static u_long
|
||||
ngx_http_geoip_addr(ngx_http_request_t *r)
|
||||
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
u_char *p;
|
||||
u_long addr;
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
ngx_addr_t addr;
|
||||
ngx_table_elt_t *xfwd;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
switch (r->connection->sockaddr->sa_family) {
|
||||
addr.sockaddr = r->connection->sockaddr;
|
||||
addr.socklen = r->connection->socklen;
|
||||
/* addr.name = r->connection->addr_text; */
|
||||
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||
return ntohl(sin->sin_addr.s_addr);
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
p = sin6->sin6_addr.s6_addr;
|
||||
addr = p[12] << 24;
|
||||
addr += p[13] << 16;
|
||||
addr += p[14] << 8;
|
||||
addr += p[15];
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (xfwd != NULL && gcf->proxies != NULL) {
|
||||
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
|
||||
xfwd->value.len, gcf->proxies,
|
||||
gcf->proxy_recursive);
|
||||
}
|
||||
|
||||
return INADDR_NONE;
|
||||
#if (NGX_HAVE_INET6)
|
||||
|
||||
if (addr.sockaddr->sa_family == AF_INET6) {
|
||||
u_char *p;
|
||||
in_addr_t inaddr;
|
||||
struct in6_addr *inaddr6;
|
||||
|
||||
inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
|
||||
p = inaddr6->s6_addr;
|
||||
|
||||
inaddr = p[12] << 24;
|
||||
inaddr += p[13] << 16;
|
||||
inaddr += p[14] << 8;
|
||||
inaddr += p[15];
|
||||
|
||||
return inaddr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (addr.sockaddr->sa_family != AF_INET) {
|
||||
return INADDR_NONE;
|
||||
}
|
||||
|
||||
sin = (struct sockaddr_in *) addr.sockaddr;
|
||||
return ntohl(sin->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
|
||||
static geoipv6_t
|
||||
ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
|
||||
{
|
||||
ngx_addr_t addr;
|
||||
ngx_table_elt_t *xfwd;
|
||||
in_addr_t addr4;
|
||||
struct in6_addr addr6;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
addr.sockaddr = r->connection->sockaddr;
|
||||
addr.socklen = r->connection->socklen;
|
||||
/* addr.name = r->connection->addr_text; */
|
||||
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
if (xfwd != NULL && gcf->proxies != NULL) {
|
||||
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
|
||||
xfwd->value.len, gcf->proxies,
|
||||
gcf->proxy_recursive);
|
||||
}
|
||||
|
||||
switch (addr.sockaddr->sa_family) {
|
||||
|
||||
case AF_INET:
|
||||
/* Produce IPv4-mapped IPv6 address. */
|
||||
sin = (struct sockaddr_in *) addr.sockaddr;
|
||||
addr4 = ntohl(sin->sin_addr.s_addr);
|
||||
|
||||
ngx_memzero(&addr6, sizeof(struct in6_addr));
|
||||
addr6.s6_addr[10] = 0xff;
|
||||
addr6.s6_addr[11] = 0xff;
|
||||
addr6.s6_addr[12] = addr4 >> 24;
|
||||
addr6.s6_addr[13] = addr4 >> 16;
|
||||
addr6.s6_addr[14] = addr4 >> 8;
|
||||
addr6.s6_addr[15] = addr4;
|
||||
return addr6;
|
||||
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) addr.sockaddr;
|
||||
return sin6->sin6_addr;
|
||||
|
||||
default:
|
||||
return in6addr_any;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_geoip_country_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_geoip_variable_handler_pt handler =
|
||||
(ngx_http_geoip_variable_handler_pt) data;
|
||||
ngx_http_geoip_variable_handler_pt handler =
|
||||
ngx_http_geoip_country_functions[data];
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
ngx_http_geoip_variable_handler_v6_pt handler_v6 =
|
||||
ngx_http_geoip_country_v6_functions[data];
|
||||
#endif
|
||||
|
||||
const char *val;
|
||||
ngx_http_geoip_conf_t *gcf;
|
||||
|
@ -235,7 +359,13 @@ ngx_http_geoip_country_variable(ngx_http_request_t *r,
|
|||
goto not_found;
|
||||
}
|
||||
|
||||
val = handler(gcf->country, ngx_http_geoip_addr(r));
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
val = gcf->country_v6
|
||||
? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf))
|
||||
: handler(gcf->country, ngx_http_geoip_addr(r, gcf));
|
||||
#else
|
||||
val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
|
||||
#endif
|
||||
|
||||
if (val == NULL) {
|
||||
goto not_found;
|
||||
|
@ -261,10 +391,8 @@ static ngx_int_t
|
|||
ngx_http_geoip_org_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_geoip_variable_handler_pt handler =
|
||||
(ngx_http_geoip_variable_handler_pt) data;
|
||||
|
||||
const char *val;
|
||||
size_t len;
|
||||
char *val;
|
||||
ngx_http_geoip_conf_t *gcf;
|
||||
|
||||
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
|
||||
|
@ -273,17 +401,35 @@ ngx_http_geoip_org_variable(ngx_http_request_t *r,
|
|||
goto not_found;
|
||||
}
|
||||
|
||||
val = handler(gcf->org, ngx_http_geoip_addr(r));
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
val = gcf->org_v6
|
||||
? GeoIP_name_by_ipnum_v6(gcf->org,
|
||||
ngx_http_geoip_addr_v6(r, gcf))
|
||||
: GeoIP_name_by_ipnum(gcf->org,
|
||||
ngx_http_geoip_addr(r, gcf));
|
||||
#else
|
||||
val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf));
|
||||
#endif
|
||||
|
||||
if (val == NULL) {
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
v->len = ngx_strlen(val);
|
||||
len = ngx_strlen(val);
|
||||
v->data = ngx_pnalloc(r->pool, len);
|
||||
if (v->data == NULL) {
|
||||
ngx_free(val);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(v->data, val, len);
|
||||
|
||||
v->len = len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = (u_char *) val;
|
||||
|
||||
ngx_free(val);
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
|
@ -453,7 +599,15 @@ ngx_http_geoip_get_city_record(ngx_http_request_t *r)
|
|||
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
|
||||
|
||||
if (gcf->city) {
|
||||
return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r));
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
return gcf->city_v6
|
||||
? GeoIP_record_by_ipnum_v6(gcf->city,
|
||||
ngx_http_geoip_addr_v6(r, gcf))
|
||||
: GeoIP_record_by_ipnum(gcf->city,
|
||||
ngx_http_geoip_addr(r, gcf));
|
||||
#else
|
||||
return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -490,6 +644,8 @@ ngx_http_geoip_create_conf(ngx_conf_t *cf)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
conf->proxy_recursive = NGX_CONF_UNSET;
|
||||
|
||||
cln = ngx_pool_cleanup_add(cf->pool, 0);
|
||||
if (cln == NULL) {
|
||||
return NULL;
|
||||
|
@ -502,6 +658,17 @@ ngx_http_geoip_create_conf(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf)
|
||||
{
|
||||
ngx_http_geoip_conf_t *gcf = conf;
|
||||
|
||||
ngx_conf_init_value(gcf->proxy_recursive, 0);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -538,11 +705,16 @@ ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
switch (gcf->country->databaseType) {
|
||||
|
||||
case GEOIP_COUNTRY_EDITION:
|
||||
case GEOIP_PROXY_EDITION:
|
||||
case GEOIP_NETSPEED_EDITION:
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
case GEOIP_COUNTRY_EDITION_V6:
|
||||
|
||||
gcf->country_v6 = 1;
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid GeoIP database \"%V\" type:%d",
|
||||
|
@ -594,6 +766,16 @@ ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
case GEOIP_ISP_EDITION_V6:
|
||||
case GEOIP_ORG_EDITION_V6:
|
||||
case GEOIP_DOMAIN_EDITION_V6:
|
||||
case GEOIP_ASNUM_EDITION_V6:
|
||||
|
||||
gcf->org_v6 = 1;
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid GeoIP database \"%V\" type:%d",
|
||||
|
@ -643,6 +825,14 @@ ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
#if (NGX_HAVE_GEOIP_V6)
|
||||
case GEOIP_CITY_EDITION_REV0_V6:
|
||||
case GEOIP_CITY_EDITION_REV1_V6:
|
||||
|
||||
gcf->city_v6 = 1;
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid GeoIP City database \"%V\" type:%d",
|
||||
|
@ -652,6 +842,66 @@ ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_geoip_conf_t *gcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_cidr_t cidr, *c;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (gcf->proxies == NULL) {
|
||||
gcf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t));
|
||||
if (gcf->proxies == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
c = ngx_array_push(gcf->proxies);
|
||||
if (c == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*c = cidr;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
|
||||
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
|
||||
cidr->family = AF_INET;
|
||||
cidr->u.in.addr = 0xffffffff;
|
||||
cidr->u.in.mask = 0xffffffff;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
rc = ngx_ptocidr(net, cidr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless", net);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_geoip_cleanup(void *data)
|
||||
{
|
||||
|
|
|
@ -320,7 +320,7 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
|
||||
|
||||
if (ctx == NULL || ctx->done) {
|
||||
if (ctx == NULL || ctx->done || r->header_only) {
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
|
@ -497,6 +497,10 @@ ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
|||
wbits--;
|
||||
memlevel--;
|
||||
}
|
||||
|
||||
if (memlevel < 1) {
|
||||
memlevel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->wbits = wbits;
|
||||
|
|
|
@ -245,7 +245,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
|
|||
b->file_last = of.size;
|
||||
|
||||
b->in_file = b->file_last ? 1 : 0;
|
||||
b->last_buf = 1;
|
||||
b->last_buf = (r == r->main) ? 1 : 0;
|
||||
b->last_in_chain = 1;
|
||||
|
||||
b->file->fd = of.fd;
|
||||
|
|
|
@ -149,6 +149,7 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
|||
if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
|
||||
|| r != r->main
|
||||
|| (r->headers_out.status != NGX_HTTP_OK
|
||||
&& r->headers_out.status != NGX_HTTP_CREATED
|
||||
&& r->headers_out.status != NGX_HTTP_NO_CONTENT
|
||||
&& r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
|
||||
&& r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
|
||||
|
|
|
@ -1169,10 +1169,22 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->width = 0;
|
||||
* conf->height = 0;
|
||||
* conf->angle = 0;
|
||||
* conf->wcv = NULL;
|
||||
* conf->hcv = NULL;
|
||||
* conf->acv = NULL;
|
||||
* conf->jqcv = NULL;
|
||||
* conf->shcv = NULL;
|
||||
*/
|
||||
|
||||
conf->filter = NGX_CONF_UNSET_UINT;
|
||||
conf->jpeg_quality = NGX_CONF_UNSET_UINT;
|
||||
conf->sharpen = NGX_CONF_UNSET_UINT;
|
||||
conf->angle = NGX_CONF_UNSET_UINT;
|
||||
conf->transparency = NGX_CONF_UNSET;
|
||||
conf->buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
|
||||
|
@ -1195,27 +1207,29 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
conf->filter = prev->filter;
|
||||
conf->width = prev->width;
|
||||
conf->height = prev->height;
|
||||
conf->angle = prev->angle;
|
||||
conf->wcv = prev->wcv;
|
||||
conf->hcv = prev->hcv;
|
||||
conf->acv = prev->acv;
|
||||
}
|
||||
}
|
||||
|
||||
/* 75 is libjpeg default quality */
|
||||
ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
|
||||
if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) {
|
||||
|
||||
if (conf->jqcv == NULL) {
|
||||
conf->jqcv = prev->jqcv;
|
||||
/* 75 is libjpeg default quality */
|
||||
ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
|
||||
|
||||
if (conf->jqcv == NULL) {
|
||||
conf->jqcv = prev->jqcv;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
|
||||
if (conf->sharpen == NGX_CONF_UNSET_UINT) {
|
||||
ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
|
||||
|
||||
if (conf->shcv == NULL) {
|
||||
conf->shcv = prev->shcv;
|
||||
}
|
||||
|
||||
ngx_conf_merge_uint_value(conf->angle, prev->angle, 0);
|
||||
if (conf->acv == NULL) {
|
||||
conf->acv = prev->acv;
|
||||
if (conf->shcv == NULL) {
|
||||
conf->shcv = prev->shcv;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
|
||||
|
|
|
@ -85,12 +85,12 @@ ngx_module_t ngx_http_index_module = {
|
|||
|
||||
/*
|
||||
* Try to open/test the first index file before the test of directory
|
||||
* existence because valid requests should be much more than invalid ones.
|
||||
* If the file open()/stat() would fail, then the directory stat() should
|
||||
* be more quickly because some data is already cached in the kernel.
|
||||
* existence because valid requests should prevail over invalid ones.
|
||||
* If open()/stat() of a file will fail then stat() of a directory
|
||||
* should be faster because kernel may have already cached some data.
|
||||
* Besides, Win32 may return ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) at once.
|
||||
* Unix has ENOTDIR error, however, it's less helpful than Win32's one:
|
||||
* it only indicates that path contains an usual file in place of directory.
|
||||
* Unix has ENOTDIR error; however, it's less helpful than Win32's one:
|
||||
* it only indicates that path points to a regular file, not a directory.
|
||||
*/
|
||||
|
||||
static ngx_int_t
|
||||
|
|
|
@ -238,7 +238,7 @@ ngx_http_limit_conn_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"limit zone: %08XD %d", node->key, lc->conn);
|
||||
"limit conn: %08XD %d", node->key, lc->conn);
|
||||
|
||||
ngx_shmtx_unlock(&shpool->mutex);
|
||||
|
||||
|
@ -358,7 +358,7 @@ ngx_http_limit_conn_cleanup(void *data)
|
|||
ngx_shmtx_lock(&shpool->mutex);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lccln->shm_zone->shm.log, 0,
|
||||
"limit zone cleanup: %08XD %d", node->key, lc->conn);
|
||||
"limit conn cleanup: %08XD %d", node->key, lc->conn);
|
||||
|
||||
lc->conn--;
|
||||
|
||||
|
@ -721,6 +721,10 @@ ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
limit = ngx_array_push(&lccf->limits);
|
||||
if (limit == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
limit->conn = n;
|
||||
limit->shm_zone = shm_zone;
|
||||
|
||||
|
|
|
@ -444,17 +444,17 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash,
|
|||
|
||||
node->key = hash;
|
||||
|
||||
ngx_rbtree_insert(&ctx->sh->rbtree, node);
|
||||
|
||||
lr = (ngx_http_limit_req_node_t *) &node->color;
|
||||
|
||||
ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
|
||||
|
||||
lr->len = (u_char) len;
|
||||
lr->excess = 0;
|
||||
|
||||
ngx_memcpy(lr->data, data, len);
|
||||
|
||||
ngx_rbtree_insert(&ctx->sh->rbtree, node);
|
||||
|
||||
ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
|
||||
|
||||
if (account) {
|
||||
lr->last = now;
|
||||
lr->count = 0;
|
||||
|
@ -937,6 +937,9 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
limit = ngx_array_push(&lrcf->limits);
|
||||
if (limit == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
limit->shm_zone = shm_zone;
|
||||
limit->burst = burst * 1000;
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
#if (NGX_ZLIB)
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ngx_http_log_op_s ngx_http_log_op_t;
|
||||
|
||||
|
@ -40,6 +44,17 @@ typedef struct {
|
|||
} ngx_http_log_main_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_char *start;
|
||||
u_char *pos;
|
||||
u_char *last;
|
||||
|
||||
ngx_event_t *event;
|
||||
ngx_msec_t flush;
|
||||
ngx_int_t gzip;
|
||||
} ngx_http_log_buf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *lengths;
|
||||
ngx_array_t *values;
|
||||
|
@ -78,10 +93,17 @@ static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
|
|||
static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
|
||||
ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len);
|
||||
|
||||
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_connection_requests(ngx_http_request_t *r,
|
||||
u_char *buf, ngx_http_log_op_t *op);
|
||||
#if (NGX_ZLIB)
|
||||
static ssize_t ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len,
|
||||
ngx_int_t level, ngx_log_t *log);
|
||||
|
||||
static void *ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size);
|
||||
static void ngx_http_log_gzip_free(void *opaque, void *address);
|
||||
#endif
|
||||
|
||||
static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log);
|
||||
static void ngx_http_log_flush_handler(ngx_event_t *ev);
|
||||
|
||||
static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf,
|
||||
|
@ -136,7 +158,7 @@ static ngx_command_t ngx_http_log_commands[] = {
|
|||
|
||||
{ ngx_string("access_log"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,
|
||||
|NGX_HTTP_LMT_CONF|NGX_CONF_1MORE,
|
||||
ngx_http_log_set_log,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
|
@ -194,9 +216,6 @@ static ngx_str_t ngx_http_combined_fmt =
|
|||
|
||||
|
||||
static ngx_http_log_var_t ngx_http_log_vars[] = {
|
||||
{ ngx_string("connection"), NGX_ATOMIC_T_LEN, ngx_http_log_connection },
|
||||
{ ngx_string("connection_requests"), NGX_INT_T_LEN,
|
||||
ngx_http_log_connection_requests },
|
||||
{ ngx_string("pipe"), 1, ngx_http_log_pipe },
|
||||
{ ngx_string("time_local"), sizeof("28/Sep/1970:12:00:00 +0600") - 1,
|
||||
ngx_http_log_time },
|
||||
|
@ -205,12 +224,10 @@ static ngx_http_log_var_t ngx_http_log_vars[] = {
|
|||
{ ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec },
|
||||
{ ngx_string("request_time"), NGX_TIME_T_LEN + 4,
|
||||
ngx_http_log_request_time },
|
||||
{ ngx_string("status"), 3, ngx_http_log_status },
|
||||
{ ngx_string("status"), NGX_INT_T_LEN, ngx_http_log_status },
|
||||
{ ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent },
|
||||
{ ngx_string("body_bytes_sent"), NGX_OFF_T_LEN,
|
||||
ngx_http_log_body_bytes_sent },
|
||||
{ ngx_string("apache_bytes_sent"), NGX_OFF_T_LEN,
|
||||
ngx_http_log_body_bytes_sent },
|
||||
{ ngx_string("request_length"), NGX_SIZE_T_LEN,
|
||||
ngx_http_log_request_length },
|
||||
|
||||
|
@ -218,15 +235,15 @@ static ngx_http_log_var_t ngx_http_log_vars[] = {
|
|||
};
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_http_log_handler(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *line, *p;
|
||||
size_t len;
|
||||
ngx_uint_t i, l;
|
||||
ngx_http_log_t *log;
|
||||
ngx_open_file_t *file;
|
||||
ngx_http_log_op_t *op;
|
||||
ngx_http_log_buf_t *buffer;
|
||||
ngx_http_log_loc_conf_t *lcf;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -267,21 +284,25 @@ ngx_http_log_handler(ngx_http_request_t *r)
|
|||
|
||||
len += NGX_LINEFEED_SIZE;
|
||||
|
||||
file = log[l].file;
|
||||
buffer = log[l].file ? log[l].file->data : NULL;
|
||||
|
||||
if (file && file->buffer) {
|
||||
if (buffer) {
|
||||
|
||||
if (len > (size_t) (file->last - file->pos)) {
|
||||
if (len > (size_t) (buffer->last - buffer->pos)) {
|
||||
|
||||
ngx_http_log_write(r, &log[l], file->buffer,
|
||||
file->pos - file->buffer);
|
||||
ngx_http_log_write(r, &log[l], buffer->start,
|
||||
buffer->pos - buffer->start);
|
||||
|
||||
file->pos = file->buffer;
|
||||
buffer->pos = buffer->start;
|
||||
}
|
||||
|
||||
if (len <= (size_t) (file->last - file->pos)) {
|
||||
if (len <= (size_t) (buffer->last - buffer->pos)) {
|
||||
|
||||
p = file->pos;
|
||||
p = buffer->pos;
|
||||
|
||||
if (buffer->event && p == buffer->start) {
|
||||
ngx_add_timer(buffer->event, buffer->flush);
|
||||
}
|
||||
|
||||
for (i = 0; i < log[l].format->ops->nelts; i++) {
|
||||
p = op[i].run(r, p, &op[i]);
|
||||
|
@ -289,10 +310,14 @@ ngx_http_log_handler(ngx_http_request_t *r)
|
|||
|
||||
ngx_linefeed(p);
|
||||
|
||||
file->pos = p;
|
||||
buffer->pos = p;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buffer->event && buffer->event->timer_set) {
|
||||
ngx_del_timer(buffer->event);
|
||||
}
|
||||
}
|
||||
|
||||
line = ngx_pnalloc(r->pool, len);
|
||||
|
@ -319,14 +344,29 @@ static void
|
|||
ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
|
||||
size_t len)
|
||||
{
|
||||
u_char *name;
|
||||
time_t now;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
u_char *name;
|
||||
time_t now;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
#if (NGX_ZLIB)
|
||||
ngx_http_log_buf_t *buffer;
|
||||
#endif
|
||||
|
||||
if (log->script == NULL) {
|
||||
name = log->file->name.data;
|
||||
|
||||
#if (NGX_ZLIB)
|
||||
buffer = log->file->data;
|
||||
|
||||
if (buffer && buffer->gzip) {
|
||||
n = ngx_http_log_gzip(log->file->fd, buf, len, buffer->gzip,
|
||||
r->connection->log);
|
||||
} else {
|
||||
n = ngx_write_fd(log->file->fd, buf, len);
|
||||
}
|
||||
#else
|
||||
n = ngx_write_fd(log->file->fd, buf, len);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
name = NULL;
|
||||
|
@ -474,6 +514,194 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
|
|||
}
|
||||
|
||||
|
||||
#if (NGX_ZLIB)
|
||||
|
||||
static ssize_t
|
||||
ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level,
|
||||
ngx_log_t *log)
|
||||
{
|
||||
int rc, wbits, memlevel;
|
||||
u_char *out;
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
z_stream zstream;
|
||||
ngx_err_t err;
|
||||
ngx_pool_t *pool;
|
||||
|
||||
wbits = MAX_WBITS;
|
||||
memlevel = MAX_MEM_LEVEL - 1;
|
||||
|
||||
while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) {
|
||||
wbits--;
|
||||
memlevel--;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a formula from deflateBound() for conservative upper bound of
|
||||
* compressed data plus 18 bytes of gzip wrapper.
|
||||
*/
|
||||
|
||||
size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18;
|
||||
|
||||
ngx_memzero(&zstream, sizeof(z_stream));
|
||||
|
||||
pool = ngx_create_pool(256, log);
|
||||
if (pool == NULL) {
|
||||
/* simulate successful logging */
|
||||
return len;
|
||||
}
|
||||
|
||||
pool->log = log;
|
||||
|
||||
zstream.zalloc = ngx_http_log_gzip_alloc;
|
||||
zstream.zfree = ngx_http_log_gzip_free;
|
||||
zstream.opaque = pool;
|
||||
|
||||
out = ngx_pnalloc(pool, size);
|
||||
if (out == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
zstream.next_in = buf;
|
||||
zstream.avail_in = len;
|
||||
zstream.next_out = out;
|
||||
zstream.avail_out = size;
|
||||
|
||||
rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel,
|
||||
Z_DEFAULT_STRATEGY);
|
||||
|
||||
if (rc != Z_OK) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"deflate in: ni:%p no:%p ai:%ud ao:%ud",
|
||||
zstream.next_in, zstream.next_out,
|
||||
zstream.avail_in, zstream.avail_out);
|
||||
|
||||
rc = deflate(&zstream, Z_FINISH);
|
||||
|
||||
if (rc != Z_STREAM_END) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
"deflate(Z_FINISH) failed: %d", rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ngx_log_debug5(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
|
||||
zstream.next_in, zstream.next_out,
|
||||
zstream.avail_in, zstream.avail_out,
|
||||
rc);
|
||||
|
||||
size -= zstream.avail_out;
|
||||
|
||||
rc = deflateEnd(&zstream);
|
||||
|
||||
if (rc != Z_OK) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
n = ngx_write_fd(fd, out, size);
|
||||
|
||||
if (n != (ssize_t) size) {
|
||||
err = (n == -1) ? ngx_errno : 0;
|
||||
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
ngx_set_errno(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
/* simulate successful logging */
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size)
|
||||
{
|
||||
ngx_pool_t *pool = opaque;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0,
|
||||
"gzip alloc: n:%ud s:%ud", items, size);
|
||||
|
||||
return ngx_palloc(pool, items * size);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_log_gzip_free(void *opaque, void *address)
|
||||
{
|
||||
#if 0
|
||||
ngx_pool_t *pool = opaque;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0, "gzip free: %p", address);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log)
|
||||
{
|
||||
size_t len;
|
||||
ssize_t n;
|
||||
ngx_http_log_buf_t *buffer;
|
||||
|
||||
buffer = file->data;
|
||||
|
||||
len = buffer->pos - buffer->start;
|
||||
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (NGX_ZLIB)
|
||||
if (buffer->gzip) {
|
||||
n = ngx_http_log_gzip(file->fd, buffer->start, len, buffer->gzip, log);
|
||||
} else {
|
||||
n = ngx_write_fd(file->fd, buffer->start, len);
|
||||
}
|
||||
#else
|
||||
n = ngx_write_fd(file->fd, buffer->start, len);
|
||||
#endif
|
||||
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||
ngx_write_fd_n " to \"%s\" failed",
|
||||
file->name.data);
|
||||
|
||||
} else if ((size_t) n != len) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
|
||||
file->name.data, n, len);
|
||||
}
|
||||
|
||||
buffer->pos = buffer->start;
|
||||
|
||||
if (buffer->event && buffer->event->timer_set) {
|
||||
ngx_del_timer(buffer->event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_log_flush_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"http log buffer flush handler");
|
||||
|
||||
ngx_http_log_flush(ev->data, ev->log);
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
|
@ -501,22 +729,6 @@ ngx_http_log_copy_long(ngx_http_request_t *r, u_char *buf,
|
|||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
{
|
||||
return ngx_sprintf(buf, "%uA", r->connection->number);
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_connection_requests(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
{
|
||||
return ngx_sprintf(buf, "%ui", r->connection->requests);
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
|
@ -584,16 +796,13 @@ ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
|||
status = r->headers_out.status;
|
||||
|
||||
} else if (r->http_version == NGX_HTTP_VERSION_9) {
|
||||
*buf++ = '0';
|
||||
*buf++ = '0';
|
||||
*buf++ = '9';
|
||||
return buf;
|
||||
status = 9;
|
||||
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
|
||||
return ngx_sprintf(buf, "%ui", status);
|
||||
return ngx_sprintf(buf, "%03ui", status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -876,10 +1085,13 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
{
|
||||
ngx_http_log_loc_conf_t *llcf = conf;
|
||||
|
||||
ssize_t buf;
|
||||
ssize_t size;
|
||||
ngx_int_t gzip;
|
||||
ngx_uint_t i, n;
|
||||
ngx_str_t *value, name;
|
||||
ngx_msec_t flush;
|
||||
ngx_str_t *value, name, s;
|
||||
ngx_http_log_t *log;
|
||||
ngx_http_log_buf_t *buffer;
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
@ -964,54 +1176,152 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
&& ngx_strcasecmp(fmt[i].name.data, name.data) == 0)
|
||||
{
|
||||
log->format = &fmt[i];
|
||||
goto buffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown log format \"%V\"", &name);
|
||||
return NGX_CONF_ERROR;
|
||||
if (log->format == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown log format \"%V\"", &name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
buffer:
|
||||
size = 0;
|
||||
flush = 0;
|
||||
gzip = 0;
|
||||
|
||||
if (cf->args->nelts == 4) {
|
||||
if (ngx_strncmp(value[3].data, "buffer=", 7) != 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[3]);
|
||||
return NGX_CONF_ERROR;
|
||||
for (i = 3; i < cf->args->nelts; i++) {
|
||||
|
||||
if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) {
|
||||
s.len = value[i].len - 7;
|
||||
s.data = value[i].data + 7;
|
||||
|
||||
size = ngx_parse_size(&s);
|
||||
|
||||
if (size == NGX_ERROR || size == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid buffer size \"%V\"", &s);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "flush=", 6) == 0) {
|
||||
s.len = value[i].len - 6;
|
||||
s.data = value[i].data + 6;
|
||||
|
||||
flush = ngx_parse_time(&s, 0);
|
||||
|
||||
if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid flush time \"%V\"", &s);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "gzip", 4) == 0
|
||||
&& (value[i].len == 4 || value[i].data[4] == '='))
|
||||
{
|
||||
#if (NGX_ZLIB)
|
||||
if (size == 0) {
|
||||
size = 64 * 1024;
|
||||
}
|
||||
|
||||
if (value[i].len == 4) {
|
||||
gzip = Z_BEST_SPEED;
|
||||
continue;
|
||||
}
|
||||
|
||||
s.len = value[i].len - 5;
|
||||
s.data = value[i].data + 5;
|
||||
|
||||
gzip = ngx_atoi(s.data, s.len);
|
||||
|
||||
if (gzip < 1 || gzip > 9) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid compression level \"%V\"", &s);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"nginx was built without zlib support");
|
||||
return NGX_CONF_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (flush && size == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"no buffer is defined for access_log \"%V\"",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
|
||||
if (log->script) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"buffered logs cannot have variables in name");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
name.len = value[3].len - 7;
|
||||
name.data = value[3].data + 7;
|
||||
if (log->file->data) {
|
||||
buffer = log->file->data;
|
||||
|
||||
buf = ngx_parse_size(&name);
|
||||
if (buffer->last - buffer->start != size
|
||||
|| buffer->flush != flush
|
||||
|| buffer->gzip != gzip)
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"access_log \"%V\" already defined "
|
||||
"with conflicting parameters",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (buf == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid buffer value \"%V\"", &name);
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t));
|
||||
if (buffer == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (log->file->buffer && log->file->last - log->file->pos != buf) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"access_log \"%V\" already defined "
|
||||
"with different buffer size", &value[1]);
|
||||
buffer->start = ngx_pnalloc(cf->pool, size);
|
||||
if (buffer->start == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
log->file->buffer = ngx_palloc(cf->pool, buf);
|
||||
if (log->file->buffer == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
buffer->pos = buffer->start;
|
||||
buffer->last = buffer->start + size;
|
||||
|
||||
if (flush) {
|
||||
buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t));
|
||||
if (buffer->event == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
buffer->event->data = log->file;
|
||||
buffer->event->handler = ngx_http_log_flush_handler;
|
||||
buffer->event->log = &cf->cycle->new_log;
|
||||
|
||||
buffer->flush = flush;
|
||||
}
|
||||
|
||||
log->file->pos = log->file->buffer;
|
||||
log->file->last = log->file->buffer + buf;
|
||||
buffer->gzip = gzip;
|
||||
|
||||
log->file->flush = ngx_http_log_flush;
|
||||
log->file->data = buffer;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
@ -1146,12 +1456,6 @@ ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
|
|||
goto invalid;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(var.data, "apache_bytes_sent", 17) == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"use \"$body_bytes_sent\" instead of "
|
||||
"\"$apache_bytes_sent\"");
|
||||
}
|
||||
|
||||
for (v = ngx_http_log_vars; v->name.len; v++) {
|
||||
|
||||
if (v->name.len == var.len
|
||||
|
|
|
@ -110,7 +110,6 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
{
|
||||
ngx_http_map_ctx_t *map = (ngx_http_map_ctx_t *) data;
|
||||
|
||||
size_t len;
|
||||
ngx_str_t val;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
|
@ -121,10 +120,8 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
len = val.len;
|
||||
|
||||
if (len && map->hostnames && val.data[len - 1] == '.') {
|
||||
len--;
|
||||
if (map->hostnames && val.len > 0 && val.data[val.len - 1] == '.') {
|
||||
val.len--;
|
||||
}
|
||||
|
||||
value = ngx_http_map_find(r, &map->map, &val);
|
||||
|
@ -212,6 +209,13 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
name = value[2];
|
||||
|
||||
if (name.data[0] != '$') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid variable name \"%V\"", &name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
name.len--;
|
||||
name.data++;
|
||||
|
||||
|
@ -281,6 +285,8 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
map->default_value = ctx.default_value ? ctx.default_value:
|
||||
&ngx_http_variable_null_value;
|
||||
|
||||
map->hostnames = ctx.hostnames;
|
||||
|
||||
hash.key = ngx_hash_key_lc;
|
||||
hash.max_size = mcf->hash_max_size;
|
||||
hash.bucket_size = mcf->hash_bucket_size;
|
||||
|
@ -370,7 +376,7 @@ static char *
|
|||
ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
{
|
||||
ngx_int_t rc, index;
|
||||
ngx_str_t *value, file, name;
|
||||
ngx_str_t *value, name;
|
||||
ngx_uint_t i, key;
|
||||
ngx_http_map_conf_ctx_t *ctx;
|
||||
ngx_http_variable_value_t *var, **vp;
|
||||
|
@ -392,15 +398,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
}
|
||||
|
||||
if (ngx_strcmp(value[0].data, "include") == 0) {
|
||||
file = value[1];
|
||||
|
||||
if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
|
||||
|
||||
return ngx_conf_parse(cf, &file);
|
||||
return ngx_conf_include(cf, dummy, conf);
|
||||
}
|
||||
|
||||
if (value[1].data[0] == '$') {
|
||||
|
@ -417,11 +415,12 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
|
||||
for (i = 0; i < ctx->var_values.nelts; i++) {
|
||||
if (index == (ngx_int_t) var[i].data) {
|
||||
var = &var[i];
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t));
|
||||
var = ngx_array_push(&ctx->var_values);
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -432,13 +431,6 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
var->len = 0;
|
||||
var->data = (u_char *) index;
|
||||
|
||||
vp = ngx_array_push(&ctx->var_values);
|
||||
if (vp == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*vp = var;
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
|
|
|
@ -616,7 +616,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
|
|||
b->file_last = of.size;
|
||||
|
||||
b->in_file = b->file_last ? 1 : 0;
|
||||
b->last_buf = 1;
|
||||
b->last_buf = (r == r->main) ? 1 : 0;
|
||||
b->last_in_chain = 1;
|
||||
|
||||
b->file->fd = of.fd;
|
||||
|
@ -750,6 +750,13 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
|
|||
|
||||
*prev = &mp4->mdat_atom;
|
||||
|
||||
if (start_offset > mp4->mdat_data.buf->file_last) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"start time is out mp4 mdat atom in \"%s\"",
|
||||
mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
adjustment = mp4->ftyp_size + mp4->moov_size
|
||||
+ ngx_http_mp4_update_mdat_atom(mp4, start_offset)
|
||||
- start_offset;
|
||||
|
@ -1024,6 +1031,10 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
|||
+ NGX_HTTP_MP4_MOOV_BUFFER_EXCESS * no_mdat;
|
||||
}
|
||||
|
||||
if (ngx_http_mp4_read(mp4, (size_t) atom_data_size) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
mp4->trak.elts = &mp4->traks;
|
||||
mp4->trak.size = sizeof(ngx_http_mp4_trak_t);
|
||||
mp4->trak.nalloc = 2;
|
||||
|
@ -1044,6 +1055,12 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
|||
mp4->buffer_start = mp4->buffer_pos;
|
||||
mp4->buffer_size = NGX_HTTP_MP4_MOOV_BUFFER_EXCESS;
|
||||
|
||||
if (mp4->buffer_start + mp4->buffer_size > mp4->buffer_end) {
|
||||
mp4->buffer = NULL;
|
||||
mp4->buffer_pos = NULL;
|
||||
mp4->buffer_end = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* skip atoms after moov atom */
|
||||
mp4->offset = mp4->end;
|
||||
|
@ -2488,7 +2505,13 @@ found:
|
|||
|
||||
ngx_mp4_set_32value(entry->chunk, 1);
|
||||
|
||||
if (trak->chunk_samples) {
|
||||
if (trak->chunk_samples && next_chunk - trak->start_chunk == 2) {
|
||||
|
||||
/* last chunk in the entry */
|
||||
|
||||
ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples);
|
||||
|
||||
} else if (trak->chunk_samples) {
|
||||
|
||||
first = &trak->stsc_chunk_entry;
|
||||
ngx_mp4_set_32value(first->chunk, 1);
|
||||
|
@ -2504,6 +2527,7 @@ found:
|
|||
|
||||
ngx_mp4_set_32value(entry->chunk, 2);
|
||||
|
||||
entries++;
|
||||
atom_size += sizeof(ngx_mp4_stsc_entry_t);
|
||||
}
|
||||
|
||||
|
|
|
@ -836,7 +836,7 @@ ngx_http_proxy_create_key(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (plcf->cache_key.value.len) {
|
||||
if (plcf->cache_key.value.data) {
|
||||
|
||||
if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
|
@ -1610,7 +1610,8 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
p->upstream_done = 1;
|
||||
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent too much data");
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -1864,6 +1865,10 @@ data:
|
|||
|
||||
}
|
||||
|
||||
if (ctx->size < 0 || ctx->length < 0) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
done:
|
||||
|
@ -2607,7 +2612,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.store_lengths = NULL;
|
||||
* conf->upstream.store_values = NULL;
|
||||
*
|
||||
* conf->method = NULL;
|
||||
* conf->method = { 0, NULL };
|
||||
* conf->headers_source = NULL;
|
||||
* conf->headers_set_len = NULL;
|
||||
* conf->headers_set = NULL;
|
||||
|
@ -2906,10 +2911,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
#endif
|
||||
|
||||
if (conf->method.len == 0) {
|
||||
conf->method = prev->method;
|
||||
ngx_conf_merge_str_value(conf->method, prev->method, "");
|
||||
|
||||
} else {
|
||||
if (conf->method.len
|
||||
&& conf->method.data[conf->method.len - 1] != ' ')
|
||||
{
|
||||
conf->method.data[conf->method.len] = ' ';
|
||||
conf->method.len++;
|
||||
}
|
||||
|
@ -3918,7 +3924,7 @@ ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (plcf->cache_key.value.len) {
|
||||
if (plcf->cache_key.value.data) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,11 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *from; /* array of ngx_in_cidr_t */
|
||||
ngx_array_t *from; /* array of ngx_cidr_t */
|
||||
ngx_uint_t type;
|
||||
ngx_uint_t hash;
|
||||
ngx_str_t header;
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
ngx_uint_t unixsock; /* unsigned unixsock:2; */
|
||||
#endif
|
||||
ngx_flag_t recursive;
|
||||
} ngx_http_realip_loc_conf_t;
|
||||
|
||||
|
||||
|
@ -35,8 +33,8 @@ typedef struct {
|
|||
|
||||
|
||||
static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip,
|
||||
size_t len);
|
||||
static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r,
|
||||
ngx_addr_t *addr);
|
||||
static void ngx_http_realip_cleanup(void *data);
|
||||
static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
@ -63,6 +61,13 @@ static ngx_command_t ngx_http_realip_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("real_ip_recursive"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_realip_loc_conf_t, recursive),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
@ -105,10 +110,9 @@ ngx_http_realip_handler(ngx_http_request_t *r)
|
|||
u_char *ip, *p;
|
||||
size_t len;
|
||||
ngx_uint_t i, hash;
|
||||
ngx_addr_t addr;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_in_cidr_t *from;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_realip_ctx_t *ctx;
|
||||
ngx_http_realip_loc_conf_t *rlcf;
|
||||
|
@ -121,12 +125,7 @@ ngx_http_realip_handler(ngx_http_request_t *r)
|
|||
|
||||
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);
|
||||
|
||||
if (rlcf->from == NULL
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
&& !rlcf->unixsock
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (rlcf->from == NULL) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
@ -152,15 +151,6 @@ ngx_http_realip_handler(ngx_http_request_t *r)
|
|||
len = r->headers_in.x_forwarded_for->value.len;
|
||||
ip = r->headers_in.x_forwarded_for->value.data;
|
||||
|
||||
for (p = ip + len - 1; p > ip; p--) {
|
||||
if (*p == ' ' || *p == ',') {
|
||||
p++;
|
||||
len -= p - ip;
|
||||
ip = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: /* NGX_HTTP_REALIP_HEADER */
|
||||
|
@ -204,42 +194,27 @@ found:
|
|||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
|
||||
|
||||
/* AF_INET only */
|
||||
addr.sockaddr = c->sockaddr;
|
||||
addr.socklen = c->socklen;
|
||||
/* addr.name = c->addr_text; */
|
||||
|
||||
if (c->sockaddr->sa_family == AF_INET) {
|
||||
sin = (struct sockaddr_in *) c->sockaddr;
|
||||
|
||||
from = rlcf->from->elts;
|
||||
for (i = 0; i < rlcf->from->nelts; i++) {
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"realip: %08XD %08XD %08XD",
|
||||
sin->sin_addr.s_addr, from[i].mask, from[i].addr);
|
||||
|
||||
if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) {
|
||||
return ngx_http_realip_set_addr(r, ip, len);
|
||||
}
|
||||
}
|
||||
if (ngx_http_get_forwarded_addr(r, &addr, ip, len, rlcf->from,
|
||||
rlcf->recursive)
|
||||
== NGX_OK)
|
||||
{
|
||||
return ngx_http_realip_set_addr(r, &addr);
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) {
|
||||
return ngx_http_realip_set_addr(r, ip, len);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
|
||||
ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr)
|
||||
{
|
||||
size_t len;
|
||||
u_char *p;
|
||||
ngx_int_t rc;
|
||||
ngx_addr_t addr;
|
||||
u_char text[NGX_SOCKADDR_STRLEN];
|
||||
ngx_connection_t *c;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_http_realip_ctx_t *ctx;
|
||||
|
@ -254,15 +229,9 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
|
|||
|
||||
c = r->connection;
|
||||
|
||||
rc = ngx_parse_addr(c->pool, &addr, ip, len);
|
||||
|
||||
switch (rc) {
|
||||
case NGX_DECLINED:
|
||||
return NGX_DECLINED;
|
||||
case NGX_ERROR:
|
||||
len = ngx_sock_ntop(addr->sockaddr, text, NGX_SOCKADDR_STRLEN, 0);
|
||||
if (len == 0) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
default: /* NGX_OK */
|
||||
break;
|
||||
}
|
||||
|
||||
p = ngx_pnalloc(c->pool, len);
|
||||
|
@ -270,7 +239,7 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
|
|||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(p, ip, len);
|
||||
ngx_memcpy(p, text, len);
|
||||
|
||||
cln->handler = ngx_http_realip_cleanup;
|
||||
|
||||
|
@ -279,8 +248,8 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
|
|||
ctx->socklen = c->socklen;
|
||||
ctx->addr_text = c->addr_text;
|
||||
|
||||
c->sockaddr = addr.sockaddr;
|
||||
c->socklen = addr.socklen;
|
||||
c->sockaddr = addr->sockaddr;
|
||||
c->socklen = addr->socklen;
|
||||
c->addr_text.len = len;
|
||||
c->addr_text.data = p;
|
||||
|
||||
|
@ -310,34 +279,33 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_cidr_t cidr;
|
||||
ngx_in_cidr_t *from;
|
||||
ngx_cidr_t *cidr;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
rlcf->unixsock = 1;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (rlcf->from == NULL) {
|
||||
rlcf->from = ngx_array_create(cf->pool, 2,
|
||||
sizeof(ngx_in_cidr_t));
|
||||
sizeof(ngx_cidr_t));
|
||||
if (rlcf->from == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
from = ngx_array_push(rlcf->from);
|
||||
if (from == NULL) {
|
||||
cidr = ngx_array_push(rlcf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr->family = AF_UNIX;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rc = ngx_ptocidr(&value[1], cidr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||
|
@ -345,20 +313,11 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (cidr.family != AF_INET) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"set_real_ip_from\" supports IPv4 only");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless", &value[1]);
|
||||
}
|
||||
|
||||
from->mask = cidr.u.in.mask;
|
||||
from->addr = cidr.u.in.addr;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
@ -409,9 +368,7 @@ ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
|
|||
*/
|
||||
|
||||
conf->type = NGX_CONF_UNSET_UINT;
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
conf->unixsock = 2;
|
||||
#endif
|
||||
conf->recursive = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
@ -427,13 +384,8 @@ ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
conf->from = prev->from;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
if (conf->unixsock == 2) {
|
||||
conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock;
|
||||
}
|
||||
#endif
|
||||
|
||||
ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP);
|
||||
ngx_conf_merge_value(conf->recursive, prev->recursive, 0);
|
||||
|
||||
if (conf->header.len == 0) {
|
||||
conf->hash = prev->hash;
|
||||
|
|
|
@ -485,6 +485,12 @@ ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
} else {
|
||||
|
||||
if (ret->status > 999) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid return code \"%V\"", &value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (cf->args->nelts == 2) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
@ -434,6 +434,7 @@ ngx_http_scgi_handler(ngx_http_request_t *r)
|
|||
u->process_header = ngx_http_scgi_process_status_line;
|
||||
u->abort_request = ngx_http_scgi_abort_request;
|
||||
u->finalize_request = ngx_http_scgi_finalize_request;
|
||||
r->state = 0;
|
||||
|
||||
u->buffering = scf->upstream.buffering;
|
||||
|
||||
|
@ -843,6 +844,7 @@ ngx_http_scgi_reinit_request(ngx_http_request_t *r)
|
|||
status->end = NULL;
|
||||
|
||||
r->upstream->process_header = ngx_http_scgi_process_status_line;
|
||||
r->state = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -1763,7 +1765,7 @@ ngx_http_scgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (scf->cache_key.value.len) {
|
||||
if (scf->cache_key.value.data) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ ngx_http_secure_link_variable(ngx_http_request_t *r,
|
|||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module);
|
||||
|
||||
if (conf->secret.len) {
|
||||
if (conf->secret.data) {
|
||||
return ngx_http_secure_link_old_variable(r, conf, v, data);
|
||||
}
|
||||
|
||||
|
@ -318,7 +318,16 @@ ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_http_secure_link_conf_t *prev = parent;
|
||||
ngx_http_secure_link_conf_t *conf = child;
|
||||
|
||||
ngx_conf_merge_str_value(conf->secret, prev->secret, "");
|
||||
if (conf->secret.data) {
|
||||
if (conf->variable || conf->md5) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"secure_link_secret\" cannot be mixed with "
|
||||
"\"secure_link\" and \"secure_link_md5\"");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (conf->variable == NULL) {
|
||||
conf->variable = prev->variable;
|
||||
|
@ -328,6 +337,10 @@ ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
conf->md5 = prev->md5;
|
||||
}
|
||||
|
||||
if (conf->variable == NULL && conf->md5 == NULL) {
|
||||
conf->secret = prev->secret;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,13 @@ ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
name = value[2];
|
||||
|
||||
if (name.data[0] != '$') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid variable name \"%V\"", &name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
name.len--;
|
||||
name.data++;
|
||||
|
||||
|
@ -211,7 +218,7 @@ ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
part->percent = 0;
|
||||
|
||||
} else {
|
||||
if (value[0].data[value[0].len - 1] != '%') {
|
||||
if (value[0].len == 0 || value[0].data[value[0].len - 1] != '%') {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
|
|
|
@ -1024,6 +1024,7 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|||
switch (state) {
|
||||
|
||||
case ssi_start_state:
|
||||
/* not reached */
|
||||
break;
|
||||
|
||||
case ssi_tag_state:
|
||||
|
|
|
@ -48,6 +48,7 @@ static ngx_conf_enum_t ngx_http_ssl_verify[] = {
|
|||
{ ngx_string("off"), 0 },
|
||||
{ ngx_string("on"), 1 },
|
||||
{ ngx_string("optional"), 2 },
|
||||
{ ngx_string("optional_no_ca"), 3 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
@ -466,7 +467,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
if (conf->verify) {
|
||||
|
||||
if (conf->client_certificate.len == 0) {
|
||||
if (conf->client_certificate.len == 0 && conf->verify != 3) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no ssl_client_certificate for ssl_client_verify");
|
||||
return NGX_CONF_ERROR;
|
||||
|
@ -592,7 +593,6 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
|
||||
if (value[i].data[j] == ':') {
|
||||
value[i].data[j] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
|
|||
r->headers_out.status = NGX_HTTP_OK;
|
||||
r->headers_out.content_length_n = b->last - b->pos;
|
||||
|
||||
b->last_buf = 1;
|
||||
b->last_buf = (r == r->main) ? 1 : 0;
|
||||
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
|
|
|
@ -627,7 +627,7 @@ ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_str_t *value;
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (slcf->match.len) {
|
||||
if (slcf->match.data) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
|
@ -687,7 +687,7 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->once, prev->once, 1);
|
||||
ngx_conf_merge_str_value(conf->match, prev->match, "");
|
||||
|
||||
if (conf->value.value.len == 0) {
|
||||
if (conf->value.value.data == NULL) {
|
||||
conf->value = prev->value;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ typedef struct {
|
|||
|
||||
ngx_uint_t hash;
|
||||
|
||||
u_char addr[3];
|
||||
u_char addrlen;
|
||||
u_char *addr;
|
||||
|
||||
u_char tries;
|
||||
|
||||
|
@ -76,7 +77,10 @@ ngx_module_t ngx_http_upstream_ip_hash_module = {
|
|||
};
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static u_char ngx_http_upstream_ip_hash_pseudo_addr[3];
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
|
||||
{
|
||||
if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
|
||||
|
@ -93,8 +97,10 @@ static ngx_int_t
|
|||
ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
|
||||
ngx_http_upstream_srv_conf_t *us)
|
||||
{
|
||||
u_char *p;
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
ngx_http_upstream_ip_hash_peer_data_t *iphp;
|
||||
|
||||
iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
|
||||
|
@ -110,20 +116,25 @@ ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
|
|||
|
||||
r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
if (r->connection->sockaddr->sa_family == AF_INET) {
|
||||
switch (r->connection->sockaddr->sa_family) {
|
||||
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||
p = (u_char *) &sin->sin_addr.s_addr;
|
||||
iphp->addr[0] = p[0];
|
||||
iphp->addr[1] = p[1];
|
||||
iphp->addr[2] = p[2];
|
||||
iphp->addr = (u_char *) &sin->sin_addr.s_addr;
|
||||
iphp->addrlen = 3;
|
||||
break;
|
||||
|
||||
} else {
|
||||
iphp->addr[0] = 0;
|
||||
iphp->addr[1] = 0;
|
||||
iphp->addr[2] = 0;
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
|
||||
iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr;
|
||||
iphp->addrlen = 16;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
iphp->addr = ngx_http_upstream_ip_hash_pseudo_addr;
|
||||
iphp->addrlen = 3;
|
||||
}
|
||||
|
||||
iphp->hash = 89;
|
||||
|
@ -140,6 +151,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
|
|||
ngx_http_upstream_ip_hash_peer_data_t *iphp = data;
|
||||
|
||||
time_t now;
|
||||
ngx_int_t w;
|
||||
uintptr_t m;
|
||||
ngx_uint_t i, n, p, hash;
|
||||
ngx_http_upstream_rr_peer_t *peer;
|
||||
|
@ -162,11 +174,25 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
|
|||
|
||||
for ( ;; ) {
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < iphp->addrlen; i++) {
|
||||
hash = (hash * 113 + iphp->addr[i]) % 6271;
|
||||
}
|
||||
|
||||
p = hash % iphp->rrp.peers->number;
|
||||
if (!iphp->rrp.peers->weighted) {
|
||||
p = hash % iphp->rrp.peers->number;
|
||||
|
||||
} else {
|
||||
w = hash % iphp->rrp.peers->total_weight;
|
||||
|
||||
for (i = 0; i < iphp->rrp.peers->number; i++) {
|
||||
w -= iphp->rrp.peers->peer[i].weight;
|
||||
if (w < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p = i;
|
||||
}
|
||||
|
||||
n = p / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
|
||||
|
@ -229,6 +255,7 @@ ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
|
||||
|
||||
uscf->flags = NGX_HTTP_UPSTREAM_CREATE
|
||||
|NGX_HTTP_UPSTREAM_WEIGHT
|
||||
|NGX_HTTP_UPSTREAM_MAX_FAILS
|
||||
|NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
|
||||
|NGX_HTTP_UPSTREAM_DOWN;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
typedef struct {
|
||||
ngx_uint_t max_cached;
|
||||
ngx_uint_t single; /* unsigned:1 */
|
||||
|
||||
ngx_queue_t cache;
|
||||
ngx_queue_t free;
|
||||
|
@ -38,8 +37,6 @@ typedef struct {
|
|||
ngx_event_save_peer_session_pt original_save_session;
|
||||
#endif
|
||||
|
||||
ngx_uint_t failed; /* unsigned:1 */
|
||||
|
||||
} ngx_http_upstream_keepalive_peer_data_t;
|
||||
|
||||
|
||||
|
@ -221,38 +218,11 @@ ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"get keepalive peer");
|
||||
|
||||
kp->failed = 0;
|
||||
|
||||
/* single pool of cached connections */
|
||||
|
||||
if (kp->conf->single && !ngx_queue_empty(&kp->conf->cache)) {
|
||||
|
||||
q = ngx_queue_head(&kp->conf->cache);
|
||||
|
||||
item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
|
||||
c = item->connection;
|
||||
|
||||
ngx_queue_remove(q);
|
||||
ngx_queue_insert_head(&kp->conf->free, q);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"get keepalive peer: using connection %p", c);
|
||||
|
||||
c->idle = 0;
|
||||
c->log = pc->log;
|
||||
c->read->log = pc->log;
|
||||
c->write->log = pc->log;
|
||||
c->pool->log = pc->log;
|
||||
|
||||
pc->connection = c;
|
||||
pc->cached = 1;
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
/* ask balancer */
|
||||
|
||||
rc = kp->original_get_peer(pc, kp->data);
|
||||
|
||||
if (kp->conf->single || rc != NGX_OK) {
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -308,18 +278,12 @@ ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"free keepalive peer");
|
||||
|
||||
/* remember failed state - peer.free() may be called more than once */
|
||||
|
||||
if (state & NGX_PEER_FAILED) {
|
||||
kp->failed = 1;
|
||||
}
|
||||
|
||||
/* cache valid connections */
|
||||
|
||||
u = kp->upstream;
|
||||
c = pc->connection;
|
||||
|
||||
if (kp->failed
|
||||
if (state & NGX_PEER_FAILED
|
||||
|| c == NULL
|
||||
|| c->read->eof
|
||||
|| c->read->error
|
||||
|
@ -528,6 +492,10 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
kcf = ngx_http_conf_upstream_srv_conf(uscf,
|
||||
ngx_http_upstream_keepalive_module);
|
||||
|
||||
if (kcf->original_init_upstream) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
kcf->original_init_upstream = uscf->peer.init_upstream
|
||||
? uscf->peer.init_upstream
|
||||
: ngx_http_upstream_init_round_robin;
|
||||
|
@ -552,7 +520,8 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
for (i = 2; i < cf->args->nelts; i++) {
|
||||
|
||||
if (ngx_strcmp(value[i].data, "single") == 0) {
|
||||
kcf->single = 1;
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"the \"single\" parameter is deprecated");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
400
src/http/modules/ngx_http_upstream_least_conn_module.c
Normal file
400
src/http/modules/ngx_http_upstream_least_conn_module.c
Normal file
|
@ -0,0 +1,400 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Maxim Dounin
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t *conns;
|
||||
} ngx_http_upstream_least_conn_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* the round robin data must be first */
|
||||
ngx_http_upstream_rr_peer_data_t rrp;
|
||||
|
||||
ngx_uint_t *conns;
|
||||
|
||||
ngx_event_get_peer_pt get_rr_peer;
|
||||
ngx_event_free_peer_pt free_rr_peer;
|
||||
} ngx_http_upstream_lc_peer_data_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r,
|
||||
ngx_http_upstream_srv_conf_t *us);
|
||||
static ngx_int_t ngx_http_upstream_get_least_conn_peer(
|
||||
ngx_peer_connection_t *pc, void *data);
|
||||
static void ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
|
||||
void *data, ngx_uint_t state);
|
||||
static void *ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_upstream_least_conn_commands[] = {
|
||||
|
||||
{ ngx_string("least_conn"),
|
||||
NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
|
||||
ngx_http_upstream_least_conn,
|
||||
0,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_http_upstream_least_conn_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
ngx_http_upstream_least_conn_create_conf, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
NULL, /* create location configuration */
|
||||
NULL /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_http_upstream_least_conn_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_upstream_least_conn_module_ctx, /* module context */
|
||||
ngx_http_upstream_least_conn_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_init_least_conn(ngx_conf_t *cf,
|
||||
ngx_http_upstream_srv_conf_t *us)
|
||||
{
|
||||
ngx_uint_t n;
|
||||
ngx_http_upstream_rr_peers_t *peers;
|
||||
ngx_http_upstream_least_conn_conf_t *lcf;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"init least conn");
|
||||
|
||||
if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
peers = us->peer.data;
|
||||
|
||||
n = peers->number;
|
||||
|
||||
if (peers->next) {
|
||||
n += peers->next->number;
|
||||
}
|
||||
|
||||
lcf = ngx_http_conf_upstream_srv_conf(us,
|
||||
ngx_http_upstream_least_conn_module);
|
||||
|
||||
lcf->conns = ngx_pcalloc(cf->pool, sizeof(ngx_uint_t) * n);
|
||||
if (lcf->conns == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
us->peer.init = ngx_http_upstream_init_least_conn_peer;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r,
|
||||
ngx_http_upstream_srv_conf_t *us)
|
||||
{
|
||||
ngx_http_upstream_lc_peer_data_t *lcp;
|
||||
ngx_http_upstream_least_conn_conf_t *lcf;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"init least conn peer");
|
||||
|
||||
lcf = ngx_http_conf_upstream_srv_conf(us,
|
||||
ngx_http_upstream_least_conn_module);
|
||||
|
||||
lcp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_lc_peer_data_t));
|
||||
if (lcp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
lcp->conns = lcf->conns;
|
||||
|
||||
r->upstream->peer.data = &lcp->rrp;
|
||||
|
||||
if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer;
|
||||
r->upstream->peer.free = ngx_http_upstream_free_least_conn_peer;
|
||||
|
||||
lcp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
|
||||
lcp->free_rr_peer = ngx_http_upstream_free_round_robin_peer;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
|
||||
{
|
||||
ngx_http_upstream_lc_peer_data_t *lcp = data;
|
||||
|
||||
time_t now;
|
||||
uintptr_t m;
|
||||
ngx_int_t rc, total;
|
||||
ngx_uint_t i, n, p, many;
|
||||
ngx_http_upstream_rr_peer_t *peer, *best;
|
||||
ngx_http_upstream_rr_peers_t *peers;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"get least conn peer, try: %ui", pc->tries);
|
||||
|
||||
if (lcp->rrp.peers->single) {
|
||||
return lcp->get_rr_peer(pc, &lcp->rrp);
|
||||
}
|
||||
|
||||
pc->cached = 0;
|
||||
pc->connection = NULL;
|
||||
|
||||
now = ngx_time();
|
||||
|
||||
peers = lcp->rrp.peers;
|
||||
|
||||
best = NULL;
|
||||
total = 0;
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
many = 0;
|
||||
p = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < peers->number; i++) {
|
||||
|
||||
n = i / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
|
||||
|
||||
if (lcp->rrp.tried[n] & m) {
|
||||
continue;
|
||||
}
|
||||
|
||||
peer = &peers->peer[i];
|
||||
|
||||
if (peer->down) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (peer->max_fails
|
||||
&& peer->fails >= peer->max_fails
|
||||
&& now - peer->checked <= peer->fail_timeout)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* select peer with least number of connections; if there are
|
||||
* multiple peers with the same number of connections, select
|
||||
* based on round-robin
|
||||
*/
|
||||
|
||||
if (best == NULL
|
||||
|| lcp->conns[i] * best->weight < lcp->conns[p] * peer->weight)
|
||||
{
|
||||
best = peer;
|
||||
many = 0;
|
||||
p = i;
|
||||
|
||||
} else if (lcp->conns[i] * best->weight
|
||||
== lcp->conns[p] * peer->weight)
|
||||
{
|
||||
many = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (best == NULL) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"get least conn peer, no peer found");
|
||||
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (many) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"get least conn peer, many");
|
||||
|
||||
for (i = p; i < peers->number; i++) {
|
||||
|
||||
n = i / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
|
||||
|
||||
if (lcp->rrp.tried[n] & m) {
|
||||
continue;
|
||||
}
|
||||
|
||||
peer = &peers->peer[i];
|
||||
|
||||
if (peer->down) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lcp->conns[i] * best->weight != lcp->conns[p] * peer->weight) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (peer->max_fails
|
||||
&& peer->fails >= peer->max_fails
|
||||
&& now - peer->checked <= peer->fail_timeout)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
peer->current_weight += peer->effective_weight;
|
||||
total += peer->effective_weight;
|
||||
|
||||
if (peer->effective_weight < peer->weight) {
|
||||
peer->effective_weight++;
|
||||
}
|
||||
|
||||
if (peer->current_weight > best->current_weight) {
|
||||
best = peer;
|
||||
p = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best->current_weight -= total;
|
||||
best->checked = now;
|
||||
|
||||
pc->sockaddr = best->sockaddr;
|
||||
pc->socklen = best->socklen;
|
||||
pc->name = &best->name;
|
||||
|
||||
lcp->rrp.current = p;
|
||||
|
||||
n = p / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
|
||||
|
||||
lcp->rrp.tried[n] |= m;
|
||||
lcp->conns[p]++;
|
||||
|
||||
if (pc->tries == 1 && peers->next) {
|
||||
pc->tries += peers->next->number;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
failed:
|
||||
|
||||
if (peers->next) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"get least conn peer, backup servers");
|
||||
|
||||
lcp->conns += peers->number;
|
||||
|
||||
lcp->rrp.peers = peers->next;
|
||||
pc->tries = lcp->rrp.peers->number;
|
||||
|
||||
n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1))
|
||||
/ (8 * sizeof(uintptr_t));
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
lcp->rrp.tried[i] = 0;
|
||||
}
|
||||
|
||||
rc = ngx_http_upstream_get_least_conn_peer(pc, lcp);
|
||||
|
||||
if (rc != NGX_BUSY) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* all peers failed, mark them as live for quick recovery */
|
||||
|
||||
for (i = 0; i < peers->number; i++) {
|
||||
peers->peer[i].fails = 0;
|
||||
}
|
||||
|
||||
pc->name = peers->name;
|
||||
|
||||
return NGX_BUSY;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
|
||||
void *data, ngx_uint_t state)
|
||||
{
|
||||
ngx_http_upstream_lc_peer_data_t *lcp = data;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"free least conn peer %ui %ui", pc->tries, state);
|
||||
|
||||
if (lcp->rrp.peers->single) {
|
||||
lcp->free_rr_peer(pc, &lcp->rrp, state);
|
||||
return;
|
||||
}
|
||||
|
||||
lcp->conns[lcp->rrp.current]--;
|
||||
|
||||
lcp->free_rr_peer(pc, &lcp->rrp, state);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_upstream_least_conn_conf_t *conf;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool,
|
||||
sizeof(ngx_http_upstream_least_conn_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->conns = NULL;
|
||||
*/
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_upstream_srv_conf_t *uscf;
|
||||
|
||||
uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
|
||||
|
||||
uscf->peer.init_upstream = ngx_http_upstream_init_least_conn;
|
||||
|
||||
uscf->flags = NGX_HTTP_UPSTREAM_CREATE
|
||||
|NGX_HTTP_UPSTREAM_WEIGHT
|
||||
|NGX_HTTP_UPSTREAM_MAX_FAILS
|
||||
|NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
|
||||
|NGX_HTTP_UPSTREAM_DOWN
|
||||
|NGX_HTTP_UPSTREAM_BACKUP;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
|
@ -467,6 +467,7 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
|
|||
u->process_header = ngx_http_uwsgi_process_status_line;
|
||||
u->abort_request = ngx_http_uwsgi_abort_request;
|
||||
u->finalize_request = ngx_http_uwsgi_finalize_request;
|
||||
r->state = 0;
|
||||
|
||||
u->buffering = uwcf->upstream.buffering;
|
||||
|
||||
|
@ -883,6 +884,7 @@ ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
|
|||
status->end = NULL;
|
||||
|
||||
r->upstream->process_header = ngx_http_uwsgi_process_status_line;
|
||||
r->state = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -1805,7 +1807,7 @@ ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (uwcf->cache_key.value.len) {
|
||||
if (uwcf->cache_key.value.data) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
|
|||
ctx->done = 1;
|
||||
|
||||
if (b == NULL) {
|
||||
return ngx_http_filter_finalize_request(r, NULL,
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
|
|||
|
||||
if (cln == NULL) {
|
||||
ngx_free(b->pos);
|
||||
return ngx_http_filter_finalize_request(r, NULL,
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
@ -810,7 +810,7 @@ ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
file = xmcf->dtd_files.elts;
|
||||
for (i = 0; i < xmcf->dtd_files.nelts; i++) {
|
||||
if (ngx_strcmp(file[i].name, &value[1].data) == 0) {
|
||||
if (ngx_strcmp(file[i].name, value[1].data) == 0) {
|
||||
xlcf->dtd = file[i].data;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -884,7 +884,7 @@ ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
file = xmcf->sheet_files.elts;
|
||||
for (i = 0; i < xmcf->sheet_files.nelts; i++) {
|
||||
if (ngx_strcmp(file[i].name, &value[1].data) == 0) {
|
||||
if (ngx_strcmp(file[i].name, value[1].data) == 0) {
|
||||
sheet->stylesheet = file[i].data;
|
||||
goto found;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue