Compare commits
173 commits
quic
...
stable-0.5
Author | SHA1 | Date | |
---|---|---|---|
|
ff8cfc0b45 | ||
|
b55c3bd75f | ||
|
60f79b0cfd | ||
|
4edf193b41 | ||
|
b6c2d1a5d6 | ||
|
e7af3c349d | ||
|
c32036746d | ||
|
29e7a067b3 | ||
|
340f9a268b | ||
|
321d1a2cfb | ||
|
8ad79171b9 | ||
|
05e3ebfd2a | ||
|
55ff3d4e84 | ||
|
69b5d6657d | ||
|
583ddf1405 | ||
|
5fa7846941 | ||
|
7560165df1 | ||
|
e9e15f8a13 | ||
|
b80397bd24 | ||
|
b811a5c388 | ||
|
73d987a411 | ||
|
c8795dae87 | ||
|
64763c5e44 | ||
|
80da2c2708 | ||
|
7c957e784c | ||
|
3b28854a2b | ||
|
e96e6e5271 | ||
|
0afa1ec458 | ||
|
f111133e2e | ||
|
3e6bbafb66 | ||
|
26181301e9 | ||
|
c4773f2a3c | ||
|
0f965a8cd0 | ||
|
70f3ec2922 | ||
|
966315a1e9 | ||
|
bf139b1f7f | ||
|
f6bfdaf2f4 | ||
|
7906a3e0e7 | ||
|
b6aa9ee289 | ||
|
81fd596e29 | ||
|
fa10dd869a | ||
|
cb5f545b0d | ||
|
2514b3962a | ||
|
82e19b3fa9 | ||
|
8ae336f5ad | ||
|
142d14d203 | ||
|
97cc2c55fe | ||
|
dc291bf4f6 | ||
|
e301eca9b5 | ||
|
14c25da2eb | ||
|
e448698e1a | ||
|
763e61004a | ||
|
721df7ef24 | ||
|
7c99942b42 | ||
|
ab2aecb398 | ||
|
a8545c11c4 | ||
|
d6e4741aa8 | ||
|
2e98f272c7 | ||
|
ee84366663 | ||
|
c86eef6299 | ||
|
6d347fa2c3 | ||
|
281a70c61c | ||
|
872ff5410e | ||
|
8552e3741f | ||
|
984293b7a7 | ||
|
2684d952f8 | ||
|
919798169d | ||
|
9a95869ac4 | ||
|
76fe404739 | ||
|
9d5ff02c8b | ||
|
a1876613aa | ||
|
2163a4a058 | ||
|
b2f5beaa06 | ||
|
7586d58399 | ||
|
09ba4853d2 | ||
|
1687d189d6 | ||
|
ca7705fc99 | ||
|
92f28e3d31 | ||
|
7ad9f14c74 | ||
|
e0f4baa71a | ||
|
d8f7a2530d | ||
|
8c08a6115f | ||
|
814b1095e2 | ||
|
94a30a8ea7 | ||
|
17a957c6f6 | ||
|
67abd13c05 | ||
|
cd46141e2b | ||
|
8e79f6fbf8 | ||
|
93b7540ff5 | ||
|
1bb036cd84 | ||
|
a142ff6a3a | ||
|
a69878f1fc | ||
|
f5ef42b0d3 | ||
|
ed6903a15d | ||
|
ff31837caf | ||
|
bed8eaacf4 | ||
|
4f2f70c7cd | ||
|
223a42cbec | ||
|
93666c389e | ||
|
cffa71db74 | ||
|
731f992260 | ||
|
ce69390c00 | ||
|
f2319c1b65 | ||
|
92a7aff502 | ||
|
e355d9c3af | ||
|
fee8fa15f5 | ||
|
d0505ea2bb | ||
|
2ee2bc5fc6 | ||
|
90964473e4 | ||
|
6e6b63ad8e | ||
|
03465b9370 | ||
|
0e37b1c1e3 | ||
|
0d3b197fcb | ||
|
5808a898f5 | ||
|
53da077a78 | ||
|
f0237bfba3 | ||
|
d8ea8ca5f8 | ||
|
8e2c9a3126 | ||
|
d8d4d64a75 | ||
|
8b655ab2dd | ||
|
b132258d73 | ||
|
8f5466261d | ||
|
a54eea5a08 | ||
|
6ba2e6522f | ||
|
a6d70e05ef | ||
|
63387a60e5 | ||
|
288c7f86fd | ||
|
96dcd68f7a | ||
|
773b0ae920 | ||
|
fc18feef28 | ||
|
4b8574c891 | ||
|
64c07187a0 | ||
|
19994e9acc | ||
|
5dc1930cce | ||
|
cc5999a68c | ||
|
b473bf5b46 | ||
|
cf18290f42 | ||
|
8bb450b5e4 | ||
|
b66b8c0906 | ||
|
42c91afe85 | ||
|
988bede80f | ||
|
f488e98593 | ||
|
aaa44dd224 | ||
|
2ac6766577 | ||
|
aef26c77db | ||
|
969f51c3c8 | ||
|
d1d9811cf3 | ||
|
7b0af7b8b3 | ||
|
10f0b17058 | ||
|
03e366afc3 | ||
|
3e6256935f | ||
|
0a647dc34d | ||
|
01d30b7b65 | ||
|
32ad363a2c | ||
|
149fdb18d8 | ||
|
0e254f6bbb | ||
|
ec6ef43624 | ||
|
96e7062852 | ||
|
129dd82d2a | ||
|
11ade0fb6a | ||
|
ea7cf4cf90 | ||
|
20f18b4d2e | ||
|
152003567d | ||
|
08f9992a63 | ||
|
4a7cc46f8c | ||
|
890a7407c7 | ||
|
61092efcfa | ||
|
f14fcc5d23 | ||
|
5f819d85df | ||
|
f989298c90 | ||
|
3702756e0d | ||
|
7474f1ea93 | ||
|
93e8ad64c7 |
145 changed files with 8598 additions and 4093 deletions
71
auto/cc/sunc
71
auto/cc/sunc
|
@ -2,8 +2,10 @@
|
|||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
# Sun C 5.7 Patch 117837-04 2005/05/11
|
||||
# Sun C 5.8 2005/10/13
|
||||
# Sun C 5.7 Patch 117837-04 2005/05/11 Sun Studio 10
|
||||
# Sun C 5.8 2005/10/13 Sun Studio 11
|
||||
# Sun C 5.9 SunOS_i386 2007/05/03 Sun Studio 12
|
||||
# Sun C 5.9 SunOS_sparc 2007/05/03
|
||||
|
||||
NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
|
||||
| sed -e 's/^.* Sun C \(.*\)/\1/'`
|
||||
|
@ -13,6 +15,33 @@ echo " + Sun C version: $NGX_SUNC_VER"
|
|||
have=NGX_COMPILER value="\"Sun C $NGX_SUNC_VER\"" . auto/define
|
||||
|
||||
|
||||
cat << END > $NGX_AUTOTEST.c
|
||||
|
||||
int main() { printf("%d", __SUNPRO_C); }
|
||||
|
||||
END
|
||||
|
||||
eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
|
||||
|
||||
if [ -x $NGX_AUTOTEST ]; then
|
||||
ngx_sunc_ver=`$NGX_AUTOTEST`
|
||||
fi
|
||||
|
||||
rm $NGX_AUTOTEST*
|
||||
|
||||
# 1424 == 0x590, Sun Studio 12
|
||||
|
||||
if [ "$ngx_sunc_ver" -ge 1424 ]; then
|
||||
ngx_sparc32="-m32"
|
||||
ngx_sparc64="-m64"
|
||||
ngx_amd64="-m64"
|
||||
|
||||
else
|
||||
ngx_sparc32="-xarch=v8plus"
|
||||
ngx_sparc64="-xarch=v9"
|
||||
ngx_amd64="-xarch=amd64"
|
||||
fi
|
||||
|
||||
case "$NGX_MACHINE" in
|
||||
|
||||
i86pc)
|
||||
|
@ -35,9 +64,6 @@ case "$NGX_MACHINE" in
|
|||
;;
|
||||
|
||||
sun4u | sun4v)
|
||||
# "-xarch=v9" enables the "casa" assembler instruction
|
||||
CFLAGS="$CFLAGS -xarch=v9"
|
||||
CORE_LINK="$CORE_LINK -xarch=v9"
|
||||
NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
|
||||
;;
|
||||
|
||||
|
@ -46,7 +72,9 @@ esac
|
|||
|
||||
# optimizations
|
||||
|
||||
CFLAGS="$CFLAGS -fast"
|
||||
IPO=-xipo
|
||||
CFLAGS="$CFLAGS -fast $IPO"
|
||||
CORE_LINK="$CORE_LINK -fast $IPO"
|
||||
|
||||
|
||||
case $CPU in
|
||||
|
@ -81,11 +109,29 @@ case $CPU in
|
|||
CPU_OPT="$CPU_OPT -xcache=64/64/2:1024/64/16"
|
||||
;;
|
||||
|
||||
sparc32)
|
||||
# build 32-bit UltraSparc binary
|
||||
CPU_OPT="$ngx_sparc32"
|
||||
CORE_LINK="$CORE_LINK $ngx_sparc32"
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_sparc32"
|
||||
NGX_CPU_CACHE_LINE=64
|
||||
;;
|
||||
|
||||
sparc64)
|
||||
# build 64-bit UltraSparc binary
|
||||
CPU_OPT="$ngx_sparc64"
|
||||
CORE_LINK="$CORE_LINK $ngx_sparc64"
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_sparc64"
|
||||
NGX_CPU_CACHE_LINE=64
|
||||
;;
|
||||
|
||||
amd64)
|
||||
# build 64-bit amd64 binary
|
||||
CPU_OPT="-xarch=amd64"
|
||||
CORE_LINK="$CORE_LINK -xarch=amd64"
|
||||
CPU_OPT="$ngx_amd64"
|
||||
CORE_LINK="$CORE_LINK $ngx_amd64"
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_amd64"
|
||||
NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il"
|
||||
NGX_CPU_CACHE_LINE=64
|
||||
;;
|
||||
|
||||
esac
|
||||
|
@ -95,17 +141,20 @@ CFLAGS="$CFLAGS $CPU_OPT"
|
|||
|
||||
|
||||
if [ ".$PCRE_OPT" = "." ]; then
|
||||
PCRE_OPT="-fast $CPU_OPT"
|
||||
PCRE_OPT="-fast $IPO $CPU_OPT"
|
||||
fi
|
||||
|
||||
if [ ".$MD5_OPT" = "." ]; then
|
||||
MD5_OPT="-fast $CPU_OPT"
|
||||
MD5_OPT="-fast $IPO $CPU_OPT"
|
||||
fi
|
||||
|
||||
if [ ".$ZLIB_OPT" = "." ]; then
|
||||
ZLIB_OPT="-fast $CPU_OPT"
|
||||
ZLIB_OPT="-fast $IPO $CPU_OPT"
|
||||
fi
|
||||
|
||||
|
||||
# stop on warning
|
||||
CFLAGS="$CFLAGS -errwarn=%all"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
|
|
|
@ -6,3 +6,5 @@ ngx_include="unistd.h"; . auto/include
|
|||
ngx_include="inttypes.h"; . auto/include
|
||||
ngx_include="limits.h"; . auto/include
|
||||
ngx_include="sys/filio.h"; . auto/include
|
||||
ngx_include="crypt.h"; . auto/include
|
||||
ngx_include="malloc.h"; . auto/include
|
||||
|
|
15
auto/init
15
auto/init
|
@ -55,15 +55,24 @@ clean:
|
|||
upgrade:
|
||||
$NGX_SBIN_PATH -t
|
||||
|
||||
# upgrade compatibility from 0.1.x to 0.2.x
|
||||
kill -USR2 \`cat $NGX_PID_PATH\`
|
||||
sleep 1
|
||||
test -f $NGX_PID_PATH.oldbin
|
||||
|
||||
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
|
||||
|
||||
upgrade1:
|
||||
# upgrade 0.1.x to 0.2+
|
||||
|
||||
$NGX_SBIN_PATH -t
|
||||
|
||||
cp $NGX_PID_PATH $NGX_PID_PATH.oldbin
|
||||
|
||||
kill -USR2 \`cat $NGX_PID_PATH\`
|
||||
sleep 1
|
||||
test -f $NGX_PID_PATH.oldbin
|
||||
|
||||
# upgrade compatibility from 0.1.x to 0.2.x
|
||||
cp $NGX_PID_PATH $NGX_PID_PATH.newbin
|
||||
|
||||
kill -WINCH \`cat $NGX_PID_PATH.oldbin\`
|
||||
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
|
||||
END
|
||||
|
|
|
@ -17,7 +17,7 @@ if [ $PCRE != NONE ]; then
|
|||
CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
|
||||
;;
|
||||
|
||||
icc* | sunc )
|
||||
icc* )
|
||||
have=NGX_PCRE . auto/have
|
||||
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
|
||||
|
||||
|
@ -25,13 +25,18 @@ if [ $PCRE != NONE ]; then
|
|||
|
||||
echo $ngx_n "checking for PCRE library ...$ngx_c"
|
||||
|
||||
if [ -e $PCRE/pcre.h ]; then
|
||||
if [ -f $PCRE/pcre.h ]; then
|
||||
ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
|
||||
| sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
|
||||
|
||||
else
|
||||
else if [ -f $PCRE/configure.in ]; then
|
||||
ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
|
||||
| sed -e 's/^.*=\(.*\)$/\1/'`
|
||||
|
||||
else
|
||||
ngx_pcre_ver=`grep pcre_major, $PCRE/configure.ac \
|
||||
| sed -e 's/^.*pcre_major,.*\[\(.*\)\].*$/\1/'`
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " $ngx_pcre_ver major version found"
|
||||
|
@ -72,7 +77,6 @@ if [ $PCRE != NONE ]; then
|
|||
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
|
||||
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
|
||||
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
|
||||
#CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
@ -106,7 +110,13 @@ else
|
|||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <pcre.h>"
|
||||
ngx_feature_path="/usr/local/include"
|
||||
ngx_feature_libs="-L /usr/local/lib -lpcre"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lpcre"
|
||||
else
|
||||
ngx_feature_libs="-L/usr/local/lib -lpcre"
|
||||
fi
|
||||
|
||||
ngx_feature_test="pcre *re;
|
||||
re = pcre_compile(NULL, 0, NULL, 0, NULL)"
|
||||
. auto/feature
|
||||
|
@ -155,7 +165,13 @@ else
|
|||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <pcre.h>"
|
||||
ngx_feature_path="/usr/pkg/include"
|
||||
ngx_feature_libs="-L /usr/pkg/lib -lpcre"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
|
||||
else
|
||||
ngx_feature_libs="-L/usr/pkg/lib -lpcre"
|
||||
fi
|
||||
|
||||
ngx_feature_test="pcre *re;
|
||||
re = pcre_compile(NULL, 0, NULL, 0, NULL)"
|
||||
. auto/feature
|
||||
|
@ -180,7 +196,13 @@ else
|
|||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <pcre.h>"
|
||||
ngx_feature_path="/opt/local/include"
|
||||
ngx_feature_libs="-L/opt/local/lib -lpcre"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
|
||||
else
|
||||
ngx_feature_libs="-L/opt/local/lib -lpcre"
|
||||
fi
|
||||
|
||||
ngx_feature_test="pcre *re;
|
||||
re = pcre_compile(NULL, 0, NULL, 0, NULL)"
|
||||
. auto/feature
|
||||
|
|
22
auto/modules
22
auto/modules
|
@ -308,8 +308,6 @@ fi
|
|||
|
||||
|
||||
if [ $MAIL_SSL = YES ]; then
|
||||
MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
|
||||
MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
|
||||
have=NGX_MAIL_SSL . auto/have
|
||||
USE_OPENSSL=YES
|
||||
fi
|
||||
|
@ -341,6 +339,26 @@ if [ $MAIL = YES ]; then
|
|||
|
||||
if [ $MAIL_SSL = YES ]; then
|
||||
modules="$modules $MAIL_SSL_MODULE"
|
||||
MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
|
||||
MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
|
||||
fi
|
||||
|
||||
if [ $MAIL_POP3 = YES ]; then
|
||||
modules="$modules $MAIL_POP3_MODULE"
|
||||
MAIL_DEPS="$MAIL_DEPS $MAIL_POP3_DEPS"
|
||||
MAIL_SRCS="$MAIL_SRCS $MAIL_POP3_SRCS"
|
||||
fi
|
||||
|
||||
if [ $MAIL_IMAP = YES ]; then
|
||||
modules="$modules $MAIL_IMAP_MODULE"
|
||||
MAIL_DEPS="$MAIL_DEPS $MAIL_IMAP_DEPS"
|
||||
MAIL_SRCS="$MAIL_SRCS $MAIL_IMAP_SRCS"
|
||||
fi
|
||||
|
||||
if [ $MAIL_SMTP = YES ]; then
|
||||
modules="$modules $MAIL_SMTP_MODULE"
|
||||
MAIL_DEPS="$MAIL_DEPS $MAIL_SMTP_DEPS"
|
||||
MAIL_SRCS="$MAIL_SRCS $MAIL_SMTP_SRCS"
|
||||
fi
|
||||
|
||||
modules="$modules $MAIL_AUTH_HTTP_MODULE"
|
||||
|
|
13
auto/options
13
auto/options
|
@ -22,6 +22,8 @@ NGX_CC_OPT=
|
|||
NGX_LD_OPT=
|
||||
CPU=NO
|
||||
|
||||
NGX_RPATH=NO
|
||||
|
||||
NGX_TEST_BUILD_DEVPOLL=NO
|
||||
NGX_TEST_BUILD_EVENTPORT=NO
|
||||
NGX_TEST_BUILD_EPOLL=NO
|
||||
|
@ -80,6 +82,9 @@ HTTP_STUB_STATUS=NO
|
|||
|
||||
MAIL=NO
|
||||
MAIL_SSL=NO
|
||||
MAIL_POP3=YES
|
||||
MAIL_IMAP=YES
|
||||
MAIL_SMTP=YES
|
||||
|
||||
NGX_ADDONS=
|
||||
|
||||
|
@ -189,6 +194,9 @@ do
|
|||
# STUB
|
||||
--with-imap) MAIL=YES ;;
|
||||
--with-imap_ssl_module) MAIL_SSL=YES ;;
|
||||
--without-mail_pop3_module) MAIL_POP3=NO ;;
|
||||
--without-mail_imap_module) MAIL_IMAP=NO ;;
|
||||
--without-mail_smtp_module) MAIL_SMTP=NO ;;
|
||||
|
||||
--add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
|
||||
|
||||
|
@ -299,8 +307,11 @@ cat << END
|
|||
|
||||
--without-http disable HTTP server
|
||||
|
||||
--with-mail enable IMAP4/POP3/SMTP proxy module
|
||||
--with-mail enable POP3/IMAP4/SMTP proxy module
|
||||
--with-mail_ssl_module enable ngx_mail_ssl_module
|
||||
--without-mail_pop3_module disable ngx_mail_pop3_module
|
||||
--without-mail_imap_module disable ngx_mail_imap_module
|
||||
--without-mail_smtp_module disable ngx_mail_smtp_module
|
||||
|
||||
--add-module=PATH enable an external module
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ CORE_DEPS="$UNIX_DEPS $SOLARIS_DEPS"
|
|||
CORE_SRCS="$UNIX_SRCS $SOLARIS_SRCS "
|
||||
CORE_LIBS="$CORE_LIBS -lsocket -lnsl -lrt"
|
||||
|
||||
NGX_RPATH=YES
|
||||
|
||||
# Solaris's make does not support a blank line between target and rules
|
||||
ngx_spacer=
|
||||
|
||||
|
|
17
auto/sources
17
auto/sources
|
@ -21,6 +21,8 @@ CORE_DEPS="src/core/nginx.h \
|
|||
src/core/ngx_file.h \
|
||||
src/core/ngx_crc.h \
|
||||
src/core/ngx_crc32.h \
|
||||
src/core/ngx_md5.h \
|
||||
src/core/ngx_sha1.h \
|
||||
src/core/ngx_rbtree.h \
|
||||
src/core/ngx_radix_tree.h \
|
||||
src/core/ngx_slab.h \
|
||||
|
@ -423,6 +425,21 @@ MAIL_SRCS="src/mail/ngx_mail.c \
|
|||
src/mail/ngx_mail_handler.c \
|
||||
src/mail/ngx_mail_parse.c"
|
||||
|
||||
MAIL_POP3_MODULE="ngx_mail_pop3_module"
|
||||
MAIL_POP3_DEPS="src/mail/ngx_mail_pop3_module.h"
|
||||
MAIL_POP3_SRCS="src/mail/ngx_mail_pop3_module.c \
|
||||
src/mail/ngx_mail_pop3_handler.c"
|
||||
|
||||
MAIL_IMAP_MODULE="ngx_mail_imap_module"
|
||||
MAIL_IMAP_DEPS="src/mail/ngx_mail_imap_module.h"
|
||||
MAIL_IMAP_SRCS="src/mail/ngx_mail_imap_module.c \
|
||||
src/mail/ngx_mail_imap_handler.c"
|
||||
|
||||
MAIL_SMTP_MODULE="ngx_mail_smtp_module"
|
||||
MAIL_SMTP_DEPS="src/mail/ngx_mail_smtp_module.h"
|
||||
MAIL_SMTP_SRCS="src/mail/ngx_mail_smtp_module.c \
|
||||
src/mail/ngx_mail_smtp_handler.c"
|
||||
|
||||
MAIL_SSL_MODULE="ngx_mail_ssl_module"
|
||||
MAIL_SSL_DEPS="src/mail/ngx_mail_ssl_module.h"
|
||||
MAIL_SSL_SRCS="src/mail/ngx_mail_ssl_module.c"
|
||||
|
|
|
@ -36,5 +36,6 @@ if [ $found = no ]; then
|
|||
found="uint`expr 8 \* $ngx_ptr_size`_t"
|
||||
echo ", $found used"
|
||||
|
||||
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
|
||||
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
|
||||
echo "typedef $found intptr_t;" | sed -e 's/u//g' >> $NGX_AUTO_CONFIG_H
|
||||
fi
|
||||
|
|
|
@ -11,7 +11,7 @@ fastcgi_param DOCUMENT_ROOT $document_root;
|
|||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
|
||||
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||
fastcgi_param SERVER_SOFTWARE nginx;
|
||||
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REMOTE_PORT $remote_port;
|
||||
|
|
|
@ -20,6 +20,7 @@ types {
|
|||
image/x-icon ico;
|
||||
image/x-jng jng;
|
||||
image/x-ms-bmp bmp;
|
||||
image/svg+xml svg;
|
||||
|
||||
application/java-archive jar war ear;
|
||||
application/mac-binhex40 hqx;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 Igor Sysoev
|
||||
* Copyright (C) 2002-2008 Igor Sysoev
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -438,6 +438,9 @@ ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
|
|||
}
|
||||
|
||||
var = ngx_array_push(&ccf->env);
|
||||
if (var == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
var->len = 2;
|
||||
var->data = (u_char *) "TZ";
|
||||
|
@ -796,6 +799,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
|
|||
|
||||
if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
|
||||
|
||||
ngx_set_errno(0);
|
||||
pwd = getpwnam(NGX_USER);
|
||||
if (pwd == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
|
||||
|
@ -806,6 +810,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
|
|||
ccf->username = NGX_USER;
|
||||
ccf->user = pwd->pw_uid;
|
||||
|
||||
ngx_set_errno(0);
|
||||
grp = getgrnam(NGX_GROUP);
|
||||
if (grp == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
|
||||
|
@ -920,6 +925,7 @@ ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ccf->username = (char *) value[1].data;
|
||||
|
||||
ngx_set_errno(0);
|
||||
pwd = getpwnam((const char *) value[1].data);
|
||||
if (pwd == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
|
||||
|
@ -931,6 +937,7 @@ ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
group = (char *) ((cf->args->nelts == 2) ? value[1].data : value[2].data);
|
||||
|
||||
ngx_set_errno(0);
|
||||
grp = getgrnam(group);
|
||||
if (grp == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VERSION "0.5.25"
|
||||
#define NGINX_VERSION "0.5.38"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
|
|
|
@ -117,7 +117,7 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
|
|||
cf->conf_file->file.name.len = filename->len;
|
||||
cf->conf_file->file.name.data = filename->data;
|
||||
cf->conf_file->file.offset = 0;
|
||||
cf->conf_file->file.log = cf->log;;
|
||||
cf->conf_file->file.log = cf->log;
|
||||
cf->conf_file->line = 1;
|
||||
|
||||
block = 0;
|
||||
|
@ -366,7 +366,7 @@ not_allowed:
|
|||
invalid:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid number arguments in \"%s\" directive",
|
||||
"invalid number of arguments in \"%s\" directive",
|
||||
name->data);
|
||||
|
||||
return NGX_ERROR;
|
||||
|
@ -925,7 +925,7 @@ ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
a = (ngx_array_t **) (p + cmd->offset);
|
||||
|
||||
if (*a == NULL) {
|
||||
if (*a == NGX_CONF_UNSET_PTR) {
|
||||
*a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
|
||||
if (*a == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
@ -257,8 +257,8 @@ char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
|
|||
}
|
||||
|
||||
#define ngx_conf_merge_ptr_value(conf, prev, default) \
|
||||
if (conf == NULL) { \
|
||||
conf = (prev == NULL) ? default : prev; \
|
||||
if (conf == NGX_CONF_UNSET_PTR) { \
|
||||
conf = (prev == NGX_CONF_UNSET_PTR) ? default : prev; \
|
||||
}
|
||||
|
||||
#define ngx_conf_merge_uint_value(conf, prev, default) \
|
||||
|
|
|
@ -70,31 +70,20 @@
|
|||
|
||||
#endif
|
||||
|
||||
typedef intptr_t ngx_int_t;
|
||||
typedef uintptr_t ngx_uint_t;
|
||||
typedef intptr_t ngx_flag_t;
|
||||
|
||||
|
||||
/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */
|
||||
#define NGX_INVALID_ARRAY_INDEX 0x80000000
|
||||
|
||||
|
||||
#if 1
|
||||
/* STUB: autoconf */
|
||||
typedef int ngx_int_t;
|
||||
typedef u_int ngx_uint_t;
|
||||
typedef int ngx_flag_t;
|
||||
#define NGX_INT_T_LEN sizeof("-2147483648") - 1
|
||||
|
||||
#else
|
||||
|
||||
typedef long ngx_int_t;
|
||||
typedef u_long ngx_uint_t;
|
||||
typedef long ngx_flag_t;
|
||||
#define NGX_INT_T_LEN sizeof("-9223372036854775808") - 1
|
||||
|
||||
#endif
|
||||
|
||||
#define NGX_INT32_LEN sizeof("-2147483648") - 1
|
||||
#define NGX_INT64_LEN sizeof("-9223372036854775808") - 1
|
||||
|
||||
#if (NGX_PTR_SIZE == 4)
|
||||
#define NGX_INT_T_LEN NGX_INT32_LEN
|
||||
#else
|
||||
#define NGX_INT_T_LEN NGX_INT64_LEN
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NGX_ALIGNMENT
|
||||
#define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */
|
||||
|
@ -108,6 +97,10 @@ typedef long ngx_flag_t;
|
|||
#define ngx_abort abort
|
||||
|
||||
|
||||
/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */
|
||||
#define NGX_INVALID_ARRAY_INDEX 0x80000000
|
||||
|
||||
|
||||
/* TODO: auto_conf: ngx_inline inline __inline __inline__ */
|
||||
#ifndef ngx_inline
|
||||
#define ngx_inline inline
|
||||
|
|
|
@ -123,7 +123,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
|
|||
ntohs(sin->sin_port))
|
||||
- ls[i].addr_text.data;
|
||||
|
||||
ls[i].backlog = -1;
|
||||
ls[i].backlog = NGX_LISTEN_BACKLOG;
|
||||
|
||||
olen = sizeof(int);
|
||||
|
||||
|
@ -735,7 +735,7 @@ ngx_close_connection(ngx_connection_t *c)
|
|||
/* we use ngx_cycle->log because c->log was in c->pool */
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
|
||||
ngx_close_socket_n " failed");
|
||||
ngx_close_socket_n " %d failed", fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -293,6 +293,68 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *confp = conf;
|
||||
|
||||
u_char *p;
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i, right, shift, *access;
|
||||
|
||||
access = (ngx_uint_t *) (confp + cmd->offset);
|
||||
|
||||
if (*access != NGX_CONF_UNSET_UINT) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
*access = 0600;
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
|
||||
p = value[i].data;
|
||||
|
||||
if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) {
|
||||
shift = 6;
|
||||
p += sizeof("user:") - 1;
|
||||
|
||||
} else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) {
|
||||
shift = 3;
|
||||
p += sizeof("group:") - 1;
|
||||
|
||||
} else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) {
|
||||
shift = 0;
|
||||
p += sizeof("all:") - 1;
|
||||
|
||||
} else {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(p, "rw") == 0) {
|
||||
right = 6;
|
||||
|
||||
} else if (ngx_strcmp(p, "r") == 0) {
|
||||
right = 4;
|
||||
|
||||
} else {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
*access |= right << shift;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
invalid:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%V\"", &value[i]);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
|
||||
{
|
||||
|
@ -456,6 +518,9 @@ ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree)
|
|||
}
|
||||
|
||||
ctx->data = data;
|
||||
|
||||
} else {
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
for ( ;; ) {
|
||||
|
@ -581,8 +646,8 @@ done:
|
|||
ngx_free(buf.data);
|
||||
}
|
||||
|
||||
if (ctx->alloc) {
|
||||
ngx_free(ctx->data);
|
||||
if (data) {
|
||||
ngx_free(data);
|
||||
ctx->data = prev;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ void ngx_init_temp_number(void);
|
|||
ngx_atomic_uint_t ngx_next_temp_number(ngx_uint_t collision);
|
||||
|
||||
char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
char *ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
|
||||
#define ngx_conf_merge_path_value(curr, prev, path, l1, l2, l3, clean, cf) \
|
||||
|
|
|
@ -53,7 +53,7 @@ ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len)
|
|||
|
||||
|
||||
void *
|
||||
ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
||||
ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
||||
{
|
||||
void *value;
|
||||
ngx_uint_t i, n, key;
|
||||
|
@ -63,7 +63,7 @@ ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
|||
|
||||
line.len = len;
|
||||
line.data = name;
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wc:\"%V\"", &line);
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wch:\"%V\"", &line);
|
||||
#endif
|
||||
|
||||
n = len;
|
||||
|
@ -112,7 +112,7 @@ ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
value = ngx_hash_find_wildcard(hwc, name, n - 1);
|
||||
value = ngx_hash_find_wc_head(hwc, name, n - 1);
|
||||
|
||||
if (value) {
|
||||
return value;
|
||||
|
@ -128,6 +128,104 @@ ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
|||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_hash_find_wc_tail(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
||||
{
|
||||
void *value;
|
||||
ngx_uint_t i, key;
|
||||
|
||||
#if 0
|
||||
ngx_str_t line;
|
||||
|
||||
line.len = len;
|
||||
line.data = name;
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wct:\"%V\"", &line);
|
||||
#endif
|
||||
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (name[i] == '.') {
|
||||
break;
|
||||
}
|
||||
|
||||
key = ngx_hash(key, name[i]);
|
||||
}
|
||||
|
||||
if (i == len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key);
|
||||
#endif
|
||||
|
||||
value = ngx_hash_find(&hwc->hash, key, name, i);
|
||||
|
||||
if (value) {
|
||||
|
||||
/*
|
||||
* the 2 low bits of value have the special meaning:
|
||||
* 00 - value is data pointer,
|
||||
* 01 - value is pointer to wildcard hash allowing "example.*".
|
||||
*/
|
||||
|
||||
if ((uintptr_t) value & 1) {
|
||||
|
||||
i++;
|
||||
|
||||
hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3);
|
||||
|
||||
value = ngx_hash_find_wc_tail(hwc, &name[i], len - i);
|
||||
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return hwc->value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return hwc->value;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_hash_find_combined(ngx_hash_combined_t *hash, ngx_uint_t key, u_char *name,
|
||||
size_t len)
|
||||
{
|
||||
void *value;
|
||||
|
||||
if (hash->hash.buckets) {
|
||||
value = ngx_hash_find(&hash->hash, key, name, len);
|
||||
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
if (hash->wc_head && hash->wc_head->hash.buckets) {
|
||||
value = ngx_hash_find_wc_head(hash->wc_head, name, len);
|
||||
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
if (hash->wc_tail && hash->wc_tail->hash.buckets) {
|
||||
value = ngx_hash_find_wc_tail(hash->wc_tail, name, len);
|
||||
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#define NGX_HASH_ELT_SIZE(name) \
|
||||
(sizeof(void *) + ngx_align((name)->key.len + 1, sizeof(void *)))
|
||||
|
||||
|
@ -544,7 +642,14 @@ ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&ha->dns_wildcards, ha->temp_pool, asize,
|
||||
if (ngx_array_init(&ha->dns_wc_head, ha->temp_pool, asize,
|
||||
sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize,
|
||||
sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
|
@ -556,9 +661,15 @@ ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ha->dns_wildcards_hash = ngx_pcalloc(ha->temp_pool,
|
||||
sizeof(ngx_array_t) * ha->hsize);
|
||||
if (ha->dns_wildcards_hash == NULL) {
|
||||
ha->dns_wc_head_hash = ngx_pcalloc(ha->temp_pool,
|
||||
sizeof(ngx_array_t) * ha->hsize);
|
||||
if (ha->dns_wc_head_hash == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ha->dns_wc_tail_hash = ngx_pcalloc(ha->temp_pool,
|
||||
sizeof(ngx_array_t) * ha->hsize);
|
||||
if (ha->dns_wc_tail_hash == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -571,37 +682,144 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
|
|||
ngx_uint_t flags)
|
||||
{
|
||||
size_t len;
|
||||
u_char *reverse;
|
||||
u_char *p;
|
||||
ngx_str_t *name;
|
||||
ngx_uint_t i, k, n, skip;
|
||||
ngx_uint_t i, k, n, skip, last;
|
||||
ngx_array_t *keys, *hwc;
|
||||
ngx_hash_key_t *hk;
|
||||
|
||||
if (!(flags & NGX_HASH_WILDCARD_KEY)) {
|
||||
last = key->len;
|
||||
|
||||
/* exact hash */
|
||||
if (flags & NGX_HASH_WILDCARD_KEY) {
|
||||
|
||||
k = 0;
|
||||
/*
|
||||
* supported wildcards:
|
||||
* "*.example.com", ".example.com", and "www.example.*"
|
||||
*/
|
||||
|
||||
n = 0;
|
||||
|
||||
for (i = 0; i < key->len; i++) {
|
||||
if (!(flags & NGX_HASH_READONLY_KEY)) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
|
||||
if (key->data[i] == '*') {
|
||||
if (++n > 1) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
}
|
||||
|
||||
if (key->data[i] == '.' && key->data[i + 1] == '.') {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= ha->hsize;
|
||||
if (key->len > 1 && key->data[0] == '.') {
|
||||
skip = 1;
|
||||
goto wildcard;
|
||||
}
|
||||
|
||||
/* check conflicts in exact hash */
|
||||
if (key->len > 2) {
|
||||
|
||||
if (key->data[0] == '*' && key->data[1] == '.') {
|
||||
skip = 2;
|
||||
goto wildcard;
|
||||
}
|
||||
|
||||
if (key->data[i - 2] == '.' && key->data[i - 1] == '*') {
|
||||
skip = 0;
|
||||
last -= 2;
|
||||
goto wildcard;
|
||||
}
|
||||
}
|
||||
|
||||
if (n) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
}
|
||||
|
||||
/* exact hash */
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < last; i++) {
|
||||
if (!(flags & NGX_HASH_READONLY_KEY)) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
}
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= ha->hsize;
|
||||
|
||||
/* check conflicts in exact hash */
|
||||
|
||||
name = ha->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
||||
if (last != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data, name[i].data, last) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&ha->keys_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*name = *key;
|
||||
|
||||
hk = ngx_array_push(&ha->keys);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *key;
|
||||
hk->key_hash = ngx_hash_key(key->data, last);
|
||||
hk->value = value;
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
|
||||
wildcard:
|
||||
|
||||
/* wildcard hash */
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = skip; i < last; i++) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= ha->hsize;
|
||||
|
||||
if (skip == 1) {
|
||||
|
||||
/* check conflicts in exact hash for ".example.com" */
|
||||
|
||||
name = ha->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = last - skip;
|
||||
|
||||
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
||||
if (key->len != name[i].len) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data, name[i].data, key->len) == 0) {
|
||||
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
@ -620,92 +838,36 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*name = *key;
|
||||
|
||||
hk = ngx_array_push(&ha->keys);
|
||||
if (hk == NULL) {
|
||||
name->len = last - 1;
|
||||
name->data = ngx_palloc(ha->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *key;
|
||||
hk->key_hash = ngx_hash_key(key->data, key->len);
|
||||
hk->value = value;
|
||||
ngx_memcpy(name->data, &key->data[1], name->len);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* wildcard hash */
|
||||
|
||||
skip = (key->data[0] == '*') ? 2 : 1;
|
||||
k = 0;
|
||||
|
||||
for (i = skip; i < key->len; i++) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= ha->hsize;
|
||||
|
||||
if (skip == 1) {
|
||||
|
||||
/* check conflicts in exact hash for ".example.com" */
|
||||
|
||||
name = ha->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = key->len - skip;
|
||||
|
||||
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&ha->keys_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = key->len - 1;
|
||||
name->data = ngx_palloc(ha->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(name->data, &key->data[1], name->len);
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
|
||||
/*
|
||||
* convert "*.example.com" to "com.example.\0"
|
||||
* and ".example.com" to "com.example\0"
|
||||
*/
|
||||
|
||||
reverse = ngx_palloc(ha->temp_pool, key->len);
|
||||
if (reverse == NULL) {
|
||||
p = ngx_palloc(ha->temp_pool, last);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
n = 0;
|
||||
|
||||
for (i = key->len - 1; i; i--) {
|
||||
for (i = last - 1; i; i--) {
|
||||
if (key->data[i] == '.') {
|
||||
ngx_memcpy(&reverse[n], &key->data[i + 1], len);
|
||||
ngx_memcpy(&p[n], &key->data[i + 1], len);
|
||||
n += len;
|
||||
reverse[n++] = '.';
|
||||
p[n++] = '.';
|
||||
len = 0;
|
||||
continue;
|
||||
}
|
||||
|
@ -714,63 +876,80 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
|
|||
}
|
||||
|
||||
if (len) {
|
||||
ngx_memcpy(&reverse[n], &key->data[1], len);
|
||||
ngx_memcpy(&p[n], &key->data[1], len);
|
||||
n += len;
|
||||
}
|
||||
|
||||
reverse[n] = '\0';
|
||||
p[n] = '\0';
|
||||
|
||||
hwc = &ha->dns_wc_head;
|
||||
keys = &ha->dns_wc_head_hash[k];
|
||||
|
||||
hk = ngx_array_push(&ha->dns_wildcards);
|
||||
if (hk == NULL) {
|
||||
} else {
|
||||
|
||||
/* convert "www.example.*" to "www.example\0" */
|
||||
|
||||
last++;
|
||||
|
||||
p = ngx_palloc(ha->temp_pool, last);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key.len = key->len - 1;
|
||||
hk->key.data = reverse;
|
||||
hk->key_hash = 0;
|
||||
hk->value = value;
|
||||
ngx_cpystrn(p, key->data, last);
|
||||
|
||||
|
||||
/* check conflicts in wildcard hash */
|
||||
|
||||
name = ha->dns_wildcards_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = key->len - skip;
|
||||
|
||||
for (i = 0; i < ha->dns_wildcards_hash[k].nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&ha->dns_wildcards_hash[k], ha->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&ha->dns_wildcards_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = key->len - skip;
|
||||
name->data = ngx_palloc(ha->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(name->data, key->data + skip, name->len);
|
||||
hwc = &ha->dns_wc_tail;
|
||||
keys = &ha->dns_wc_tail_hash[k];
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (name) {
|
||||
len = last - skip;
|
||||
|
||||
for (i = 0; i < keys->nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(keys);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = last - skip;
|
||||
name->data = ngx_palloc(ha->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(name->data, key->data + skip, name->len);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,13 @@ typedef struct {
|
|||
typedef ngx_uint_t (*ngx_hash_key_pt) (u_char *data, size_t len);
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *wc_head;
|
||||
ngx_hash_wildcard_t *wc_tail;
|
||||
} ngx_hash_combined_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t *hash;
|
||||
ngx_hash_key_pt key;
|
||||
|
@ -73,8 +80,11 @@ typedef struct {
|
|||
ngx_array_t keys;
|
||||
ngx_array_t *keys_hash;
|
||||
|
||||
ngx_array_t dns_wildcards;
|
||||
ngx_array_t *dns_wildcards_hash;
|
||||
ngx_array_t dns_wc_head;
|
||||
ngx_array_t *dns_wc_head_hash;
|
||||
|
||||
ngx_array_t dns_wc_tail;
|
||||
ngx_array_t *dns_wc_tail_hash;
|
||||
} ngx_hash_keys_arrays_t;
|
||||
|
||||
|
||||
|
@ -87,8 +97,10 @@ typedef struct {
|
|||
|
||||
|
||||
void *ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len);
|
||||
void *ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name,
|
||||
size_t len);
|
||||
void *ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len);
|
||||
void *ngx_hash_find_wc_tail(ngx_hash_wildcard_t *hwc, u_char *name, size_t len);
|
||||
void *ngx_hash_find_combined(ngx_hash_combined_t *hash, ngx_uint_t key,
|
||||
u_char *name, size_t len);
|
||||
|
||||
ngx_int_t ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
||||
ngx_uint_t nelts);
|
||||
|
|
|
@ -214,12 +214,18 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
|
|||
|
||||
in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - m))));
|
||||
|
||||
return NGX_OK;
|
||||
if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
in_cidr->addr &= in_cidr->mask;
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
||||
ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
|
||||
{
|
||||
u_char *p, *host, *port_start;
|
||||
size_t len, port_len;
|
||||
|
@ -267,12 +273,12 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
|
||||
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
|
||||
if (u->addrs == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
saun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un));
|
||||
saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
|
||||
if (saun == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -402,12 +408,12 @@ no_port:
|
|||
|
||||
if (u->host.len) {
|
||||
|
||||
host = ngx_palloc(cf->temp_pool, u->host.len + 1);
|
||||
if (host == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
host = ngx_alloc(u->host.len + 1, pool->log);
|
||||
if (host == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
(void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
|
||||
(void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
|
||||
|
||||
u->addr.in_addr = inet_addr((const char *) host);
|
||||
|
||||
|
@ -415,6 +421,7 @@ no_port:
|
|||
h = gethostbyname((const char *) host);
|
||||
|
||||
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||
ngx_free(host);
|
||||
u->err = "host not found";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -422,6 +429,8 @@ no_port:
|
|||
u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
|
||||
}
|
||||
|
||||
ngx_free(host);
|
||||
|
||||
} else {
|
||||
u->addr.in_addr = INADDR_ANY;
|
||||
}
|
||||
|
@ -447,7 +456,7 @@ no_port:
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_inet_resolve_host(cf, u) != NGX_OK) {
|
||||
if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -456,7 +465,7 @@ no_port:
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
||||
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
|
||||
{
|
||||
u_char *p, *host;
|
||||
size_t len;
|
||||
|
@ -465,7 +474,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
struct hostent *h;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
host = ngx_palloc(cf->temp_pool, u->host.len + 1);
|
||||
host = ngx_alloc(u->host.len + 1, pool->log);
|
||||
if (host == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -479,6 +488,8 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
if (in_addr == INADDR_NONE) {
|
||||
h = gethostbyname((char *) host);
|
||||
|
||||
ngx_free(host);
|
||||
|
||||
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||
u->err = "host not found";
|
||||
return NGX_ERROR;
|
||||
|
@ -493,7 +504,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
|
||||
/* MP: ngx_shared_palloc() */
|
||||
|
||||
u->addrs = ngx_pcalloc(cf->pool, i * sizeof(ngx_peer_addr_t));
|
||||
u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_peer_addr_t));
|
||||
if (u->addrs == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -502,7 +513,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
|
||||
for (i = 0; h->h_addr_list[i] != NULL; i++) {
|
||||
|
||||
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
||||
sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
|
||||
if (sin == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -516,7 +527,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
|
||||
len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
|
||||
|
||||
p = ngx_palloc(cf->pool, len);
|
||||
p = ngx_palloc(pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -529,14 +540,16 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
|
||||
} else {
|
||||
|
||||
ngx_free(host);
|
||||
|
||||
/* MP: ngx_shared_palloc() */
|
||||
|
||||
u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
|
||||
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
|
||||
if (u->addrs == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
||||
sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
|
||||
if (sin == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -550,7 +563,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
|||
u->addrs[0].sockaddr = (struct sockaddr *) sin;
|
||||
u->addrs[0].socklen = sizeof(struct sockaddr_in);
|
||||
|
||||
p = ngx_palloc(cf->pool, u->host.len + sizeof(":65536") - 1);
|
||||
p = ngx_palloc(pool, u->host.len + sizeof(":65536") - 1);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ typedef struct {
|
|||
size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len);
|
||||
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
|
||||
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
|
||||
ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
|
||||
ngx_int_t ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u);
|
||||
ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
|
||||
ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
|
||||
|
||||
|
||||
|
||||
|
|
40
src/core/ngx_md5.h
Normal file
40
src/core/ngx_md5.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_MD5_H_INCLUDED_
|
||||
#define _NGX_MD5_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
#if (NGX_HAVE_OPENSSL_MD5_H)
|
||||
#include <openssl/md5.h>
|
||||
#else
|
||||
#include <md5.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef MD5_CTX ngx_md5_t;
|
||||
|
||||
|
||||
#if (NGX_OPENSSL_MD5)
|
||||
|
||||
#define ngx_md5_init MD5_Init
|
||||
#define ngx_md5_update MD5_Update
|
||||
#define ngx_md5_final MD5_Final
|
||||
|
||||
#else
|
||||
|
||||
#define ngx_md5_init MD5Init
|
||||
#define ngx_md5_update MD5Update
|
||||
#define ngx_md5_final MD5Final
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_MD5_H_INCLUDED_ */
|
|
@ -163,6 +163,7 @@ ngx_palloc(ngx_pool_t *pool, size_t size)
|
|||
|
||||
large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
30
src/core/ngx_sha1.h
Normal file
30
src/core/ngx_sha1.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_SHA1_H_INCLUDED_
|
||||
#define _NGX_SHA1_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
#if (NGX_HAVE_OPENSSL_SHA1_H)
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#include <sha.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef SHA_CTX ngx_sha1_t;
|
||||
|
||||
|
||||
#define ngx_sha1_init SHA1_Init
|
||||
#define ngx_sha1_update SHA1_Update
|
||||
#define ngx_sha1_final SHA1_Final
|
||||
|
||||
|
||||
#endif /* _NGX_SHA1_H_INCLUDED_ */
|
|
@ -111,10 +111,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
|||
|
||||
p += n * sizeof(ngx_slab_page_t);
|
||||
|
||||
/* STUB: possible overflow on 64-bit platform */
|
||||
pages = (ngx_uint_t) ((uint64_t) size * ngx_pagesize
|
||||
/ (ngx_pagesize + sizeof(ngx_slab_page_t))
|
||||
/ ngx_pagesize);
|
||||
pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
|
||||
|
||||
ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
|
||||
|
||||
|
|
|
@ -59,8 +59,9 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
|
|||
* %P ngx_pid_t
|
||||
* %M ngx_msec_t
|
||||
* %r rlim_t
|
||||
* %p pointer
|
||||
* %V pointer to ngx_str_t
|
||||
* %p void *
|
||||
* %V ngx_str_t *
|
||||
* %v ngx_variable_value_t *
|
||||
* %s null-terminated string
|
||||
* %Z '\0'
|
||||
* %N '\n'
|
||||
|
@ -105,21 +106,22 @@ ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
|
|||
u_char *
|
||||
ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
||||
{
|
||||
u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
|
||||
u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
|
||||
/*
|
||||
* really we need temp[NGX_INT64_LEN] only,
|
||||
* but icc issues the warning
|
||||
*/
|
||||
int d;
|
||||
size_t len;
|
||||
uint32_t ui32;
|
||||
int64_t i64;
|
||||
uint64_t ui64;
|
||||
ngx_msec_t ms;
|
||||
ngx_str_t *s;
|
||||
ngx_uint_t width, sign, hexadecimal, max_width;
|
||||
static u_char hex[] = "0123456789abcdef";
|
||||
static u_char HEX[] = "0123456789ABCDEF";
|
||||
int d;
|
||||
size_t len;
|
||||
uint32_t ui32;
|
||||
int64_t i64;
|
||||
uint64_t ui64;
|
||||
ngx_msec_t ms;
|
||||
ngx_uint_t width, sign, hexadecimal, max_width;
|
||||
ngx_str_t *v;
|
||||
ngx_variable_value_t *vv;
|
||||
static u_char hex[] = "0123456789abcdef";
|
||||
static u_char HEX[] = "0123456789ABCDEF";
|
||||
|
||||
if (max == 0) {
|
||||
return buf;
|
||||
|
@ -188,12 +190,23 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||
switch (*fmt) {
|
||||
|
||||
case 'V':
|
||||
s = va_arg(args, ngx_str_t *);
|
||||
v = va_arg(args, ngx_str_t *);
|
||||
|
||||
len = s->len & 0xffff;
|
||||
len = v->len;
|
||||
len = (buf + len < last) ? len : (size_t) (last - buf);
|
||||
|
||||
buf = ngx_cpymem(buf, s->data, len);
|
||||
buf = ngx_cpymem(buf, v->data, len);
|
||||
fmt++;
|
||||
|
||||
continue;
|
||||
|
||||
case 'v':
|
||||
vv = va_arg(args, ngx_variable_value_t *);
|
||||
|
||||
len = vv->len;
|
||||
len = (buf + len < last) ? len : (size_t) (last - buf);
|
||||
|
||||
buf = ngx_cpymem(buf, vv->data, len);
|
||||
fmt++;
|
||||
|
||||
continue;
|
||||
|
@ -429,7 +442,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||
|
||||
|
||||
/*
|
||||
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII string only,
|
||||
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
|
||||
* and implement our own ngx_strcasecmp()/ngx_strncasecmp()
|
||||
* to avoid libc locale overhead. Besides, we use the ngx_uint_t's
|
||||
* instead of the u_char's, because they are slightly faster.
|
||||
|
@ -490,6 +503,95 @@ ngx_strncasecmp(u_char *s1, u_char *s2, size_t n)
|
|||
}
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_strnstr(u_char *s1, char *s2, size_t len)
|
||||
{
|
||||
u_char c1, c2;
|
||||
size_t n;
|
||||
|
||||
c2 = *(u_char *) s2++;
|
||||
|
||||
n = ngx_strlen(s2);
|
||||
|
||||
do {
|
||||
do {
|
||||
if (len-- == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c1 = *s1++;
|
||||
|
||||
if (c1 == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} while (c1 != c2);
|
||||
|
||||
if (n > len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
|
||||
|
||||
return --s1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ngx_strstrn() and ngx_strcasestrn() are intended to search for static
|
||||
* substring with known length in null-terminated string. The argument n
|
||||
* must be length of the second substring - 1.
|
||||
*/
|
||||
|
||||
u_char *
|
||||
ngx_strstrn(u_char *s1, char *s2, size_t n)
|
||||
{
|
||||
u_char c1, c2;
|
||||
|
||||
c2 = *(u_char *) s2++;
|
||||
|
||||
do {
|
||||
do {
|
||||
c1 = *s1++;
|
||||
|
||||
if (c1 == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} while (c1 != c2);
|
||||
|
||||
} while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
|
||||
|
||||
return --s1;
|
||||
}
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_strcasestrn(u_char *s1, char *s2, size_t n)
|
||||
{
|
||||
ngx_uint_t c1, c2;
|
||||
|
||||
c2 = (ngx_uint_t) *s2++;
|
||||
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
|
||||
|
||||
do {
|
||||
do {
|
||||
c1 = (ngx_uint_t) *s1++;
|
||||
|
||||
if (c1 == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
|
||||
|
||||
} while (c1 != c2);
|
||||
|
||||
} while (ngx_strncasecmp(s1, (u_char *) s2, n) != 0);
|
||||
|
||||
return --s1;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
|
||||
{
|
||||
|
@ -1019,13 +1121,13 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
|||
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
/* " ", """, "%", "'", %00-%1F, %7F-%FF */
|
||||
/* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
|
||||
|
||||
static uint32_t html[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
|
||||
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||
0x800000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
|
||||
0x000000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
|
||||
|
||||
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
|
@ -1039,18 +1141,53 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
|||
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
/* " ", """, "%", "'", %00-%1F, %7F-%FF */
|
||||
|
||||
switch (type) {
|
||||
case NGX_ESCAPE_HTML:
|
||||
escape = html;
|
||||
break;
|
||||
case NGX_ESCAPE_ARGS:
|
||||
escape = args;
|
||||
break;
|
||||
default:
|
||||
escape = uri;
|
||||
break;
|
||||
}
|
||||
static uint32_t refresh[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
|
||||
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||
0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
|
||||
|
||||
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
|
||||
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
/* " ", "%", %00-%1F */
|
||||
|
||||
static uint32_t memcached[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
|
||||
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||
0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */
|
||||
|
||||
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
|
||||
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||
};
|
||||
|
||||
/* mail_auth is the same as memcached */
|
||||
|
||||
static uint32_t *map[] =
|
||||
{ uri, args, html, refresh, memcached, memcached };
|
||||
|
||||
|
||||
escape = map[type];
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
|
@ -1106,7 +1243,9 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
|
|||
|
||||
switch (state) {
|
||||
case sw_usual:
|
||||
if (ch == '?' && type == NGX_UNESCAPE_URI) {
|
||||
if (ch == '?'
|
||||
&& (type & (NGX_UNESCAPE_URI|NGX_UNESCAPE_REDIRECT)))
|
||||
{
|
||||
*d++ = ch;
|
||||
goto done;
|
||||
}
|
||||
|
@ -1149,7 +1288,7 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
|
|||
if (ch >= '0' && ch <= '9') {
|
||||
ch = (u_char) ((decoded << 4) + ch - '0');
|
||||
|
||||
if (type == NGX_UNESCAPE_URI) {
|
||||
if (type & NGX_UNESCAPE_REDIRECT) {
|
||||
if (ch > '%' && ch < 0x7f) {
|
||||
*d++ = ch;
|
||||
break;
|
||||
|
@ -1169,7 +1308,17 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
|
|||
if (c >= 'a' && c <= 'f') {
|
||||
ch = (u_char) ((decoded << 4) + c - 'a' + 10);
|
||||
|
||||
if (type == NGX_UNESCAPE_URI) {
|
||||
if (type & NGX_UNESCAPE_URI) {
|
||||
if (ch == '?') {
|
||||
*d++ = ch;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*d++ = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
if (type & NGX_UNESCAPE_REDIRECT) {
|
||||
if (ch == '?') {
|
||||
*d++ = ch;
|
||||
goto done;
|
||||
|
@ -1202,6 +1351,67 @@ done:
|
|||
}
|
||||
|
||||
|
||||
uintptr_t
|
||||
ngx_escape_html(u_char *dst, u_char *src, size_t size)
|
||||
{
|
||||
u_char ch;
|
||||
ngx_uint_t i, len;
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
len = 0;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
switch (*src++) {
|
||||
|
||||
case '<':
|
||||
len += sizeof("<") - 2;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
len += sizeof(">") - 2;
|
||||
break;
|
||||
|
||||
case '&':
|
||||
len += sizeof("&") - 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (uintptr_t) len;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
ch = *src++;
|
||||
|
||||
switch (ch) {
|
||||
|
||||
case '<':
|
||||
*dst++ = '&'; *dst++ = 'l'; *dst++ = 't'; *dst++ = ';';
|
||||
break;
|
||||
|
||||
case '>':
|
||||
*dst++ = '&'; *dst++ = 'g'; *dst++ = 't'; *dst++ = ';';
|
||||
break;
|
||||
|
||||
case '&':
|
||||
*dst++ = '&'; *dst++ = 'a'; *dst++ = 'm'; *dst++ = 'p';
|
||||
*dst++ = ';';
|
||||
break;
|
||||
|
||||
default:
|
||||
*dst++ = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (uintptr_t) dst;
|
||||
}
|
||||
|
||||
|
||||
/* ngx_sort() is implemented as insertion sort because we need stable sort */
|
||||
|
||||
void
|
||||
|
|
|
@ -13,17 +13,28 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
size_t len;
|
||||
u_char *data;
|
||||
size_t len;
|
||||
u_char *data;
|
||||
} ngx_str_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t key;
|
||||
ngx_str_t value;
|
||||
ngx_str_t key;
|
||||
ngx_str_t value;
|
||||
} ngx_keyval_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned len:29;
|
||||
|
||||
unsigned valid:1;
|
||||
unsigned no_cacheable:1;
|
||||
unsigned not_found:1;
|
||||
|
||||
u_char *data;
|
||||
} ngx_variable_value_t;
|
||||
|
||||
|
||||
#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
|
||||
#define ngx_null_string { 0, NULL }
|
||||
|
||||
|
@ -115,6 +126,11 @@ u_char *ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args);
|
|||
ngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);
|
||||
ngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n);
|
||||
|
||||
u_char *ngx_strnstr(u_char *s1, char *s2, size_t n);
|
||||
|
||||
u_char *ngx_strstrn(u_char *s1, char *s2, size_t n);
|
||||
u_char *ngx_strcasestrn(u_char *s1, char *s2, size_t n);
|
||||
|
||||
ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n);
|
||||
ngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n);
|
||||
ngx_int_t ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2);
|
||||
|
@ -139,24 +155,30 @@ size_t ngx_utf_length(u_char *p, size_t n);
|
|||
u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
|
||||
|
||||
|
||||
#define NGX_ESCAPE_URI 0
|
||||
#define NGX_ESCAPE_ARGS 1
|
||||
#define NGX_ESCAPE_HTML 2
|
||||
#define NGX_ESCAPE_URI 0
|
||||
#define NGX_ESCAPE_ARGS 1
|
||||
#define NGX_ESCAPE_HTML 2
|
||||
#define NGX_ESCAPE_REFRESH 3
|
||||
#define NGX_ESCAPE_MEMCACHED 4
|
||||
#define NGX_ESCAPE_MAIL_AUTH 5
|
||||
|
||||
#define NGX_UNESCAPE_URI 1
|
||||
#define NGX_UNESCAPE_URI 1
|
||||
#define NGX_UNESCAPE_REDIRECT 2
|
||||
|
||||
uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
|
||||
ngx_uint_t type);
|
||||
void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
|
||||
uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
|
||||
|
||||
|
||||
|
||||
void ngx_sort(void *base, size_t n, size_t size,
|
||||
int (*cmp)(const void *, const void *));
|
||||
#define ngx_qsort qsort
|
||||
#define ngx_qsort qsort
|
||||
|
||||
|
||||
#define ngx_value_helper(n) #n
|
||||
#define ngx_value(n) ngx_value_helper(n)
|
||||
#define ngx_value_helper(n) #n
|
||||
#define ngx_value(n) ngx_value_helper(n)
|
||||
|
||||
|
||||
#endif /* _NGX_STRING_H_INCLUDED_ */
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
static ngx_int_t ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_aio_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, u_int flags);
|
||||
static ngx_int_t ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags);
|
||||
static ngx_int_t ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags);
|
||||
|
||||
|
@ -100,21 +102,21 @@ ngx_aio_done(ngx_cycle_t *cycle)
|
|||
/* the event adding and deleting are needed for the listening sockets */
|
||||
|
||||
static ngx_int_t
|
||||
ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
return ngx_kqueue_module_ctx.actions.add(ev, event, flags);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
return ngx_kqueue_module_ctx.actions.del(ev, event, flags);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_aio_del_connection(ngx_connection_t *c, u_int flags)
|
||||
ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define POLLREMOVE 0x0800
|
||||
#define DP_POLL 0xD001
|
||||
#define DP_ISPOLLED 0xD002
|
||||
|
||||
struct dvpoll {
|
||||
struct pollfd *dp_fds;
|
||||
|
@ -26,16 +27,19 @@ struct dvpoll {
|
|||
|
||||
|
||||
typedef struct {
|
||||
u_int changes;
|
||||
u_int events;
|
||||
ngx_uint_t changes;
|
||||
ngx_uint_t events;
|
||||
} ngx_devpoll_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_devpoll_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle,
|
||||
ngx_msec_t timer, ngx_uint_t flags);
|
||||
|
||||
|
@ -44,7 +48,7 @@ static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf);
|
|||
|
||||
static int dp = -1;
|
||||
static struct pollfd *change_list, *event_list;
|
||||
static u_int nchanges, max_changes, nevents;
|
||||
static ngx_uint_t nchanges, max_changes, nevents;
|
||||
|
||||
static ngx_event_t **change_index;
|
||||
|
||||
|
@ -208,7 +212,7 @@ ngx_devpoll_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
#if (NGX_DEBUG)
|
||||
ngx_connection_t *c;
|
||||
|
@ -221,7 +225,7 @@ ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
#if (NGX_DEBUG)
|
||||
c = ev->data;
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"devpoll add event: fd:%d ev:%04Xd", c->fd, event);
|
||||
"devpoll add event: fd:%d ev:%04Xi", c->fd, event);
|
||||
#endif
|
||||
|
||||
ev->active = 1;
|
||||
|
@ -231,7 +235,7 @@ ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_event_t *e;
|
||||
ngx_connection_t *c;
|
||||
|
@ -243,7 +247,7 @@ ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
#endif
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"devpoll del event: fd:%d ev:%04Xd", c->fd, event);
|
||||
"devpoll del event: fd:%d ev:%04Xi", c->fd, event);
|
||||
|
||||
if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
|
@ -252,10 +256,16 @@ ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
ev->active = 0;
|
||||
|
||||
if (flags & NGX_CLOSE_EVENT) {
|
||||
e = (event == POLLIN) ? c->write : c->read;
|
||||
|
||||
if (e) {
|
||||
e->active = 0;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/* restore the paired event if it exists */
|
||||
/* restore the pair event if it exists */
|
||||
|
||||
if (event == POLLIN) {
|
||||
e = c->write;
|
||||
|
@ -275,7 +285,7 @@ ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
size_t n;
|
||||
ngx_connection_t *c;
|
||||
|
@ -283,7 +293,7 @@ ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
|
|||
c = ev->data;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"devpoll fd:%d ev:%04Xd fl:%04Xd", c->fd, event, flags);
|
||||
"devpoll fd:%d ev:%04Xi fl:%04Xi", c->fd, event, flags);
|
||||
|
||||
if (nchanges >= max_changes) {
|
||||
ngx_log_error(NGX_LOG_WARN, ev->log, 0,
|
||||
|
@ -300,7 +310,7 @@ ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
|
|||
}
|
||||
|
||||
change_list[nchanges].fd = c->fd;
|
||||
change_list[nchanges].events = event;
|
||||
change_list[nchanges].events = (short) event;
|
||||
change_list[nchanges].revents = 0;
|
||||
|
||||
change_index[nchanges] = ev;
|
||||
|
@ -327,13 +337,15 @@ ngx_int_t
|
|||
ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags)
|
||||
{
|
||||
int events, revents;
|
||||
int events, revents, rc;
|
||||
size_t n;
|
||||
ngx_fd_t fd;
|
||||
ngx_err_t err;
|
||||
ngx_int_t i;
|
||||
ngx_uint_t level;
|
||||
ngx_event_t *rev, *wev, **queue;
|
||||
ngx_connection_t *c;
|
||||
struct pollfd pfd;
|
||||
struct dvpoll dvp;
|
||||
|
||||
/* NGX_TIMER_INFINITE == INFTIM */
|
||||
|
@ -353,7 +365,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
}
|
||||
|
||||
dvp.dp_fds = event_list;
|
||||
dvp.dp_nfds = nevents;
|
||||
dvp.dp_nfds = (int) nevents;
|
||||
dvp.dp_timeout = timer;
|
||||
events = ioctl(dp, DP_POLL, &dvp);
|
||||
|
||||
|
@ -398,34 +410,77 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
ngx_mutex_lock(ngx_posted_events_mutex);
|
||||
|
||||
for (i = 0; i < events; i++) {
|
||||
c = ngx_cycle->files[event_list[i].fd];
|
||||
|
||||
if (c->fd == -1) {
|
||||
if (c->read->closed) {
|
||||
continue;
|
||||
fd = event_list[i].fd;
|
||||
revents = event_list[i].revents;
|
||||
|
||||
c = ngx_cycle->files[fd];
|
||||
|
||||
if (c == NULL || c->fd == -1) {
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = 0;
|
||||
pfd.revents = 0;
|
||||
|
||||
rc = ioctl(dp, DP_ISPOLLED, &pfd);
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case -1:
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
"ioctl(DP_ISPOLLED) failed for socket %d, event",
|
||||
fd, revents);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"phantom event %04Xd for closed and removed socket %d",
|
||||
revents, fd);
|
||||
break;
|
||||
|
||||
default:
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"unexpected event %04Xd for closed and removed socket %d, ",
|
||||
"ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd",
|
||||
revents, fd, rc, pfd.fd, pfd.revents);
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLREMOVE;
|
||||
pfd.revents = 0;
|
||||
|
||||
if (write(dp, &pfd, sizeof(struct pollfd))
|
||||
!= (ssize_t) sizeof(struct pollfd))
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
"write(/dev/poll) for %d failed, fd");
|
||||
}
|
||||
|
||||
if (close(fd) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
"close(%d) failed", fd);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event");
|
||||
continue;
|
||||
}
|
||||
|
||||
revents = event_list[i].revents;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
|
||||
event_list[i].fd, event_list[i].events, revents);
|
||||
fd, event_list[i].events, revents);
|
||||
|
||||
if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd",
|
||||
event_list[i].fd, event_list[i].events, revents);
|
||||
fd, event_list[i].events, revents);
|
||||
}
|
||||
|
||||
if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"strange ioctl(DP_POLL) events "
|
||||
"fd:%d ev:%04Xd rev:%04Xd",
|
||||
event_list[i].fd, event_list[i].events, revents);
|
||||
fd, event_list[i].events, revents);
|
||||
}
|
||||
|
||||
if ((revents & (POLLERR|POLLHUP|POLLNVAL))
|
||||
|
|
|
@ -66,16 +66,19 @@ int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout)
|
|||
|
||||
|
||||
typedef struct {
|
||||
u_int events;
|
||||
ngx_uint_t events;
|
||||
} ngx_epoll_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_epoll_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_epoll_add_connection(ngx_connection_t *c);
|
||||
static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c, u_int flags);
|
||||
static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags);
|
||||
|
||||
|
@ -84,7 +87,7 @@ static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf);
|
|||
|
||||
static int ep = -1;
|
||||
static struct epoll_event *event_list;
|
||||
static u_int nevents;
|
||||
static ngx_uint_t nevents;
|
||||
|
||||
|
||||
static ngx_str_t epoll_name = ngx_string("epoll");
|
||||
|
@ -205,7 +208,7 @@ ngx_epoll_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
int op;
|
||||
uint32_t events, prev;
|
||||
|
@ -240,7 +243,7 @@ ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
op = EPOLL_CTL_ADD;
|
||||
}
|
||||
|
||||
ee.events = events | flags;
|
||||
ee.events = events | (uint32_t) flags;
|
||||
ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
|
@ -263,7 +266,7 @@ ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
int op;
|
||||
uint32_t prev;
|
||||
|
@ -295,7 +298,7 @@ ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
if (e->active) {
|
||||
op = EPOLL_CTL_MOD;
|
||||
ee.events = prev | flags;
|
||||
ee.events = prev | (uint32_t) flags;
|
||||
ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
|
||||
|
||||
} else {
|
||||
|
@ -345,10 +348,10 @@ ngx_epoll_add_connection(ngx_connection_t *c)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_epoll_del_connection(ngx_connection_t *c, u_int flags)
|
||||
ngx_epoll_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
||||
{
|
||||
int op;
|
||||
struct epoll_event ee;
|
||||
int op;
|
||||
struct epoll_event ee;
|
||||
|
||||
/*
|
||||
* when the file descriptor is closed the epoll automatically deletes
|
||||
|
@ -399,7 +402,7 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"epoll timer: %M", timer);
|
||||
|
||||
events = epoll_wait(ep, event_list, nevents, timer);
|
||||
events = epoll_wait(ep, event_list, (int) nevents, timer);
|
||||
|
||||
if (events == -1) {
|
||||
err = ngx_errno;
|
||||
|
|
|
@ -40,11 +40,15 @@ typedef struct port_notify {
|
|||
void *portnfy_user; /* user defined */
|
||||
} port_notify_t;
|
||||
|
||||
typedef struct itimerspec { /* definition per POSIX.4 */
|
||||
struct timespec it_interval; /* timer period */
|
||||
struct timespec it_value; /* timer expiration */
|
||||
#if (__FreeBSD_version < 700005)
|
||||
|
||||
typedef struct itimerspec { /* definition per POSIX.4 */
|
||||
struct timespec it_interval;/* timer period */
|
||||
struct timespec it_value; /* timer expiration */
|
||||
} itimerspec_t;
|
||||
|
||||
#endif
|
||||
|
||||
int port_create(void)
|
||||
{
|
||||
return -1;
|
||||
|
@ -87,16 +91,16 @@ int timer_delete(timer_t timerid)
|
|||
|
||||
|
||||
typedef struct {
|
||||
u_int events;
|
||||
ngx_uint_t events;
|
||||
} ngx_eventport_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_eventport_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, int event,
|
||||
u_int flags);
|
||||
static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, int event,
|
||||
u_int flags);
|
||||
static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle,
|
||||
ngx_msec_t timer, ngx_uint_t flags);
|
||||
|
||||
|
@ -105,8 +109,8 @@ static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);
|
|||
|
||||
static int ep = -1;
|
||||
static port_event_t *event_list;
|
||||
static u_int nevents;
|
||||
static timer_t event_timer = -1;
|
||||
static ngx_uint_t nevents;
|
||||
static timer_t event_timer = (timer_t) -1;
|
||||
|
||||
static ngx_str_t eventport_name = ngx_string("eventport");
|
||||
|
||||
|
@ -237,13 +241,13 @@ ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer)
|
|||
static void
|
||||
ngx_eventport_done(ngx_cycle_t *cycle)
|
||||
{
|
||||
if (event_timer != -1) {
|
||||
if (event_timer != (timer_t) -1) {
|
||||
if (timer_delete(event_timer) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
"timer_delete() failed");
|
||||
}
|
||||
|
||||
event_timer = -1;
|
||||
event_timer = (timer_t) -1;
|
||||
}
|
||||
|
||||
if (close(ep) == -1) {
|
||||
|
@ -261,9 +265,9 @@ ngx_eventport_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
int events, prev;
|
||||
ngx_int_t events, prev;
|
||||
ngx_event_t *e;
|
||||
ngx_connection_t *c;
|
||||
|
||||
|
@ -291,7 +295,7 @@ ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"eventport add event: fd:%d ev:%04Xd", c->fd, events);
|
||||
"eventport add event: fd:%d ev:%04Xi", c->fd, events);
|
||||
|
||||
if (port_associate(ep, PORT_SOURCE_FD, c->fd, events,
|
||||
(void *) ((uintptr_t) ev | ev->instance))
|
||||
|
@ -310,7 +314,7 @@ ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_eventport_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_event_t *e;
|
||||
ngx_connection_t *c;
|
||||
|
@ -340,7 +344,7 @@ ngx_eventport_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
if (e->oneshot) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"eventport change event: fd:%d ev:%04Xd", c->fd, event);
|
||||
"eventport change event: fd:%d ev:%04Xi", c->fd, event);
|
||||
|
||||
if (port_associate(ep, PORT_SOURCE_FD, c->fd, event,
|
||||
(void *) ((uintptr_t) ev | ev->instance))
|
||||
|
@ -396,7 +400,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
|
||||
events = 1;
|
||||
|
||||
n = port_getn(ep, event_list, nevents, &events, tp);
|
||||
n = port_getn(ep, event_list, (u_int) nevents, &events, tp);
|
||||
|
||||
err = ngx_errno;
|
||||
|
||||
|
@ -514,6 +518,10 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
|
||||
} else {
|
||||
rev->handler(rev);
|
||||
|
||||
if (ev->closed) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rev->accept) {
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static ngx_thread_value_t __stdcall ngx_iocp_timer(void *data);
|
||||
static void ngx_iocp_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key);
|
||||
static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, u_int flags);
|
||||
static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t key);
|
||||
static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags);
|
||||
static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags);
|
||||
static void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
|
||||
|
@ -186,7 +187,7 @@ ngx_iocp_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
|
||||
ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t key)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
||||
|
@ -196,7 +197,7 @@ ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
|
|||
c->write->active = 1;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"iocp add: fd:%d k:%d ov:%p", c->fd, key, &ev->ovlp);
|
||||
"iocp add: fd:%d k:%ui ov:%p", c->fd, key, &ev->ovlp);
|
||||
|
||||
if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
|
@ -209,7 +210,7 @@ ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_iocp_del_connection(ngx_connection_t *c, u_int flags)
|
||||
ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
||||
{
|
||||
#if 0
|
||||
if (flags & NGX_CLOSE_EVENT) {
|
||||
|
|
|
@ -11,16 +11,19 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
int changes;
|
||||
int events;
|
||||
ngx_uint_t changes;
|
||||
ngx_uint_t events;
|
||||
} ngx_kqueue_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_kqueue_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
|
||||
static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try);
|
||||
static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags);
|
||||
|
@ -43,7 +46,7 @@ int ngx_kqueue = -1;
|
|||
|
||||
static struct kevent *change_list, *change_list0, *change_list1;
|
||||
static struct kevent *event_list;
|
||||
static int max_changes, nchanges, nevents;
|
||||
static ngx_uint_t max_changes, nchanges, nevents;
|
||||
|
||||
#if (NGX_THREADS)
|
||||
static ngx_mutex_t *list_mutex;
|
||||
|
@ -151,7 +154,9 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
|
|||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
|
||||
if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
|
||||
== -1)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
"kevent() failed");
|
||||
return NGX_ERROR;
|
||||
|
@ -273,7 +278,7 @@ ngx_kqueue_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
#if 0
|
||||
|
@ -289,7 +294,7 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
#if 0
|
||||
|
||||
if (ev->index < (u_int) nchanges
|
||||
if (ev->index < nchanges
|
||||
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
|
||||
== (uintptr_t) ev)
|
||||
{
|
||||
|
@ -301,10 +306,10 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
*/
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"kevent activated: %d: ft:%d",
|
||||
"kevent activated: %d: ft:%i",
|
||||
ngx_event_ident(ev->data), event);
|
||||
|
||||
if (ev->index < (u_int) --nchanges) {
|
||||
if (ev->index < --nchanges) {
|
||||
e = (ngx_event_t *)
|
||||
((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
|
||||
change_list[ev->index] = change_list[nchanges];
|
||||
|
@ -337,7 +342,7 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_event_t *e;
|
||||
|
@ -347,19 +352,19 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
ngx_mutex_lock(list_mutex);
|
||||
|
||||
if (ev->index < (u_int) nchanges
|
||||
if (ev->index < nchanges
|
||||
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
|
||||
== (uintptr_t) ev)
|
||||
{
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"kevent deleted: %d: ft:%d",
|
||||
"kevent deleted: %d: ft:%i",
|
||||
ngx_event_ident(ev->data), event);
|
||||
|
||||
/* if the event is still not passed to a kernel we will not pass it */
|
||||
|
||||
nchanges--;
|
||||
|
||||
if (ev->index < (u_int) nchanges) {
|
||||
if (ev->index < nchanges) {
|
||||
e = (ngx_event_t *)
|
||||
((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
|
||||
change_list[ev->index] = change_list[nchanges];
|
||||
|
@ -396,7 +401,7 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
|
||||
ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
|
||||
{
|
||||
struct kevent *kev;
|
||||
struct timespec ts;
|
||||
|
@ -404,8 +409,8 @@ ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
|
|||
|
||||
c = ev->data;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"kevent set event: %d: ft:%d fl:%04Xd",
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"kevent set event: %d: ft:%i fl:%04Xi",
|
||||
c->fd, filter, flags);
|
||||
|
||||
if (nchanges >= max_changes) {
|
||||
|
@ -415,7 +420,9 @@ ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
|
|||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
|
||||
if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
|
||||
== -1)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -426,8 +433,8 @@ ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
|
|||
kev = &change_list[nchanges];
|
||||
|
||||
kev->ident = c->fd;
|
||||
kev->filter = filter;
|
||||
kev->flags = flags;
|
||||
kev->filter = (short) filter;
|
||||
kev->flags = (u_short) flags;
|
||||
kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
|
||||
|
||||
if (filter == EVFILT_VNODE) {
|
||||
|
@ -482,7 +489,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
n = 0;
|
||||
|
||||
} else {
|
||||
n = nchanges;
|
||||
n = (int) nchanges;
|
||||
nchanges = 0;
|
||||
}
|
||||
|
||||
|
@ -510,7 +517,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"kevent timer: %M, changes: %d", timer, n);
|
||||
|
||||
events = kevent(ngx_kqueue, change_list, n, event_list, nevents, tp);
|
||||
events = kevent(ngx_kqueue, change_list, n, event_list, (int) nevents, tp);
|
||||
|
||||
if (events == -1) {
|
||||
err = ngx_errno;
|
||||
|
@ -696,7 +703,7 @@ ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try)
|
|||
change_list = change_list0;
|
||||
}
|
||||
|
||||
n = nchanges;
|
||||
n = (int) nchanges;
|
||||
nchanges = 0;
|
||||
|
||||
ngx_mutex_unlock(list_mutex);
|
||||
|
@ -758,8 +765,8 @@ ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf)
|
|||
{
|
||||
ngx_kqueue_conf_t *kcf = conf;
|
||||
|
||||
ngx_conf_init_value(kcf->changes, 512);
|
||||
ngx_conf_init_value(kcf->events, 512);
|
||||
ngx_conf_init_uint_value(kcf->changes, 512);
|
||||
ngx_conf_init_uint_value(kcf->events, 512);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
@ -13,5 +13,4 @@ extern ngx_module_t ngx_kqueue_module;
|
|||
extern ngx_event_module_t ngx_kqueue_module_ctx;
|
||||
|
||||
|
||||
|
||||
#endif /* _NGX_KQUEUE_MODULE_H_INCLUDED_ */
|
||||
|
|
|
@ -11,15 +11,17 @@
|
|||
|
||||
static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_poll_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags);
|
||||
static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf);
|
||||
|
||||
|
||||
static struct pollfd *event_list;
|
||||
static int nevents;
|
||||
static ngx_int_t nevents;
|
||||
|
||||
|
||||
static ngx_str_t poll_name = ngx_string("poll");
|
||||
|
@ -108,7 +110,7 @@ ngx_poll_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_event_t *e;
|
||||
ngx_connection_t *c;
|
||||
|
@ -119,7 +121,7 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
if (ev->index != NGX_INVALID_INDEX) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
|
||||
"poll event fd:%d ev:%d is already set", c->fd, event);
|
||||
"poll event fd:%d ev:%i is already set", c->fd, event);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -137,11 +139,11 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"poll add event: fd:%d ev:%d", c->fd, event);
|
||||
"poll add event: fd:%d ev:%i", c->fd, event);
|
||||
|
||||
if (e == NULL || e->index == NGX_INVALID_INDEX) {
|
||||
event_list[nevents].fd = c->fd;
|
||||
event_list[nevents].events = event;
|
||||
event_list[nevents].events = (short) event;
|
||||
event_list[nevents].revents = 0;
|
||||
|
||||
ev->index = nevents;
|
||||
|
@ -149,9 +151,9 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
} else {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"poll add index: %d", e->index);
|
||||
"poll add index: %i", e->index);
|
||||
|
||||
event_list[e->index].events |= event;
|
||||
event_list[e->index].events |= (short) event;
|
||||
ev->index = e->index;
|
||||
}
|
||||
|
||||
|
@ -160,7 +162,7 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_event_t *e;
|
||||
ngx_connection_t *c;
|
||||
|
@ -171,7 +173,7 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
if (ev->index == NGX_INVALID_INDEX) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
|
||||
"poll event fd:%d ev:%d is already deleted",
|
||||
"poll event fd:%d ev:%i is already deleted",
|
||||
c->fd, event);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -190,15 +192,15 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"poll del event: fd:%d ev:%d", c->fd, event);
|
||||
"poll del event: fd:%d ev:%i", c->fd, event);
|
||||
|
||||
if (e == NULL || e->index == NGX_INVALID_INDEX) {
|
||||
nevents--;
|
||||
|
||||
if (ev->index < (u_int) nevents) {
|
||||
if (ev->index < (ngx_uint_t) nevents) {
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"index: copy event %d to %d", nevents, ev->index);
|
||||
"index: copy event %ui to %i", nevents, ev->index);
|
||||
|
||||
event_list[ev->index] = event_list[nevents];
|
||||
|
||||
|
@ -209,11 +211,11 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
"unexpected last event");
|
||||
|
||||
} else {
|
||||
if (c->read->index == (u_int) nevents) {
|
||||
if (c->read->index == (ngx_uint_t) nevents) {
|
||||
c->read->index = ev->index;
|
||||
}
|
||||
|
||||
if (c->write->index == (u_int) nevents) {
|
||||
if (c->write->index == (ngx_uint_t) nevents) {
|
||||
c->write->index = ev->index;
|
||||
}
|
||||
}
|
||||
|
@ -221,9 +223,9 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
} else {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"poll del index: %d", e->index);
|
||||
"poll del index: %i", e->index);
|
||||
|
||||
event_list[e->index].events &= ~event;
|
||||
event_list[e->index].events &= (short) ~event;
|
||||
}
|
||||
|
||||
ev->index = NGX_INVALID_INDEX;
|
||||
|
|
|
@ -11,9 +11,14 @@
|
|||
|
||||
#if (NGX_TEST_BUILD_RTSIG)
|
||||
|
||||
#define F_SETSIG 10
|
||||
#ifdef SIGRTMIN
|
||||
#define si_fd _reason.__spare__.__spare2__[0]
|
||||
#else
|
||||
#define SIGRTMIN 33
|
||||
#define si_fd __spare__[0]
|
||||
#endif
|
||||
|
||||
#define F_SETSIG 10
|
||||
#define KERN_RTSIGNR 30
|
||||
#define KERN_RTSIGMAX 31
|
||||
|
||||
|
@ -29,10 +34,10 @@ int ngx_linux_rtsig_max;
|
|||
|
||||
|
||||
typedef struct {
|
||||
int signo;
|
||||
ngx_int_t overflow_events;
|
||||
ngx_int_t overflow_test;
|
||||
ngx_int_t overflow_threshold;
|
||||
ngx_uint_t signo;
|
||||
ngx_uint_t overflow_events;
|
||||
ngx_uint_t overflow_test;
|
||||
ngx_uint_t overflow_threshold;
|
||||
} ngx_rtsig_conf_t;
|
||||
|
||||
|
||||
|
@ -41,7 +46,8 @@ extern ngx_event_module_t ngx_poll_module_ctx;
|
|||
static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_rtsig_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c);
|
||||
static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags);
|
||||
static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle,
|
||||
ngx_msec_t timer, ngx_uint_t flags);
|
||||
static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle,
|
||||
|
@ -143,8 +149,8 @@ ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
|
|||
rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, rtscf->signo);
|
||||
sigaddset(&set, rtscf->signo + 1);
|
||||
sigaddset(&set, (int) rtscf->signo);
|
||||
sigaddset(&set, (int) rtscf->signo + 1);
|
||||
sigaddset(&set, SIGIO);
|
||||
sigaddset(&set, SIGALRM);
|
||||
|
||||
|
@ -188,7 +194,7 @@ ngx_rtsig_done(ngx_cycle_t *cycle)
|
|||
static ngx_int_t
|
||||
ngx_rtsig_add_connection(ngx_connection_t *c)
|
||||
{
|
||||
int signo;
|
||||
ngx_uint_t signo;
|
||||
ngx_rtsig_conf_t *rtscf;
|
||||
|
||||
if (c->read->accept && c->read->disabled) {
|
||||
|
@ -211,7 +217,7 @@ ngx_rtsig_add_connection(ngx_connection_t *c)
|
|||
signo = rtscf->signo + c->read->instance;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"rtsig add connection: fd:%d signo:%d", c->fd, signo);
|
||||
"rtsig add connection: fd:%d signo:%ui", c->fd, signo);
|
||||
|
||||
if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
|
@ -219,7 +225,7 @@ ngx_rtsig_add_connection(ngx_connection_t *c)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (fcntl(c->fd, F_SETSIG, signo) == -1) {
|
||||
if (fcntl(c->fd, F_SETSIG, (int) signo) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
"fcntl(F_SETSIG) failed");
|
||||
return NGX_ERROR;
|
||||
|
@ -247,7 +253,7 @@ ngx_rtsig_add_connection(ngx_connection_t *c)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags)
|
||||
ngx_rtsig_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
||||
{
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"rtsig del connection: fd:%d", c->fd);
|
||||
|
@ -348,7 +354,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|||
|
||||
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
|
||||
|
||||
if (signo == rtscf->signo || signo == rtscf->signo + 1) {
|
||||
if (signo == (int) rtscf->signo || signo == (int) rtscf->signo + 1) {
|
||||
|
||||
if (overflow && (ngx_uint_t) si.si_fd > overflow_current) {
|
||||
return NGX_OK;
|
||||
|
@ -363,7 +369,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
instance = signo - rtscf->signo;
|
||||
instance = signo - (int) rtscf->signo;
|
||||
|
||||
rev = c->read;
|
||||
|
||||
|
@ -459,8 +465,8 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
{
|
||||
int name[2], rtsig_max, rtsig_nr, events, ready;
|
||||
size_t len;
|
||||
ngx_int_t tested, n, i;
|
||||
ngx_err_t err;
|
||||
ngx_uint_t tested, n, i;
|
||||
ngx_event_t *rev, *wev, **queue;
|
||||
ngx_connection_t *c;
|
||||
ngx_rtsig_conf_t *rtscf;
|
||||
|
@ -638,7 +644,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|||
* "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
|
||||
*/
|
||||
|
||||
if (rtsig_max / rtscf->overflow_threshold < rtsig_nr) {
|
||||
if (rtsig_max / (int) rtscf->overflow_threshold < rtsig_nr) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"rtsig queue state: %d/%d",
|
||||
rtsig_nr, rtsig_max);
|
||||
|
@ -703,19 +709,18 @@ ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf)
|
|||
ngx_rtsig_conf_t *rtscf = conf;
|
||||
|
||||
/* LinuxThreads use the first 3 RT signals */
|
||||
ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10);
|
||||
ngx_conf_init_uint_value(rtscf->signo, SIGRTMIN + 10);
|
||||
|
||||
ngx_conf_init_value(rtscf->overflow_events, 16);
|
||||
ngx_conf_init_value(rtscf->overflow_test, 32);
|
||||
ngx_conf_init_value(rtscf->overflow_threshold, 10);
|
||||
ngx_conf_init_uint_value(rtscf->overflow_events, 16);
|
||||
ngx_conf_init_uint_value(rtscf->overflow_test, 32);
|
||||
ngx_conf_init_uint_value(rtscf->overflow_threshold, 10);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
|
||||
void *post, void *data)
|
||||
ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
if (ngx_linux_rtsig_max) {
|
||||
return ngx_conf_check_num_bounds(cf, post, data);
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
|
||||
static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static void ngx_select_done(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_select_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_select_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event,
|
||||
ngx_uint_t flags);
|
||||
static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags);
|
||||
static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
|
||||
|
@ -25,10 +27,10 @@ static fd_set work_read_fd_set;
|
|||
static fd_set work_write_fd_set;
|
||||
|
||||
#if (NGX_WIN32)
|
||||
static int max_read;
|
||||
static int max_write;
|
||||
static ngx_uint_t max_read;
|
||||
static ngx_uint_t max_write;
|
||||
#else
|
||||
static int max_fd;
|
||||
static ngx_int_t max_fd;
|
||||
#endif
|
||||
|
||||
static ngx_uint_t nevents;
|
||||
|
@ -129,18 +131,18 @@ ngx_select_done(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = ev->data;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"select add event fd:%d ev:%d", c->fd, event);
|
||||
"select add event fd:%d ev:%i", c->fd, event);
|
||||
|
||||
if (ev->index != NGX_INVALID_INDEX) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
|
||||
"select event fd:%d ev:%d is already set", c->fd, event);
|
||||
"select event fd:%d ev:%i is already set", c->fd, event);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -190,7 +192,7 @@ ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
||||
|
@ -203,7 +205,7 @@ ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"select del event fd:%d ev:%d", c->fd, event);
|
||||
"select del event fd:%d ev:%i", c->fd, event);
|
||||
|
||||
#if (NGX_WIN32)
|
||||
|
||||
|
@ -231,7 +233,7 @@ ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
|
|||
|
||||
#endif
|
||||
|
||||
if (ev->index < (u_int) --nevents) {
|
||||
if (ev->index < --nevents) {
|
||||
event_index[ev->index] = event_index[nevents];
|
||||
event_index[ev->index]->index = ev->index;
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_handle_read_event(ngx_event_t *rev, u_int flags)
|
||||
ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
|
||||
{
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
|
@ -1038,8 +1038,9 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
#if (NGX_DEBUG)
|
||||
ngx_event_conf_t *ecf = conf;
|
||||
|
||||
ngx_event_debug_t *dc;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_event_debug_t *dc;
|
||||
struct hostent *h;
|
||||
ngx_inet_cidr_t in_cidr;
|
||||
|
||||
|
@ -1056,13 +1057,21 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
if (dc->addr != INADDR_NONE) {
|
||||
dc->mask = 0xffffffff;
|
||||
return NGX_OK;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_OK) {
|
||||
rc = ngx_ptocidr(&value[1], &in_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) {
|
||||
dc->mask = in_cidr.mask;
|
||||
dc->addr = in_cidr.addr;
|
||||
return NGX_OK;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
h = gethostbyname((char *) value[1].data);
|
||||
|
@ -1084,7 +1093,7 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ struct ngx_event_s {
|
|||
|
||||
unsigned accept:1;
|
||||
|
||||
/* used to detect the stale events in kqueue, rt signals and epoll */
|
||||
/* used to detect the stale events in kqueue, rtsig, and epoll */
|
||||
unsigned instance:1;
|
||||
|
||||
/*
|
||||
|
@ -126,7 +126,7 @@ struct ngx_event_s {
|
|||
|
||||
#endif
|
||||
|
||||
u_int index;
|
||||
ngx_uint_t index;
|
||||
|
||||
ngx_log_t *log;
|
||||
|
||||
|
@ -182,7 +182,7 @@ struct ngx_event_s {
|
|||
|
||||
/* event should not cross cache line in SMP */
|
||||
|
||||
int padding[NGX_EVENT_T_PADDING];
|
||||
uint32_t padding[NGX_EVENT_T_PADDING];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
@ -195,14 +195,14 @@ typedef struct {
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t (*add)(ngx_event_t *ev, int event, u_int flags);
|
||||
ngx_int_t (*del)(ngx_event_t *ev, int event, u_int flags);
|
||||
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);
|
||||
|
||||
ngx_int_t (*enable)(ngx_event_t *ev, int event, u_int flags);
|
||||
ngx_int_t (*disable)(ngx_event_t *ev, int event, u_int flags);
|
||||
ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
|
||||
ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
|
||||
|
||||
ngx_int_t (*add_conn)(ngx_connection_t *c);
|
||||
ngx_int_t (*del_conn)(ngx_connection_t *c, u_int flags);
|
||||
ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
|
||||
|
||||
ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
|
||||
ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
|
@ -247,8 +247,7 @@ extern ngx_event_actions_t ngx_event_actions;
|
|||
#define NGX_USE_LOWAT_EVENT 0x00000010
|
||||
|
||||
/*
|
||||
* The event filter requires to do i/o operation until EAGAIN:
|
||||
* epoll, rt signals.
|
||||
* The event filter requires to do i/o operation until EAGAIN: epoll, rtsig.
|
||||
*/
|
||||
#define NGX_USE_GREEDY_EVENT 0x00000020
|
||||
|
||||
|
@ -258,7 +257,7 @@ extern ngx_event_actions_t ngx_event_actions;
|
|||
#define NGX_USE_EPOLL_EVENT 0x00000040
|
||||
|
||||
/*
|
||||
* No need to add or delete the event filters: rt signals.
|
||||
* No need to add or delete the event filters: rtsig.
|
||||
*/
|
||||
#define NGX_USE_RTSIG_EVENT 0x00000080
|
||||
|
||||
|
@ -276,13 +275,13 @@ extern ngx_event_actions_t ngx_event_actions;
|
|||
|
||||
/*
|
||||
* The event filter has no opaque data and requires file descriptors table:
|
||||
* poll, /dev/poll, rt signals.
|
||||
* poll, /dev/poll, rtsig.
|
||||
*/
|
||||
#define NGX_USE_FD_EVENT 0x00000400
|
||||
|
||||
/*
|
||||
* The event module handles periodic or absolute timer event by itself:
|
||||
* kqueue in FreeBSD 4.4 and NetBSD 2.0, Solaris 10's event ports.
|
||||
* kqueue in FreeBSD 4.4, NetBSD 2.0, and MacOSX 10.4, Solaris 10's event ports.
|
||||
*/
|
||||
#define NGX_USE_TIMER_EVENT 0x00000800
|
||||
|
||||
|
@ -290,17 +289,26 @@ extern ngx_event_actions_t ngx_event_actions;
|
|||
* All event filters on file descriptor are deleted after a notification:
|
||||
* Solaris 10's event ports.
|
||||
*/
|
||||
#define NGX_USE_EVENTPORT_EVENT 0x00001000
|
||||
#define NGX_USE_EVENTPORT_EVENT 0x00001000
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The event filter is deleted before the closing file.
|
||||
* Has no meaning for select, poll, kqueue, epoll.
|
||||
* /dev/poll: we need to flush POLLREMOVE event before closing file
|
||||
* The event filter is deleted just before the closing file.
|
||||
* Has no meaning for select and poll.
|
||||
* kqueue, epoll, rtsig, eventport: allows to avoid explicit delete,
|
||||
* because filter automatically is deleted
|
||||
* on file close,
|
||||
*
|
||||
* /dev/poll: we need to flush POLLREMOVE event
|
||||
* before closing file.
|
||||
*/
|
||||
|
||||
#define NGX_CLOSE_EVENT 1
|
||||
|
||||
/*
|
||||
* disable temporarily event filter, this may avoid locks
|
||||
* in kernel malloc()/free(): kqueue.
|
||||
*/
|
||||
#define NGX_DISABLE_EVENT 2
|
||||
|
||||
|
||||
|
@ -489,7 +497,7 @@ u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
|||
|
||||
|
||||
void ngx_process_events_and_timers(ngx_cycle_t *cycle);
|
||||
ngx_int_t ngx_handle_read_event(ngx_event_t *rev, u_int flags);
|
||||
ngx_int_t ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
|
||||
ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <ngx_event.h>
|
||||
|
||||
|
||||
static int ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
|
||||
static ngx_int_t ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_ctx_t *ctx);
|
||||
static void ngx_event_busy_lock_handler(ngx_event_t *ev);
|
||||
static void ngx_event_busy_lock_posted_handler(ngx_event_t *ev);
|
||||
|
@ -65,14 +65,14 @@ ngx_event_busy_lock(ngx_event_busy_lock_t *bl, ngx_event_busy_lock_ctx_t *ctx)
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_ctx_t *ctx)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
|
||||
ngx_mutex_lock(bl->mutex);
|
||||
|
||||
rc = ngx_event_busy_lock_look_cachable(bl, ctx);
|
||||
rc = ngx_event_busy_lock_look_cacheable(bl, ctx);
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
|
||||
"event busy lock: %d w:%d mw:%d",
|
||||
|
@ -201,14 +201,14 @@ ngx_event_busy_lock_cancel(ngx_event_busy_lock_t *bl,
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_ctx_t *ctx)
|
||||
{
|
||||
ngx_int_t free;
|
||||
ngx_uint_t i, bit, cachable, mask;
|
||||
ngx_uint_t i, bit, cacheable, mask;
|
||||
|
||||
bit = 0;
|
||||
cachable = 0;
|
||||
cacheable = 0;
|
||||
free = -1;
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
|
@ -227,14 +227,14 @@ ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
|
|||
ctx->slot = i;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
cachable++;
|
||||
cacheable++;
|
||||
|
||||
} else if (free == -1) {
|
||||
free = i;
|
||||
}
|
||||
|
||||
if (cachable == bl->cachable) {
|
||||
if (free == -1 && cachable < bl->max_busy) {
|
||||
if (cacheable == bl->cacheable) {
|
||||
if (free == -1 && cacheable < bl->max_busy) {
|
||||
free = i + 1;
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
|
|||
bl->md5_mask[free / 8] |= 1 << (free & 7);
|
||||
ctx->slot = free;
|
||||
|
||||
bl->cachable++;
|
||||
bl->cacheable++;
|
||||
bl->busy++;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
|
@ -34,7 +34,7 @@ struct ngx_event_busy_lock_ctx_s {
|
|||
typedef struct {
|
||||
u_char *md5_mask;
|
||||
char *md5;
|
||||
ngx_uint_t cachable;
|
||||
ngx_uint_t cacheable;
|
||||
|
||||
ngx_uint_t busy;
|
||||
ngx_uint_t max_busy;
|
||||
|
@ -53,7 +53,7 @@ typedef struct {
|
|||
|
||||
ngx_int_t ngx_event_busy_lock(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_ctx_t *ctx);
|
||||
ngx_int_t ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
|
||||
ngx_int_t ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_ctx_t *ctx);
|
||||
void ngx_event_busy_unlock(ngx_event_busy_lock_t *bl,
|
||||
ngx_event_busy_lock_ctx_t *ctx);
|
||||
|
|
|
@ -14,7 +14,7 @@ ngx_int_t
|
|||
ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
||||
{
|
||||
int rc;
|
||||
u_int event;
|
||||
ngx_int_t event;
|
||||
ngx_err_t err;
|
||||
ngx_uint_t level;
|
||||
ngx_socket_t s;
|
||||
|
@ -85,6 +85,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||
c->recv_chain = ngx_recv_chain;
|
||||
c->send_chain = ngx_send_chain;
|
||||
|
||||
c->sendfile = 1;
|
||||
|
||||
c->log_error = pc->log_error;
|
||||
|
||||
if (pc->sockaddr->sa_family != AF_INET) {
|
||||
|
|
|
@ -13,50 +13,56 @@
|
|||
#include <ngx_event.h>
|
||||
|
||||
|
||||
#define NGX_PEER_KEEPALIVE 1
|
||||
#define NGX_PEER_NEXT 2
|
||||
#define NGX_PEER_FAILED 4
|
||||
#define NGX_PEER_KEEPALIVE 1
|
||||
#define NGX_PEER_NEXT 2
|
||||
#define NGX_PEER_FAILED 4
|
||||
|
||||
|
||||
typedef struct ngx_peer_connection_s ngx_peer_connection_t;
|
||||
|
||||
typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
#if (NGX_SSL)
|
||||
typedef void (*ngx_event_save_peer_pt)(ngx_peer_connection_t *pc, void *data);
|
||||
#endif
|
||||
typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data,
|
||||
ngx_uint_t state);
|
||||
#if (NGX_SSL)
|
||||
|
||||
typedef ngx_int_t (*ngx_event_set_peer_session_pt)(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
typedef void (*ngx_event_save_peer_session_pt)(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
|
||||
struct ngx_peer_connection_s {
|
||||
ngx_connection_t *connection;
|
||||
ngx_connection_t *connection;
|
||||
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
ngx_str_t *name;
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
ngx_str_t *name;
|
||||
|
||||
ngx_uint_t tries;
|
||||
ngx_uint_t tries;
|
||||
|
||||
ngx_event_get_peer_pt get;
|
||||
ngx_event_free_peer_pt free;
|
||||
void *data;
|
||||
ngx_event_get_peer_pt get;
|
||||
ngx_event_free_peer_pt free;
|
||||
void *data;
|
||||
|
||||
#if (NGX_SSL)
|
||||
ngx_ssl_session_t *ssl_session;
|
||||
ngx_event_save_peer_pt save_session;
|
||||
ngx_event_set_peer_session_pt set_session;
|
||||
ngx_event_save_peer_session_pt save_session;
|
||||
#endif
|
||||
|
||||
#if (NGX_THREADS)
|
||||
ngx_atomic_t *lock;
|
||||
ngx_atomic_t *lock;
|
||||
#endif
|
||||
|
||||
int rcvbuf;
|
||||
int rcvbuf;
|
||||
|
||||
ngx_log_t *log;
|
||||
ngx_log_t *log;
|
||||
|
||||
unsigned cached:1;
|
||||
unsigned log_error:2; /* ngx_connection_log_error_e */
|
||||
unsigned cached:1;
|
||||
|
||||
/* ngx_connection_log_error_e */
|
||||
unsigned log_error:2;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ static void ngx_ssl_read_handler(ngx_event_t *rev);
|
|||
static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
|
||||
static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
|
||||
ngx_err_t err, char *text);
|
||||
static void ngx_ssl_clear_error(ngx_log_t *log);
|
||||
|
||||
static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
|
||||
void *data);
|
||||
|
@ -186,6 +187,11 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
|||
SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* we need this option because in ngx_ssl_send_chain()
|
||||
* we may switch to a buffered write and may copy leftover part of
|
||||
* previously unbuffered data to our internal buffer
|
||||
*/
|
||||
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
|
||||
SSL_CTX_set_read_ahead(ssl->ctx, 1);
|
||||
|
@ -404,6 +410,8 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
int n, sslerr;
|
||||
ngx_err_t err;
|
||||
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
n = SSL_do_handshake(c->ssl->connection);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
|
||||
|
@ -602,6 +610,8 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
|
|||
|
||||
bytes = 0;
|
||||
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
/*
|
||||
* SSL_read() may return data in parts, so try to read
|
||||
* until SSL_read() would return no data
|
||||
|
@ -784,7 +794,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
|
||||
/* the maximum limit size is the maximum uint32_t value - the page size */
|
||||
|
||||
if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) {
|
||||
if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) {
|
||||
limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
|
||||
}
|
||||
|
||||
|
@ -882,6 +892,8 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|||
int n, sslerr;
|
||||
ngx_err_t err;
|
||||
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
|
||||
|
||||
n = SSL_write(c->ssl->connection, data, size);
|
||||
|
@ -965,9 +977,8 @@ ngx_ssl_read_handler(ngx_event_t *rev)
|
|||
ngx_int_t
|
||||
ngx_ssl_shutdown(ngx_connection_t *c)
|
||||
{
|
||||
int n, sslerr, mode;
|
||||
ngx_err_t err;
|
||||
ngx_uint_t again;
|
||||
int n, sslerr, mode;
|
||||
ngx_err_t err;
|
||||
|
||||
if (c->timedout) {
|
||||
mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
|
||||
|
@ -986,40 +997,31 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|||
|
||||
SSL_set_shutdown(c->ssl->connection, mode);
|
||||
|
||||
again = 0;
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
n = SSL_shutdown(c->ssl->connection);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
|
||||
|
||||
sslerr = 0;
|
||||
|
||||
for ( ;; ) {
|
||||
n = SSL_shutdown(c->ssl->connection);
|
||||
/* SSL_shutdown() never return -1, on error it return 0 */
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
|
||||
|
||||
if (n == 1 || (n == 0 && c->timedout)) {
|
||||
SSL_free(c->ssl->connection);
|
||||
c->ssl = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
again = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!again) {
|
||||
if (n != 1 && ERR_peek_error()) {
|
||||
sslerr = SSL_get_error(c->ssl->connection, n);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"SSL_get_error: %d", sslerr);
|
||||
}
|
||||
|
||||
if (again
|
||||
|| sslerr == SSL_ERROR_WANT_READ
|
||||
|| sslerr == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
|
||||
SSL_free(c->ssl->connection);
|
||||
c->ssl = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
|
||||
c->read->handler = ngx_ssl_shutdown_handler;
|
||||
c->write->handler = ngx_ssl_shutdown_handler;
|
||||
|
||||
|
@ -1031,7 +1033,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (again || sslerr == SSL_ERROR_WANT_READ) {
|
||||
if (sslerr == SSL_ERROR_WANT_READ) {
|
||||
ngx_add_timer(c->read, 30000);
|
||||
}
|
||||
|
||||
|
@ -1112,12 +1114,24 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_ssl_clear_error(ngx_log_t *log)
|
||||
{
|
||||
while (ERR_peek_error()) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
||||
|
||||
void ngx_cdecl
|
||||
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
||||
{
|
||||
u_long n;
|
||||
va_list args;
|
||||
u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
|
||||
u_long n;
|
||||
va_list args;
|
||||
u_char *p, *last;
|
||||
u_char errstr[NGX_MAX_CONF_ERRSTR];
|
||||
|
||||
last = errstr + NGX_MAX_CONF_ERRSTR;
|
||||
|
||||
|
@ -1127,7 +1141,7 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
|||
|
||||
p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);
|
||||
|
||||
while (p < last) {
|
||||
for ( ;; ) {
|
||||
|
||||
n = ERR_get_error();
|
||||
|
||||
|
@ -1135,6 +1149,10 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
|||
break;
|
||||
}
|
||||
|
||||
if (p >= last) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*p++ = ' ';
|
||||
|
||||
ERR_error_string_n(n, (char *) p, last - p);
|
||||
|
@ -1588,7 +1606,7 @@ ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
|
|||
}
|
||||
|
||||
if (n++ != 0 && sess_id->expire > tp->sec) {
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
sess_id->next->prev = sess_id->prev;
|
||||
|
|
|
@ -21,7 +21,7 @@ static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p);
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
|
||||
ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
|
||||
{
|
||||
u_int flags;
|
||||
ngx_event_t *rev, *wev;
|
||||
|
@ -192,7 +192,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
|
|||
chain->buf = b;
|
||||
chain->next = NULL;
|
||||
|
||||
} else if (!p->cachable
|
||||
} else if (!p->cacheable
|
||||
&& p->downstream->data == p->output_ctx
|
||||
&& p->downstream->write->ready
|
||||
&& !p->downstream->write->delayed)
|
||||
|
@ -209,7 +209,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
|
|||
|
||||
break;
|
||||
|
||||
} else if (p->cachable
|
||||
} else if (p->cacheable
|
||||
|| p->temp_file->offset < p->max_temp_file_size)
|
||||
{
|
||||
|
||||
|
@ -406,7 +406,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
|
|||
}
|
||||
}
|
||||
|
||||
if (p->cachable && p->in) {
|
||||
if (p->cacheable && p->in) {
|
||||
if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
@ -421,6 +421,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
{
|
||||
u_char *prev;
|
||||
size_t bsize;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t flush, prev_last_shadow;
|
||||
ngx_chain_t *out, **ll, *cl;
|
||||
ngx_connection_t *downstream;
|
||||
|
@ -451,7 +452,13 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
cl->buf->recycled = 0;
|
||||
}
|
||||
|
||||
if (p->output_filter(p->output_ctx, p->out) == NGX_ERROR) {
|
||||
rc = p->output_filter(p->output_ctx, p->out);
|
||||
|
||||
if (downstream->destroyed) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
p->downstream_error = 1;
|
||||
return ngx_event_pipe_drain_chains(p);
|
||||
}
|
||||
|
@ -467,12 +474,13 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
cl->buf->recycled = 0;
|
||||
}
|
||||
|
||||
if (p->output_filter(p->output_ctx, p->in) == NGX_ERROR) {
|
||||
rc = p->output_filter(p->output_ctx, p->in);
|
||||
|
||||
if (downstream->destroyed) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
if (downstream->destroyed) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
p->downstream_error = 1;
|
||||
return ngx_event_pipe_drain_chains(p);
|
||||
}
|
||||
|
@ -542,7 +550,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
|
||||
ngx_event_pipe_free_shadow_raw_buf(&p->free_raw_bufs, cl->buf);
|
||||
|
||||
} else if (!p->cachable && p->in) {
|
||||
} else if (!p->cacheable && p->in) {
|
||||
cl = p->in;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||
|
@ -602,7 +610,13 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
break;
|
||||
}
|
||||
|
||||
if (p->output_filter(p->output_ctx, out) == NGX_ERROR) {
|
||||
rc = p->output_filter(p->output_ctx, out);
|
||||
|
||||
if (downstream->destroyed) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
p->downstream_error = 1;
|
||||
return ngx_event_pipe_drain_chains(p);
|
||||
}
|
||||
|
@ -612,7 +626,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
for (cl = p->free; cl; cl = cl->next) {
|
||||
|
||||
if (cl->buf->temp_file) {
|
||||
if (p->cachable || !p->cyclic_temp_file) {
|
||||
if (p->cacheable || !p->cyclic_temp_file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -659,7 +673,7 @@ ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
|
|||
out = p->in;
|
||||
}
|
||||
|
||||
if (!p->cachable) {
|
||||
if (!p->cacheable) {
|
||||
|
||||
size = 0;
|
||||
cl = out;
|
||||
|
|
|
@ -47,7 +47,7 @@ struct ngx_event_pipe_s {
|
|||
void *output_ctx;
|
||||
|
||||
unsigned read:1;
|
||||
unsigned cachable:1;
|
||||
unsigned cacheable:1;
|
||||
unsigned single_buf:1;
|
||||
unsigned free_bufs:1;
|
||||
unsigned upstream_done:1;
|
||||
|
@ -86,7 +86,7 @@ struct ngx_event_pipe_s {
|
|||
};
|
||||
|
||||
|
||||
ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, int do_write);
|
||||
ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write);
|
||||
ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf);
|
||||
ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b);
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
{
|
||||
ngx_http_access_loc_conf_t *alcf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_inet_cidr_t in_cidr;
|
||||
ngx_http_access_rule_t *rule;
|
||||
|
@ -173,12 +174,19 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_ERROR) {
|
||||
rc = ngx_ptocidr(&value[1], &in_cidr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||
&value[1]);
|
||||
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]);
|
||||
}
|
||||
|
||||
rule->mask = in_cidr.mask;
|
||||
rule->addr = in_cidr.addr;
|
||||
|
||||
|
|
|
@ -236,6 +236,11 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
|
|||
rc = ngx_http_send_header(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
|
||||
if (ngx_close_dir(&dir) == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||
ngx_close_dir_n " \"%V\" failed", &path);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -397,7 +397,7 @@ ngx_http_browser_add_variable(ngx_conf_t *cf)
|
|||
|
||||
for (var = ngx_http_browsers; var->name.len; var++) {
|
||||
|
||||
v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGABLE);
|
||||
v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGEABLE);
|
||||
if (v == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
bcf->modern_browser_value->len = value[1].len;
|
||||
bcf->modern_browser_value->valid = 1;
|
||||
bcf->modern_browser_value->no_cachable = 0;
|
||||
bcf->modern_browser_value->no_cacheable = 0;
|
||||
bcf->modern_browser_value->not_found = 0;
|
||||
bcf->modern_browser_value->data = value[1].data;
|
||||
|
||||
|
@ -698,7 +698,7 @@ ngx_http_ancient_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
bcf->ancient_browser_value->len = value[1].len;
|
||||
bcf->ancient_browser_value->valid = 1;
|
||||
bcf->ancient_browser_value->no_cachable = 0;
|
||||
bcf->ancient_browser_value->no_cacheable = 0;
|
||||
bcf->ancient_browser_value->not_found = 0;
|
||||
bcf->ancient_browser_value->data = value[1].data;
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
|
|||
{
|
||||
u_char *ct;
|
||||
ngx_int_t charset, source_charset;
|
||||
ngx_str_t *mc, *from, *to;
|
||||
ngx_str_t *mc, *from, *to, s;
|
||||
ngx_uint_t n;
|
||||
ngx_http_charset_t *charsets;
|
||||
ngx_http_charset_ctx_t *ctx;
|
||||
|
@ -256,8 +256,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
charset = ngx_http_charset_get_charset(charsets, n,
|
||||
(ngx_str_t *) vv);
|
||||
s.len = vv->len;
|
||||
s.data = vv->data;
|
||||
|
||||
charset = ngx_http_charset_get_charset(charsets, n, &s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,8 +305,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
source_charset = ngx_http_charset_get_charset(charsets, n,
|
||||
(ngx_str_t *) vv);
|
||||
s.len = vv->len;
|
||||
s.data = vv->data;
|
||||
|
||||
source_charset = ngx_http_charset_get_charset(charsets, n, &s);
|
||||
}
|
||||
|
||||
if (charset != NGX_HTTP_NO_CHARSET) {
|
||||
|
@ -362,8 +366,8 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
|
|||
no_charset_map:
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"no \"charset_map\" between the charsets "
|
||||
"\"%V\" and \"%V\"", from, to);
|
||||
"no \"charset_map\" between the charsets \"%V\" and \"%V\"",
|
||||
from, to);
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
@ -373,17 +377,16 @@ static ngx_int_t
|
|||
ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
|
||||
ngx_str_t *charset)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
|
||||
len = charset->len & 0xffff;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (charsets[i].name.len != len) {
|
||||
if (charsets[i].name.len != charset->len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(charsets[i].name.data, charset->data, len) == 0) {
|
||||
if (ngx_strncasecmp(charsets[i].name.data, charset->data, charset->len)
|
||||
== 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -1459,6 +1462,12 @@ ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (conf->source_charset >= NGX_HTTP_CHARSET_VAR
|
||||
|| conf->charset >= NGX_HTTP_CHARSET_VAR)
|
||||
{
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
mcf = ngx_http_conf_get_module_main_conf(cf,
|
||||
ngx_http_charset_filter_module);
|
||||
recode = mcf->recodes.elts;
|
||||
|
@ -1516,9 +1525,8 @@ ngx_http_charset_postconfiguration(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
" no \"charset_map\" between the charsets "
|
||||
"\"%V\" and \"%V\"",
|
||||
&charset[c].name, &charset[recode[i].dst].name);
|
||||
"no \"charset_map\" between the charsets \"%V\" and \"%V\"",
|
||||
&charset[c].name, &charset[recode[i].dst].name);
|
||||
return NGX_ERROR;
|
||||
|
||||
next:
|
||||
|
|
|
@ -57,8 +57,6 @@ static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt);
|
|||
static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err,
|
||||
ngx_int_t not_found, char *failed, u_char *path);
|
||||
static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path);
|
||||
static char *ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
|
@ -94,9 +92,9 @@ static ngx_command_t ngx_http_dav_commands[] = {
|
|||
|
||||
{ ngx_string("dav_access"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
|
||||
ngx_http_dav_access,
|
||||
ngx_conf_set_access_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
offsetof(ngx_http_dav_loc_conf_t, access),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
|
@ -239,9 +237,7 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
|
|||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
if (ngx_change_file_access(temp->data, dlcf->access)
|
||||
== NGX_FILE_ERROR)
|
||||
{
|
||||
if (ngx_change_file_access(temp->data, dlcf->access) == NGX_FILE_ERROR) {
|
||||
err = ngx_errno;
|
||||
not_found = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
failed = ngx_change_file_access_n;
|
||||
|
@ -1108,66 +1104,6 @@ ngx_http_dav_location(ngx_http_request_t *r, u_char *path)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_dav_loc_conf_t *lcf = conf;
|
||||
|
||||
u_char *p;
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i, right, shift;
|
||||
|
||||
if (lcf->access != NGX_CONF_UNSET_UINT) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
lcf->access = 0600;
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
|
||||
p = value[i].data;
|
||||
|
||||
if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) {
|
||||
shift = 6;
|
||||
p += sizeof("user:") - 1;
|
||||
|
||||
} else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) {
|
||||
shift = 3;
|
||||
p += sizeof("group:") - 1;
|
||||
|
||||
} else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) {
|
||||
shift = 0;
|
||||
p += sizeof("all:") - 1;
|
||||
|
||||
} else {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(p, "rw") == 0) {
|
||||
right = 6;
|
||||
|
||||
} else if (ngx_strcmp(p, "r") == 0) {
|
||||
right = 4;
|
||||
|
||||
} else {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
lcf->access |= right << shift;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
invalid:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid value \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
|
@ -127,12 +127,10 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r)
|
|||
|
||||
if (r->method == NGX_HTTP_HEAD) {
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
r->headers_out.content_length_n = sizeof(ngx_empty_gif);
|
||||
r->headers_out.last_modified_time = 23349600;
|
||||
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
|
||||
return rc;
|
||||
}
|
||||
return ngx_http_send_header(r);
|
||||
}
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
|
|
|
@ -37,6 +37,12 @@ typedef enum {
|
|||
} ngx_http_fastcgi_state_e;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_char *start;
|
||||
u_char *end;
|
||||
} ngx_http_fastcgi_split_part_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_fastcgi_state_e state;
|
||||
u_char *pos;
|
||||
|
@ -45,7 +51,9 @@ typedef struct {
|
|||
size_t length;
|
||||
size_t padding;
|
||||
|
||||
ngx_uint_t fastcgi_stdout;
|
||||
ngx_uint_t fastcgi_stdout; /* unsigned :1 */
|
||||
|
||||
ngx_array_t *split_parts;
|
||||
} ngx_http_fastcgi_ctx_t;
|
||||
|
||||
|
||||
|
@ -116,6 +124,8 @@ static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
|
|||
|
||||
static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
|
||||
|
@ -192,6 +202,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
|
|||
offsetof(ngx_http_fastcgi_loc_conf_t, index),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("fastcgi_store"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_fastcgi_store,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("fastcgi_store_access"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
|
||||
ngx_conf_set_access_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.store_access),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("fastcgi_ignore_client_abort"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
|
@ -408,7 +432,7 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
|
|||
if (r->subrequest_in_memory) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"ngx_http_fastcgi_module does not support "
|
||||
"subrequest in memeory");
|
||||
"subrequest in memory");
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
@ -481,7 +505,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
|||
if (flcf->params_len) {
|
||||
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
|
||||
|
||||
ngx_http_script_flush_no_cachable_variables(r, flcf->flushes);
|
||||
ngx_http_script_flush_no_cacheable_variables(r, flcf->flushes);
|
||||
le.flushed = 1;
|
||||
|
||||
le.ip = flcf->params_len->elts;
|
||||
|
@ -527,7 +551,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
|||
|
||||
if (len > 65535) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"fastcgi: the request record is too big");
|
||||
"fastcgi request record is too big: %uz", len);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -840,15 +864,18 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
|
|||
static ngx_int_t
|
||||
ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *start, *last;
|
||||
u_char *p, *start, *last, *part_start;
|
||||
size_t size;
|
||||
ngx_str_t *status_line, line, *pattern;
|
||||
ngx_int_t rc, status;
|
||||
ngx_buf_t buf;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_fastcgi_ctx_t *f;
|
||||
ngx_http_upstream_header_t *hh;
|
||||
ngx_http_fastcgi_loc_conf_t *flcf;
|
||||
ngx_http_fastcgi_split_part_t *part;
|
||||
ngx_http_upstream_main_conf_t *umcf;
|
||||
|
||||
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
|
||||
|
@ -858,7 +885,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
if (f == NULL) {
|
||||
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
|
||||
if (f == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
|
||||
|
@ -966,7 +993,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
|
||||
for (i = 0; i < flcf->catch_stderr->nelts; i++) {
|
||||
if (ngx_strstr(line.data, pattern[i].data)) {
|
||||
return NGX_HTTP_BAD_GATEWAY;
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1017,6 +1044,8 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
|
||||
for ( ;; ) {
|
||||
|
||||
part_start = u->buffer.pos;
|
||||
|
||||
rc = ngx_http_parse_header_line(r, &u->buffer);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -1032,33 +1061,81 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
|
||||
h = ngx_list_push(&u->headers_in.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (f->split_parts && f->split_parts->nelts) {
|
||||
|
||||
part = f->split_parts->elts;
|
||||
size = u->buffer.pos - part_start;
|
||||
|
||||
for (i = 0; i < f->split_parts->nelts; i++) {
|
||||
size += part[i].end - part[i].start;
|
||||
}
|
||||
|
||||
p = ngx_palloc(r->pool, size);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
buf.pos = p;
|
||||
|
||||
for (i = 0; i < f->split_parts->nelts; i++) {
|
||||
p = ngx_cpymem(p, part[i].start,
|
||||
part[i].end - part[i].start);
|
||||
}
|
||||
|
||||
p = ngx_cpymem(p, part_start, u->buffer.pos - part_start);
|
||||
|
||||
buf.last = p;
|
||||
|
||||
f->split_parts->nelts = 0;
|
||||
|
||||
rc = ngx_http_parse_header_line(r, &buf);
|
||||
|
||||
h->key.len = r->header_name_end - r->header_name_start;
|
||||
h->key.data = r->header_name_start;
|
||||
h->key.data[h->key.len] = '\0';
|
||||
|
||||
h->value.len = r->header_end - r->header_start;
|
||||
h->value.data = r->header_start;
|
||||
h->value.data[h->value.len] = '\0';
|
||||
|
||||
h->lowcase_key = ngx_palloc(r->pool, h->key.len);
|
||||
if (h->lowcase_key == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
h->key.len = r->header_name_end - r->header_name_start;
|
||||
h->value.len = r->header_end - r->header_start;
|
||||
|
||||
h->key.data = ngx_palloc(r->pool,
|
||||
h->key.len + 1 + h->value.len + 1
|
||||
+ h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->value.data = h->key.data + h->key.len + 1;
|
||||
h->lowcase_key = h->key.data + h->key.len + 1
|
||||
+ h->value.len + 1;
|
||||
|
||||
ngx_cpystrn(h->key.data, r->header_name_start,
|
||||
h->key.len + 1);
|
||||
ngx_cpystrn(h->value.data, r->header_start,
|
||||
h->value.len + 1);
|
||||
}
|
||||
|
||||
h->hash = r->header_hash;
|
||||
|
||||
h->key.len = r->header_name_end - r->header_name_start;
|
||||
h->value.len = r->header_end - r->header_start;
|
||||
|
||||
h->key.data = ngx_palloc(r->pool,
|
||||
h->key.len + 1 + h->value.len + 1 + h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
h->value.data = h->key.data + h->key.len + 1;
|
||||
h->lowcase_key = h->key.data + h->key.len + 1
|
||||
+ h->value.len + 1;
|
||||
|
||||
ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
|
||||
ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
|
||||
|
||||
if (h->key.len == r->lowcase_index) {
|
||||
ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
|
||||
|
||||
} else {
|
||||
for (i = 0; i < h->key.len; i++) {
|
||||
h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
|
||||
h->lowcase_key[i] = ngx_tolower(h->key.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1066,7 +1143,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -1095,7 +1172,10 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
status = ngx_atoi(status_line->data, 3);
|
||||
|
||||
if (status == NGX_ERROR) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent invalid status \"%V\"",
|
||||
status_line);
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
u->headers_in.status_n = status;
|
||||
|
@ -1109,8 +1189,8 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
|
||||
u->state->status = u->headers_in.status_n;
|
||||
#if 0
|
||||
if (u->cachable) {
|
||||
u->cachable = ngx_http_upstream_is_cachable(r);
|
||||
if (u->cacheable) {
|
||||
u->cacheable = ngx_http_upstream_is_cacheable(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1123,7 +1203,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
"upstream sent invalid header");
|
||||
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
|
||||
}
|
||||
|
||||
if (last) {
|
||||
|
@ -1144,16 +1223,29 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (u->buffer.pos == u->buffer.last) {
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"upstream split a header line in FastCGI records");
|
||||
/* rc == NGX_AGAIN */
|
||||
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"upstream split a header line in FastCGI records");
|
||||
|
||||
if (f->split_parts == NULL) {
|
||||
f->split_parts = ngx_array_create(r->pool, 1,
|
||||
sizeof(ngx_http_fastcgi_split_part_t));
|
||||
if (f->split_parts == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
part = ngx_array_push(f->split_parts);
|
||||
|
||||
part->start = part_start;
|
||||
part->end = u->buffer.last;
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1521,7 +1613,7 @@ ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
|
|||
ngx_http_variable_t *var;
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
|
||||
NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHABLE);
|
||||
NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -1549,17 +1641,18 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.next_upstream = 0;
|
||||
* conf->upstream.temp_path = NULL;
|
||||
* conf->upstream.hide_headers_hash = { NULL, 0 };
|
||||
* conf->upstream.hide_headers = NULL;
|
||||
* conf->upstream.pass_headers = NULL;
|
||||
* conf->upstream.catch_stderr = NULL;
|
||||
* conf->upstream.schema = { 0, NULL };
|
||||
* conf->upstream.uri = { 0, NULL };
|
||||
* conf->upstream.location = NULL;
|
||||
* conf->upstream.store_lengths = NULL;
|
||||
* conf->upstream.store_values = NULL;
|
||||
*
|
||||
* conf->index.len = 0;
|
||||
* conf->index.data = NULL;
|
||||
*/
|
||||
|
||||
conf->upstream.store = NGX_CONF_UNSET;
|
||||
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
|
||||
conf->upstream.buffering = NGX_CONF_UNSET;
|
||||
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
|
||||
|
||||
|
@ -1577,11 +1670,16 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
||||
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
||||
|
||||
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
||||
conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
|
||||
|
||||
conf->upstream.intercept_errors = NGX_CONF_UNSET;
|
||||
|
||||
/* "fastcgi_cyclic_temp_file" is disabled */
|
||||
conf->upstream.cyclic_temp_file = 0;
|
||||
|
||||
conf->catch_stderr = NGX_CONF_UNSET_PTR;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
@ -1595,15 +1693,25 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
u_char *p;
|
||||
size_t size;
|
||||
uintptr_t *code;
|
||||
ngx_str_t *header;
|
||||
ngx_uint_t i, j;
|
||||
ngx_array_t hide_headers;
|
||||
ngx_uint_t i;
|
||||
ngx_keyval_t *src;
|
||||
ngx_hash_key_t *hk;
|
||||
ngx_hash_init_t hash;
|
||||
ngx_http_script_compile_t sc;
|
||||
ngx_http_script_copy_code_t *copy;
|
||||
|
||||
if (conf->upstream.store != 0) {
|
||||
ngx_conf_merge_value(conf->upstream.store,
|
||||
prev->upstream.store, 0);
|
||||
|
||||
if (conf->upstream.store_lengths == NULL) {
|
||||
conf->upstream.store_lengths = prev->upstream.store_lengths;
|
||||
conf->upstream.store_values = prev->upstream.store_values;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_merge_uint_value(conf->upstream.store_access,
|
||||
prev->upstream.store_access, 0600);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.buffering,
|
||||
prev->upstream.buffering, 1);
|
||||
|
||||
|
@ -1748,108 +1856,19 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_str_value(conf->index, prev->index, "");
|
||||
|
||||
if (conf->upstream.hide_headers == NULL
|
||||
&& conf->upstream.pass_headers == NULL)
|
||||
{
|
||||
conf->upstream.hide_headers = prev->upstream.hide_headers;
|
||||
conf->upstream.pass_headers = prev->upstream.pass_headers;
|
||||
conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
|
||||
hash.max_size = 512;
|
||||
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
|
||||
hash.name = "fastcgi_hide_headers_hash";
|
||||
|
||||
if (conf->upstream.hide_headers_hash.buckets) {
|
||||
goto peers;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (conf->upstream.hide_headers == NULL) {
|
||||
conf->upstream.hide_headers = prev->upstream.hide_headers;
|
||||
}
|
||||
|
||||
if (conf->upstream.pass_headers == NULL) {
|
||||
conf->upstream.pass_headers = prev->upstream.pass_headers;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
|
||||
if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
|
||||
&prev->upstream,
|
||||
ngx_http_fastcgi_hide_headers,
|
||||
&hash)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (header = ngx_http_fastcgi_hide_headers; header->len; header++) {
|
||||
hk = ngx_array_push(&hide_headers);
|
||||
if (hk == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *header;
|
||||
hk->key_hash = ngx_hash_key_lc(header->data, header->len);
|
||||
hk->value = (void *) 1;
|
||||
}
|
||||
|
||||
if (conf->upstream.hide_headers) {
|
||||
|
||||
header = conf->upstream.hide_headers->elts;
|
||||
|
||||
for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
|
||||
|
||||
hk = hide_headers.elts;
|
||||
|
||||
for (j = 0; j < hide_headers.nelts; j++) {
|
||||
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
|
||||
goto exist;
|
||||
}
|
||||
}
|
||||
|
||||
hk = ngx_array_push(&hide_headers);
|
||||
if (hk == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
hk->key = header[i];
|
||||
hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
|
||||
hk->value = (void *) 1;
|
||||
|
||||
exist:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->upstream.pass_headers) {
|
||||
|
||||
hk = hide_headers.elts;
|
||||
header = conf->upstream.pass_headers->elts;
|
||||
|
||||
for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
|
||||
|
||||
for (j = 0; j < hide_headers.nelts; j++) {
|
||||
|
||||
if (hk[j].key.data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
|
||||
hk[j].key.data = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hash.hash = &conf->upstream.hide_headers_hash;
|
||||
hash.key = ngx_hash_key_lc;
|
||||
hash.max_size = 512;
|
||||
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
|
||||
hash.name = "fastcgi_hide_headers_hash";
|
||||
hash.pool = cf->pool;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
peers:
|
||||
|
||||
if (conf->upstream.upstream == NULL) {
|
||||
conf->upstream.upstream = prev->upstream.upstream;
|
||||
conf->upstream.schema = prev->upstream.schema;
|
||||
|
@ -1997,7 +2016,7 @@ ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
|
|||
|
||||
if (r->uri.len) {
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
||||
|
@ -2021,7 +2040,7 @@ ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
|
|||
} else {
|
||||
v->len = 0;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = NULL;
|
||||
|
||||
|
@ -2074,6 +2093,52 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_fastcgi_loc_conf_t *flcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
||||
if (flcf->upstream.store != NGX_CONF_UNSET || flcf->upstream.store_lengths)
|
||||
{
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strcmp(value[1].data, "on") == 0) {
|
||||
flcf->upstream.store = 1;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
||||
flcf->upstream.store = 0;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
/* include the terminating '\0' into script */
|
||||
value[1].len++;
|
||||
|
||||
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
|
||||
|
||||
sc.cf = cf;
|
||||
sc.source = &value[1];
|
||||
sc.lengths = &flcf->upstream.store_lengths;
|
||||
sc.values = &flcf->upstream.store_values;
|
||||
sc.variables = ngx_http_script_variables_count(&value[1]);
|
||||
sc.complete_lengths = 1;
|
||||
sc.complete_values = 1;
|
||||
|
||||
if (ngx_http_script_compile(&sc) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
|
|
|
@ -167,7 +167,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
|||
i = 1;
|
||||
|
||||
if (r->args.len) {
|
||||
p = (u_char *) ngx_strstr(r->args.data, "start=");
|
||||
p = (u_char *) ngx_strnstr(r->args.data, "start=", r->args.len);
|
||||
|
||||
if (p) {
|
||||
p += 6;
|
||||
|
|
|
@ -86,7 +86,7 @@ ngx_http_geo_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
*v = *vv;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo: %V %V", &r->connection->addr_text, v);
|
||||
"http geo: %V %v", &r->connection->addr_text, v);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -100,8 +100,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_conf_t save;
|
||||
ngx_pool_t *pool;
|
||||
ngx_radix_tree_t *tree;
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_geo_conf_ctx_t ctx;
|
||||
ngx_http_variable_t *var;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
|
@ -116,7 +116,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
name.data++;
|
||||
}
|
||||
|
||||
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
|
||||
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -212,12 +212,20 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
cidrin.mask = 0;
|
||||
|
||||
} else {
|
||||
if (ngx_ptocidr(&value[0], &cidrin) == NGX_ERROR) {
|
||||
rc = ngx_ptocidr(&value[0], &cidrin);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[0]);
|
||||
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[0]);
|
||||
}
|
||||
|
||||
cidrin.addr = ntohl(cidrin.addr);
|
||||
cidrin.mask = ntohl(cidrin.mask);
|
||||
}
|
||||
|
@ -249,7 +257,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
}
|
||||
|
||||
var->valid = 1;
|
||||
var->no_cachable = 0;
|
||||
var->no_cacheable = 0;
|
||||
var->not_found = 0;
|
||||
|
||||
v = ngx_array_push(&ctx->values);
|
||||
|
@ -277,9 +285,8 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
ngx_radix32tree_find(ctx->tree, cidrin.addr & cidrin.mask);
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"duplicate parameter \"%V\", value: \"%V\", "
|
||||
"old value: \"%V\"",
|
||||
&value[0], var, old);
|
||||
"duplicate parameter \"%V\", value: \"%v\", old value: \"%v\"",
|
||||
&value[0], var, old);
|
||||
|
||||
rc = ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
typedef struct {
|
||||
ngx_flag_t enable;
|
||||
ngx_flag_t no_buffer;
|
||||
ngx_flag_t vary;
|
||||
|
||||
ngx_array_t *types; /* array of ngx_str_t */
|
||||
|
||||
|
@ -192,6 +193,13 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
|
|||
offsetof(ngx_http_gzip_conf_t, min_length),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("gzip_vary"),
|
||||
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_gzip_conf_t, vary),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
@ -261,6 +269,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||
{
|
||||
ngx_str_t *type;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_http_gzip_ctx_t *ctx;
|
||||
ngx_http_gzip_conf_t *conf;
|
||||
|
||||
|
@ -279,7 +288,9 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||
|| r->headers_in.accept_encoding == NULL
|
||||
|| (r->headers_out.content_length_n != -1
|
||||
&& r->headers_out.content_length_n < conf->min_length)
|
||||
|| ngx_strstr(r->headers_in.accept_encoding->value.data, "gzip") == NULL
|
||||
|| ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
|
||||
"gzip", 4 - 1)
|
||||
== NULL
|
||||
)
|
||||
{
|
||||
return ngx_http_next_header_filter(r);
|
||||
|
@ -334,16 +345,31 @@ found:
|
|||
|
||||
ctx->request = r;
|
||||
|
||||
r->headers_out.content_encoding = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.content_encoding == NULL) {
|
||||
header = ngx_list_push(&r->headers_out.headers);
|
||||
if (header == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.content_encoding->hash = 1;
|
||||
r->headers_out.content_encoding->key.len = sizeof("Content-Encoding") - 1;
|
||||
r->headers_out.content_encoding->key.data = (u_char *) "Content-Encoding";
|
||||
r->headers_out.content_encoding->value.len = sizeof("gzip") - 1;
|
||||
r->headers_out.content_encoding->value.data = (u_char *) "gzip";
|
||||
header->hash = 1;
|
||||
header->key.len = sizeof("Content-Encoding") - 1;
|
||||
header->key.data = (u_char *) "Content-Encoding";
|
||||
header->value.len = sizeof("gzip") - 1;
|
||||
header->value.data = (u_char *) "gzip";
|
||||
|
||||
r->headers_out.content_encoding = header;
|
||||
|
||||
if (conf->vary) {
|
||||
header = ngx_list_push(&r->headers_out.headers);
|
||||
if (header == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
header->hash = 1;
|
||||
header->key.len = sizeof("Vary") - 1;
|
||||
header->key.data = (u_char *) "Vary";
|
||||
header->value.len = sizeof("Accept-Encoding") - 1;
|
||||
header->value.data = (u_char *) "Accept-Encoding";
|
||||
}
|
||||
|
||||
ctx->length = r->headers_out.content_length_n;
|
||||
|
||||
|
@ -811,12 +837,15 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
}
|
||||
}
|
||||
|
||||
if (last == NGX_AGAIN && !ctx->done) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
if (ctx->out == NULL) {
|
||||
|
||||
if (ctx->out == NULL && ctx->busy == NULL) {
|
||||
return NGX_OK;
|
||||
if (last == NGX_AGAIN) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (ctx->busy == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
last = ngx_http_next_body_filter(r, ctx->out);
|
||||
|
@ -938,7 +967,7 @@ ngx_http_gzip_ratio_variable(ngx_http_request_t *r,
|
|||
ngx_http_gzip_ctx_t *ctx;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
|
||||
|
@ -994,6 +1023,7 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf)
|
|||
|
||||
conf->enable = NGX_CONF_UNSET;
|
||||
conf->no_buffer = NGX_CONF_UNSET;
|
||||
conf->vary = NGX_CONF_UNSET;
|
||||
|
||||
conf->http_version = NGX_CONF_UNSET_UINT;
|
||||
|
||||
|
@ -1029,6 +1059,7 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
MAX_MEM_LEVEL - 1);
|
||||
ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
|
||||
ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
|
||||
ngx_conf_merge_value(conf->vary, prev->vary, 0);
|
||||
|
||||
if (conf->types == NULL) {
|
||||
if (prev->types == NULL) {
|
||||
|
|
|
@ -9,17 +9,31 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_table_elt_t value;
|
||||
ngx_array_t *lengths;
|
||||
ngx_array_t *values;
|
||||
} ngx_http_header_val_t;
|
||||
typedef struct ngx_http_header_val_s ngx_http_header_val_t;
|
||||
|
||||
typedef ngx_int_t (*ngx_http_set_header_pt)(ngx_http_request_t *r,
|
||||
ngx_http_header_val_t *hv, ngx_str_t *value);
|
||||
|
||||
|
||||
typedef struct {
|
||||
time_t expires;
|
||||
ngx_str_t cache_control;
|
||||
ngx_array_t *headers;
|
||||
ngx_str_t name;
|
||||
ngx_uint_t offset;
|
||||
ngx_http_set_header_pt handler;
|
||||
} ngx_http_set_header_t;
|
||||
|
||||
|
||||
struct ngx_http_header_val_s {
|
||||
ngx_table_elt_t value;
|
||||
ngx_uint_t offset;
|
||||
ngx_http_set_header_pt handler;
|
||||
ngx_array_t *lengths;
|
||||
ngx_array_t *values;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
time_t expires;
|
||||
ngx_array_t *headers;
|
||||
} ngx_http_headers_conf_t;
|
||||
|
||||
|
||||
|
@ -29,6 +43,13 @@ typedef struct {
|
|||
#define NGX_HTTP_EXPIRES_MAX -2147483644
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r,
|
||||
ngx_http_headers_conf_t *conf);
|
||||
static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
|
||||
ngx_http_header_val_t *hv, ngx_str_t *value);
|
||||
static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r,
|
||||
ngx_http_header_val_t *hv, ngx_str_t *value);
|
||||
|
||||
static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
|
@ -39,6 +60,18 @@ static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
|
||||
|
||||
static ngx_http_set_header_t ngx_http_set_headers[] = {
|
||||
|
||||
{ ngx_string("Cache-Control"), 0, ngx_http_add_cache_control },
|
||||
|
||||
{ ngx_string("Last-Modified"),
|
||||
offsetof(ngx_http_headers_out_t, last_modified),
|
||||
ngx_http_set_last_modified },
|
||||
|
||||
{ ngx_null_string, 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_headers_filter_commands[] = {
|
||||
|
||||
{ ngx_string("expires"),
|
||||
|
@ -98,13 +131,15 @@ static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
|
|||
static ngx_int_t
|
||||
ngx_http_headers_filter(ngx_http_request_t *r)
|
||||
{
|
||||
size_t len;
|
||||
ngx_str_t value;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *expires, *cc, **ccp, *out;
|
||||
ngx_http_header_val_t *h;
|
||||
ngx_http_headers_conf_t *conf;
|
||||
|
||||
if (r != r->main
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
|
||||
|
||||
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_NO_CONTENT
|
||||
&& r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
|
||||
|
@ -114,124 +149,73 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
|||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
|
||||
|
||||
if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
|
||||
|
||||
expires = r->headers_out.expires;
|
||||
|
||||
if (expires == NULL) {
|
||||
|
||||
expires = ngx_list_push(&r->headers_out.headers);
|
||||
if (expires == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.expires = expires;
|
||||
|
||||
expires->hash = 1;
|
||||
expires->key.len = sizeof("Expires") - 1;
|
||||
expires->key.data = (u_char *) "Expires";
|
||||
if (ngx_http_set_expires(r, conf) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
|
||||
expires->value.len = len - 1;
|
||||
if (conf->headers) {
|
||||
h = conf->headers->elts;
|
||||
for (i = 0; i < conf->headers->nelts; i++) {
|
||||
|
||||
ccp = r->headers_out.cache_control.elts;
|
||||
|
||||
if (ccp == NULL) {
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc->hash = 1;
|
||||
cc->key.len = sizeof("Cache-Control") - 1;
|
||||
cc->key.data = (u_char *) "Cache-Control";
|
||||
|
||||
*ccp = cc;
|
||||
|
||||
} else {
|
||||
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
|
||||
ccp[i]->hash = 0;
|
||||
}
|
||||
|
||||
cc = ccp[0];
|
||||
}
|
||||
|
||||
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
|
||||
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
|
||||
|
||||
cc->value.len = sizeof("no-cache") - 1;
|
||||
cc->value.data = (u_char *) "no-cache";
|
||||
|
||||
} else if (conf->expires == NGX_HTTP_EXPIRES_MAX) {
|
||||
expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT";
|
||||
|
||||
/* 10 years */
|
||||
cc->value.len = sizeof("max-age=315360000") - 1;
|
||||
cc->value.data = (u_char *) "max-age=315360000";
|
||||
|
||||
} else {
|
||||
expires->value.data = ngx_palloc(r->pool, len);
|
||||
if (expires->value.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (conf->expires == 0) {
|
||||
ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
|
||||
ngx_cached_http_time.len + 1);
|
||||
|
||||
cc->value.len = sizeof("max-age=0") - 1;
|
||||
cc->value.data = (u_char *) "max-age=0";
|
||||
if (h[i].lengths == NULL) {
|
||||
value = h[i].value.value;
|
||||
|
||||
} else {
|
||||
ngx_http_time(expires->value.data, ngx_time() + conf->expires);
|
||||
|
||||
if (conf->expires < 0) {
|
||||
cc->value.len = sizeof("no-cache") - 1;
|
||||
cc->value.data = (u_char *) "no-cache";
|
||||
|
||||
} else {
|
||||
cc->value.data = ngx_palloc(r->pool, sizeof("max-age=")
|
||||
+ NGX_TIME_T_LEN + 1);
|
||||
if (cc->value.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
|
||||
conf->expires)
|
||||
- cc->value.data;
|
||||
if (ngx_http_script_run(r, &value, h[i].lengths->elts, 0,
|
||||
h[i].values->elts)
|
||||
== NULL)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (h[i].handler(r, &h[i], &value) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->cache_control.len) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
ccp = r->headers_out.cache_control.elts;
|
||||
|
||||
if (ccp == NULL) {
|
||||
static ngx_int_t
|
||||
ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *expires, *cc, **ccp;
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
expires = r->headers_out.expires;
|
||||
|
||||
if (expires == NULL) {
|
||||
|
||||
expires = ngx_list_push(&r->headers_out.headers);
|
||||
if (expires == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.expires = expires;
|
||||
|
||||
expires->hash = 1;
|
||||
expires->key.len = sizeof("Expires") - 1;
|
||||
expires->key.data = (u_char *) "Expires";
|
||||
}
|
||||
|
||||
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
|
||||
expires->value.len = len - 1;
|
||||
|
||||
ccp = r->headers_out.cache_control.elts;
|
||||
|
||||
if (ccp == NULL) {
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
|
@ -247,37 +231,161 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
|||
cc->hash = 1;
|
||||
cc->key.len = sizeof("Cache-Control") - 1;
|
||||
cc->key.data = (u_char *) "Cache-Control";
|
||||
cc->value = conf->cache_control;
|
||||
|
||||
*ccp = cc;
|
||||
|
||||
} else {
|
||||
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
|
||||
ccp[i]->hash = 0;
|
||||
}
|
||||
|
||||
cc = ccp[0];
|
||||
}
|
||||
|
||||
if (conf->headers) {
|
||||
h = conf->headers->elts;
|
||||
for (i = 0; i < conf->headers->nelts; i++) {
|
||||
out = ngx_list_push(&r->headers_out.headers);
|
||||
if (out == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
|
||||
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
|
||||
|
||||
out->hash = h[i].value.hash;
|
||||
out->key = h[i].value.key;
|
||||
cc->value.len = sizeof("no-cache") - 1;
|
||||
cc->value.data = (u_char *) "no-cache";
|
||||
|
||||
if (h[i].lengths == NULL) {
|
||||
out->value = h[i].value.value;
|
||||
continue;
|
||||
}
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_http_script_run(r, &out->value, h[i].lengths->elts, 0,
|
||||
h[i].values->elts)
|
||||
== NULL)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
if (conf->expires == NGX_HTTP_EXPIRES_MAX) {
|
||||
expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT";
|
||||
|
||||
/* 10 years */
|
||||
cc->value.len = sizeof("max-age=315360000") - 1;
|
||||
cc->value.data = (u_char *) "max-age=315360000";
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
expires->value.data = ngx_palloc(r->pool, len);
|
||||
if (expires->value.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (conf->expires == 0) {
|
||||
ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
|
||||
ngx_cached_http_time.len + 1);
|
||||
|
||||
cc->value.len = sizeof("max-age=0") - 1;
|
||||
cc->value.data = (u_char *) "max-age=0";
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_http_time(expires->value.data, ngx_time() + conf->expires);
|
||||
|
||||
if (conf->expires < 0) {
|
||||
cc->value.len = sizeof("no-cache") - 1;
|
||||
cc->value.data = (u_char *) "no-cache";
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
cc->value.data = ngx_palloc(r->pool,
|
||||
sizeof("max-age=") + NGX_TIME_T_LEN + 1);
|
||||
if (cc->value.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", conf->expires)
|
||||
- cc->value.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
ngx_table_elt_t *h;
|
||||
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->hash = hv->value.hash;
|
||||
h->key = hv->value.key;
|
||||
h->value = *value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
ngx_table_elt_t *cc, **ccp;
|
||||
|
||||
ccp = r->headers_out.cache_control.elts;
|
||||
|
||||
if (ccp == NULL) {
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc->hash = 1;
|
||||
cc->key.len = sizeof("Cache-Control") - 1;
|
||||
cc->key.data = (u_char *) "Cache-Control";
|
||||
cc->value = *value;
|
||||
|
||||
*ccp = cc;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
ngx_table_elt_t *h, **old;
|
||||
|
||||
if (hv->offset) {
|
||||
old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
|
||||
|
||||
} else {
|
||||
old = NULL;
|
||||
}
|
||||
|
||||
if (old == NULL || *old == NULL) {
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
h = *old;
|
||||
}
|
||||
|
||||
h->hash = hv->value.hash;
|
||||
h->key = hv->value.key;
|
||||
h->value = *value;
|
||||
|
||||
r->headers_out.last_modified_time = -1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -294,8 +402,6 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
|
|||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->cache_control.len = 0;
|
||||
* conf->cache_control.data = NULL;
|
||||
* conf->headers = NULL;
|
||||
*/
|
||||
|
||||
|
@ -313,11 +419,7 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
|
||||
conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ?
|
||||
NGX_HTTP_EXPIRES_OFF : prev->expires;
|
||||
}
|
||||
|
||||
if (conf->cache_control.data == NULL) {
|
||||
conf->cache_control = prev->cache_control;
|
||||
NGX_HTTP_EXPIRES_OFF : prev->expires;
|
||||
}
|
||||
|
||||
if (conf->headers == NULL) {
|
||||
|
@ -406,16 +508,13 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ngx_int_t n;
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i;
|
||||
ngx_http_header_val_t *h;
|
||||
ngx_http_set_header_t *sh;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strcasecmp(value[1].data, (u_char *) "cache-control") == 0) {
|
||||
hcf->cache_control = value[2];
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (hcf->headers == NULL) {
|
||||
hcf->headers = ngx_array_create(cf->pool, 1,
|
||||
sizeof(ngx_http_header_val_t));
|
||||
|
@ -432,9 +531,22 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
h->value.hash = 1;
|
||||
h->value.key = value[1];
|
||||
h->value.value = value[2];
|
||||
h->offset = 0;
|
||||
h->handler = ngx_http_add_header;
|
||||
h->lengths = NULL;
|
||||
h->values = NULL;
|
||||
|
||||
sh = ngx_http_set_headers;
|
||||
for (i = 0; sh[i].name.len; i++) {
|
||||
if (ngx_strcasecmp(value[1].data, sh[i].name.data) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
h->offset = sh[i].offset;
|
||||
h->handler = sh[i].handler;
|
||||
break;
|
||||
}
|
||||
|
||||
n = ngx_http_script_variables_count(&value[2]);
|
||||
|
||||
if (n == 0) {
|
||||
|
|
|
@ -141,7 +141,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
|
|||
if (len > 255) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"the value of the \"%V\" variable "
|
||||
"is more than 255 bytes: \"%V\"",
|
||||
"is more than 255 bytes: \"%v\"",
|
||||
&ctx->var, vv);
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
|
|
@ -114,7 +114,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_CONF_TAKE123,
|
||||
|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,
|
||||
ngx_http_log_set_log,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
|
@ -423,6 +423,11 @@ ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* although there is a real $body_bytes_sent variable,
|
||||
* this log operation code function is more optimized for logging
|
||||
*/
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_body_bytes_sent(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
|
|
|
@ -26,8 +26,7 @@ typedef struct {
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
ngx_hash_combined_t hash;
|
||||
ngx_int_t index;
|
||||
ngx_http_variable_value_t *default_value;
|
||||
ngx_uint_t hostnames; /* unsigned hostnames:1 */
|
||||
|
@ -142,32 +141,17 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
key = ngx_hash(key, name[i]);
|
||||
}
|
||||
|
||||
value = NULL;
|
||||
|
||||
if (map->hash.buckets) {
|
||||
value = ngx_hash_find(&map->hash, key, name, len);
|
||||
}
|
||||
value = ngx_hash_find_combined(&map->hash, key, name, len);
|
||||
|
||||
if (value) {
|
||||
*v = *value;
|
||||
|
||||
} else {
|
||||
if (map->dns_wildcards && map->dns_wildcards->hash.buckets) {
|
||||
value = ngx_hash_find_wildcard(map->dns_wildcards, name, len);
|
||||
if (value) {
|
||||
*v = *value;
|
||||
|
||||
} else {
|
||||
*v = *map->default_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
*v = *map->default_value;
|
||||
}
|
||||
*v = *map->default_value;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http map: \"%V\" \"%V\"", vv, v);
|
||||
"http map: \"%v\" \"%v\"", vv, v);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -237,7 +221,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
name.len--;
|
||||
name.data++;
|
||||
|
||||
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
|
||||
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -282,6 +266,9 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return rv;
|
||||
}
|
||||
|
||||
map->default_value = ctx.default_value ? ctx.default_value:
|
||||
&ngx_http_variable_null_value;
|
||||
|
||||
hash.key = ngx_hash_key_lc;
|
||||
hash.max_size = mcf->hash_max_size;
|
||||
hash.bucket_size = mcf->hash_bucket_size;
|
||||
|
@ -289,7 +276,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
hash.pool = cf->pool;
|
||||
|
||||
if (ctx.keys.keys.nelts) {
|
||||
hash.hash = &map->hash;
|
||||
hash.hash = &map->hash.hash;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
|
||||
|
@ -300,27 +287,44 @@ 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;
|
||||
if (ctx.keys.dns_wc_head.nelts) {
|
||||
|
||||
if (ctx.keys.dns_wildcards.nelts) {
|
||||
|
||||
ngx_qsort(ctx.keys.dns_wildcards.elts,
|
||||
(size_t) ctx.keys.dns_wildcards.nelts,
|
||||
ngx_qsort(ctx.keys.dns_wc_head.elts,
|
||||
(size_t) ctx.keys.dns_wc_head.nelts,
|
||||
sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wildcards.elts,
|
||||
ctx.keys.dns_wildcards.nelts)
|
||||
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_head.elts,
|
||||
ctx.keys.dns_wc_head.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
map->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
|
||||
map->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
if (ctx.keys.dns_wc_tail.nelts) {
|
||||
|
||||
ngx_qsort(ctx.keys.dns_wc_tail.elts,
|
||||
(size_t) ctx.keys.dns_wc_tail.nelts,
|
||||
sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts,
|
||||
ctx.keys.dns_wc_tail.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
map->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
ngx_destroy_pool(pool);
|
||||
|
@ -344,10 +348,9 @@ ngx_http_map_cmp_dns_wildcards(const void *one, const void *two)
|
|||
static char *
|
||||
ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
{
|
||||
u_char ch;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value, file;
|
||||
ngx_uint_t i, key, flags;
|
||||
ngx_uint_t i, key;
|
||||
ngx_http_map_conf_ctx_t *ctx;
|
||||
ngx_http_variable_value_t *var, **vp;
|
||||
|
||||
|
@ -427,7 +430,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
}
|
||||
|
||||
var->valid = 1;
|
||||
var->no_cachable = 0;
|
||||
var->no_cacheable = 0;
|
||||
var->not_found = 0;
|
||||
|
||||
vp = ngx_array_push(&ctx->values_hash[key]);
|
||||
|
@ -439,50 +442,36 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
|
||||
found:
|
||||
|
||||
ch = value[0].data[0];
|
||||
if (ngx_strcmp(value[0].data, "default") == 0) {
|
||||
|
||||
if ((ch != '*' && ch != '.') || ctx->hostnames == 0) {
|
||||
|
||||
if (ngx_strcmp(value[0].data, "default") == 0) {
|
||||
|
||||
if (ctx->default_value) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate default map parameter");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx->default_value = var;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (value[0].len && ch == '!') {
|
||||
value[0].len--;
|
||||
value[0].data++;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
|
||||
} else {
|
||||
|
||||
if ((ch == '*' && (value[0].len < 3 || value[0].data[1] != '.'))
|
||||
|| (ch == '.' && value[0].len < 2))
|
||||
{
|
||||
if (ctx->default_value) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid DNS wildcard \"%V\"", &value[0]);
|
||||
|
||||
"duplicate default map parameter");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
flags = NGX_HASH_WILDCARD_KEY;
|
||||
ctx->default_value = var;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
rc = ngx_hash_add_key(&ctx->keys, &value[0], var, flags);
|
||||
if (value[0].len && value[0].data[0] == '!') {
|
||||
value[0].len--;
|
||||
value[0].data++;
|
||||
}
|
||||
|
||||
rc = ngx_hash_add_key(&ctx->keys, &value[0], var,
|
||||
(ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid hostname or wildcard \"%V\"", &value[0]);
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"conflicting parameter \"%V\"", &value[0]);
|
||||
|
|
|
@ -226,6 +226,7 @@ static ngx_int_t
|
|||
ngx_http_memcached_create_request(ngx_http_request_t *r)
|
||||
{
|
||||
size_t len;
|
||||
uintptr_t escape;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_memcached_ctx_t *ctx;
|
||||
|
@ -242,10 +243,9 @@ ngx_http_memcached_create_request(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
len = sizeof("get ") - 1 + vv->len + sizeof(CRLF) - 1;
|
||||
if (vv->len) {
|
||||
len += 1 + vv->len;
|
||||
}
|
||||
escape = 2 * ngx_escape_uri(NULL, vv->data, vv->len, NGX_ESCAPE_MEMCACHED);
|
||||
|
||||
len = sizeof("get ") - 1 + vv->len + escape + sizeof(CRLF) - 1;
|
||||
|
||||
b = ngx_create_temp_buf(r->pool, len);
|
||||
if (b == NULL) {
|
||||
|
@ -268,7 +268,13 @@ ngx_http_memcached_create_request(ngx_http_request_t *r)
|
|||
|
||||
ctx->key.data = b->last;
|
||||
|
||||
b->last = ngx_copy(b->last, vv->data, vv->len);
|
||||
if (escape == 0) {
|
||||
b->last = ngx_copy(b->last, vv->data, vv->len);
|
||||
|
||||
} else {
|
||||
b->last = (u_char *) ngx_escape_uri(b->last, vv->data, vv->len,
|
||||
NGX_ESCAPE_MEMCACHED);
|
||||
}
|
||||
|
||||
ctx->key.len = b->last - ctx->key.data;
|
||||
|
||||
|
@ -365,6 +371,7 @@ found:
|
|||
}
|
||||
|
||||
u->headers_in.status_n = 200;
|
||||
u->state->status = 200;
|
||||
u->buffer.pos = p + 1;
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -375,6 +382,7 @@ found:
|
|||
"key: \"%V\" was not found by memcached", &ctx->key);
|
||||
|
||||
u->headers_in.status_n = 404;
|
||||
u->state->status = 404;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -419,16 +427,16 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||
if (u->length == ctx->rest) {
|
||||
|
||||
if (ngx_strncmp(b->last,
|
||||
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END
|
||||
- ctx->rest,
|
||||
bytes) != 0)
|
||||
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
|
||||
ctx->rest)
|
||||
!= 0)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
||||
"memcached sent invalid trailer");
|
||||
}
|
||||
|
||||
u->length -= bytes;
|
||||
ctx->rest -= bytes;
|
||||
u->length = 0;
|
||||
ctx->rest = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -447,7 +455,8 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||
|
||||
*ll = cl;
|
||||
|
||||
cl->buf->pos = b->last;
|
||||
last = b->last;
|
||||
cl->buf->pos = last;
|
||||
b->last += bytes;
|
||||
cl->buf->last = b->last;
|
||||
|
||||
|
@ -455,20 +464,19 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||
"memcached filter bytes:%z size:%z length:%z rest:%z",
|
||||
bytes, b->last - b->pos, u->length, ctx->rest);
|
||||
|
||||
if (b->last - b->pos <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
|
||||
if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
|
||||
u->length -= bytes;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
last = b->pos + u->length - NGX_HTTP_MEMCACHED_END;
|
||||
last += u->length - NGX_HTTP_MEMCACHED_END;
|
||||
|
||||
if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
||||
"memcached sent invalid trailer");
|
||||
}
|
||||
|
||||
ctx->rest = u->length - (b->last - b->pos);
|
||||
ctx->rest -= b->last - last;
|
||||
b->last = last;
|
||||
cl->buf->last = last;
|
||||
u->length = ctx->rest;
|
||||
|
|
|
@ -70,7 +70,7 @@ ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
|
|||
* I think that the equality of the dates is correcter
|
||||
*/
|
||||
|
||||
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
|
||||
if (ims == r->headers_out.last_modified_time) {
|
||||
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
|
||||
r->headers_out.content_type.len = 0;
|
||||
ngx_http_clear_content_length(r);
|
||||
|
|
|
@ -105,6 +105,8 @@ static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
|
||||
|
||||
|
@ -154,6 +156,20 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_store"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_proxy_store,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_store_access"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
|
||||
ngx_conf_set_access_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.store_access),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_buffering"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
|
@ -404,10 +420,10 @@ static ngx_str_t ngx_http_proxy_hide_headers[] = {
|
|||
static ngx_http_variable_t ngx_http_proxy_vars[] = {
|
||||
|
||||
{ ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
|
||||
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
|
||||
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
||||
{ ngx_string("proxy_add_x_forwarded_for"), NULL,
|
||||
ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
||||
|
@ -537,7 +553,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
|||
|
||||
} else {
|
||||
unparsed_uri = 0;
|
||||
if (r->quoted_uri) {
|
||||
if (r->quoted_uri || r->internal) {
|
||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
|
||||
r->uri.len - loc_len, NGX_ESCAPE_URI);
|
||||
}
|
||||
|
@ -545,7 +561,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
|||
len += r->uri.len - loc_len + escape + sizeof("?") - 1 + r->args.len;
|
||||
}
|
||||
|
||||
ngx_http_script_flush_no_cachable_variables(r, plcf->flushes);
|
||||
ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes);
|
||||
|
||||
if (plcf->body_set_len) {
|
||||
le.ip = plcf->body_set_len->elts;
|
||||
|
@ -822,7 +838,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
|
|||
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
|
||||
|
||||
if (p == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rc = ngx_http_proxy_parse_status_line(r, p);
|
||||
|
@ -844,7 +860,8 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
|
|||
#endif
|
||||
|
||||
r->http_version = NGX_HTTP_VERSION_9;
|
||||
p->status = NGX_HTTP_OK;
|
||||
u->headers_in.status_n = NGX_HTTP_OK;
|
||||
u->state->status = NGX_HTTP_OK;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -856,7 +873,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
|
|||
u->headers_in.status_line.data = ngx_palloc(r->pool,
|
||||
u->headers_in.status_line.len);
|
||||
if (u->headers_in.status_line.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(u->headers_in.status_line.data, p->status_start,
|
||||
|
@ -1100,7 +1117,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
|||
|
||||
h = ngx_list_push(&r->upstream->headers_in.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->hash = r->header_hash;
|
||||
|
@ -1111,7 +1128,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
|||
h->key.data = ngx_palloc(r->pool,
|
||||
h->key.len + 1 + h->value.len + 1 + h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->value.data = h->key.data + h->key.len + 1;
|
||||
|
@ -1125,7 +1142,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
|||
|
||||
} else {
|
||||
for (i = 0; i < h->key.len; i++) {
|
||||
h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
|
||||
h->lowcase_key[i] = ngx_tolower(h->key.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1150,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
|||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -1158,7 +1175,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
|||
if (r->upstream->headers_in.server == NULL) {
|
||||
h = ngx_list_push(&r->upstream->headers_in.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
|
||||
|
@ -1174,7 +1191,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
|||
if (r->upstream->headers_in.date == NULL) {
|
||||
h = ngx_list_push(&r->upstream->headers_in.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');
|
||||
|
@ -1233,7 +1250,7 @@ ngx_http_proxy_host_variable(ngx_http_request_t *r,
|
|||
|
||||
v->len = plcf->host_header.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = plcf->host_header.data;
|
||||
|
||||
|
@ -1251,7 +1268,7 @@ ngx_http_proxy_port_variable(ngx_http_request_t *r,
|
|||
|
||||
v->len = plcf->port.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = plcf->port.data;
|
||||
|
||||
|
@ -1266,7 +1283,7 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
|||
u_char *p;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
if (r->headers_in.x_forwarded_for == NULL) {
|
||||
|
@ -1310,7 +1327,7 @@ ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
v->data = ngx_palloc(r->connection->pool, NGX_SIZE_T_LEN);
|
||||
|
@ -1485,11 +1502,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.next_upstream = 0;
|
||||
* conf->upstream.temp_path = NULL;
|
||||
* conf->upstream.hide_headers_hash = { NULL, 0 };
|
||||
* conf->upstream.hide_headers = NULL;
|
||||
* conf->upstream.pass_headers = NULL;
|
||||
* conf->upstream.schema = { 0, NULL };
|
||||
* conf->upstream.uri = { 0, NULL };
|
||||
* conf->upstream.location = NULL;
|
||||
* conf->upstream.store_lengths = NULL;
|
||||
* conf->upstream.store_values = NULL;
|
||||
*
|
||||
* conf->method = NULL;
|
||||
* conf->headers_source = NULL;
|
||||
|
@ -1502,6 +1519,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->rewrite_locations = NULL;
|
||||
*/
|
||||
|
||||
conf->upstream.store = NGX_CONF_UNSET;
|
||||
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
|
||||
conf->upstream.buffering = NGX_CONF_UNSET;
|
||||
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
|
||||
|
||||
|
@ -1519,6 +1538,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
||||
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
||||
|
||||
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
||||
conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
|
||||
|
||||
conf->upstream.intercept_errors = NGX_CONF_UNSET;
|
||||
|
||||
/* "proxy_cyclic_temp_file" is disabled */
|
||||
|
@ -1543,9 +1565,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
u_char *p;
|
||||
size_t size;
|
||||
uintptr_t *code;
|
||||
ngx_str_t *header;
|
||||
ngx_uint_t i, j;
|
||||
ngx_array_t hide_headers;
|
||||
ngx_uint_t i;
|
||||
ngx_keyval_t *src, *s, *h;
|
||||
ngx_hash_key_t *hk;
|
||||
ngx_hash_init_t hash;
|
||||
|
@ -1553,6 +1573,19 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_http_script_compile_t sc;
|
||||
ngx_http_script_copy_code_t *copy;
|
||||
|
||||
if (conf->upstream.store != 0) {
|
||||
ngx_conf_merge_value(conf->upstream.store,
|
||||
prev->upstream.store, 0);
|
||||
|
||||
if (conf->upstream.store_lengths == NULL) {
|
||||
conf->upstream.store_lengths = prev->upstream.store_lengths;
|
||||
conf->upstream.store_values = prev->upstream.store_values;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_merge_uint_value(conf->upstream.store_access,
|
||||
prev->upstream.store_access, 0600);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.buffering,
|
||||
prev->upstream.buffering, 1);
|
||||
|
||||
|
@ -1741,107 +1774,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size,
|
||||
ngx_cacheline_size);
|
||||
|
||||
if (conf->upstream.hide_headers == NULL
|
||||
&& conf->upstream.pass_headers == NULL)
|
||||
{
|
||||
conf->upstream.hide_headers = prev->upstream.hide_headers;
|
||||
conf->upstream.pass_headers = prev->upstream.pass_headers;
|
||||
conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
|
||||
hash.max_size = conf->headers_hash_max_size;
|
||||
hash.bucket_size = conf->headers_hash_bucket_size;
|
||||
hash.name = "proxy_headers_hash";
|
||||
|
||||
if (conf->upstream.hide_headers_hash.buckets) {
|
||||
goto peers;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (conf->upstream.hide_headers == NULL) {
|
||||
conf->upstream.hide_headers = prev->upstream.hide_headers;
|
||||
}
|
||||
|
||||
if (conf->upstream.pass_headers == NULL) {
|
||||
conf->upstream.pass_headers = prev->upstream.pass_headers;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
|
||||
if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
|
||||
&prev->upstream,
|
||||
ngx_http_proxy_hide_headers, &hash)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (header = ngx_http_proxy_hide_headers; header->len; header++) {
|
||||
hk = ngx_array_push(&hide_headers);
|
||||
if (hk == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *header;
|
||||
hk->key_hash = ngx_hash_key_lc(header->data, header->len);
|
||||
hk->value = (void *) 1;
|
||||
}
|
||||
|
||||
if (conf->upstream.hide_headers) {
|
||||
|
||||
header = conf->upstream.hide_headers->elts;
|
||||
|
||||
for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
|
||||
|
||||
hk = hide_headers.elts;
|
||||
|
||||
for (j = 0; j < hide_headers.nelts; j++) {
|
||||
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
|
||||
goto exist;
|
||||
}
|
||||
}
|
||||
|
||||
hk = ngx_array_push(&hide_headers);
|
||||
if (hk == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
hk->key = header[i];
|
||||
hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
|
||||
hk->value = (void *) 1;
|
||||
|
||||
exist:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->upstream.pass_headers) {
|
||||
|
||||
hk = hide_headers.elts;
|
||||
header = conf->upstream.pass_headers->elts;
|
||||
|
||||
for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
|
||||
for (j = 0; j < hide_headers.nelts; j++) {
|
||||
|
||||
if (hk[j].key.data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
|
||||
hk[j].key.data = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hash.hash = &conf->upstream.hide_headers_hash;
|
||||
hash.key = ngx_hash_key_lc;
|
||||
hash.max_size = conf->headers_hash_max_size;
|
||||
hash.bucket_size = conf->headers_hash_bucket_size;
|
||||
hash.name = "proxy_headers_hash";
|
||||
hash.pool = cf->pool;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
peers:
|
||||
|
||||
if (conf->upstream.upstream == NULL) {
|
||||
conf->upstream.upstream = prev->upstream.upstream;
|
||||
|
||||
|
@ -2204,6 +2148,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
if (port == 80) {
|
||||
plcf->port.len = sizeof("80") - 1;
|
||||
plcf->port.data = (u_char *) "80";
|
||||
|
||||
} else {
|
||||
plcf->port.len = sizeof("443") - 1;
|
||||
plcf->port.data = (u_char *) "443";
|
||||
|
@ -2242,13 +2187,17 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
plcf->upstream.location = clcf->name;
|
||||
|
||||
if (clcf->named
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (clcf->regex || clcf->noname) {
|
||||
|| clcf->regex
|
||||
#endif
|
||||
|| clcf->noname)
|
||||
{
|
||||
if (plcf->upstream.uri.len) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"proxy_pass\" may not have URI part in "
|
||||
"location given by regular expression, "
|
||||
"or inside named location, "
|
||||
"or inside the \"if\" statement, "
|
||||
"or inside the \"limit_except\" block");
|
||||
return NGX_CONF_ERROR;
|
||||
|
@ -2257,8 +2206,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
plcf->upstream.location.len = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
plcf->upstream.url = *url;
|
||||
|
||||
if (clcf->name.data[clcf->name.len - 1] == '/') {
|
||||
|
@ -2359,6 +2306,52 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_proxy_loc_conf_t *plcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
||||
if (plcf->upstream.store != NGX_CONF_UNSET || plcf->upstream.store_lengths)
|
||||
{
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strcmp(value[1].data, "on") == 0) {
|
||||
plcf->upstream.store = 1;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
||||
plcf->upstream.store = 0;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
/* include the terminating '\0' into script */
|
||||
value[1].len++;
|
||||
|
||||
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
|
||||
|
||||
sc.cf = cf;
|
||||
sc.source = &value[1];
|
||||
sc.lengths = &plcf->upstream.store_lengths;
|
||||
sc.values = &plcf->upstream.store_values;
|
||||
sc.variables = ngx_http_script_variables_count(&value[1]);
|
||||
sc.complete_lengths = 1;
|
||||
sc.complete_values = 1;
|
||||
|
||||
if (ngx_http_script_compile(&sc) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
|
|
|
@ -134,6 +134,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
u_char *p;
|
||||
size_t len;
|
||||
off_t start, end;
|
||||
time_t if_range;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t suffix, i;
|
||||
ngx_atomic_uint_t boundary;
|
||||
|
@ -156,18 +157,21 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
(u_char *) "bytes=", 6)
|
||||
!= 0)
|
||||
{
|
||||
r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.accept_ranges == NULL) {
|
||||
return NGX_ERROR;
|
||||
goto next_filter;
|
||||
}
|
||||
|
||||
if (r->headers_in.if_range && r->headers_out.last_modified_time != -1) {
|
||||
|
||||
if_range = ngx_http_parse_time(r->headers_in.if_range->value.data,
|
||||
r->headers_in.if_range->value.len);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http ir:%d lm:%d",
|
||||
if_range, r->headers_out.last_modified_time);
|
||||
|
||||
if (if_range != r->headers_out.last_modified_time) {
|
||||
goto next_filter;
|
||||
}
|
||||
|
||||
r->headers_out.accept_ranges->hash = 1;
|
||||
r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1;
|
||||
r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges";
|
||||
r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
|
||||
r->headers_out.accept_ranges->value.data = (u_char *) "bytes";
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
|
||||
|
@ -460,6 +464,21 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
|
||||
next_filter:
|
||||
|
||||
r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.accept_ranges == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.accept_ranges->hash = 1;
|
||||
r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1;
|
||||
r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges";
|
||||
r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
|
||||
r->headers_out.accept_ranges->value.data = (u_char *) "bytes";
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
{
|
||||
ngx_http_realip_loc_conf_t *rlcf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_inet_cidr_t in_cidr;
|
||||
ngx_http_realip_from_t *from;
|
||||
|
@ -215,12 +216,19 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_ERROR) {
|
||||
rc = ngx_ptocidr(&value[1], &in_cidr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||
&value[1]);
|
||||
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 = in_cidr.mask;
|
||||
from->addr = in_cidr.addr;
|
||||
|
||||
|
|
|
@ -11,9 +11,26 @@
|
|||
|
||||
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
ngx_regex_t *regex;
|
||||
ngx_str_t name;
|
||||
} ngx_http_referer_regex_t;
|
||||
|
||||
#else
|
||||
|
||||
#define ngx_regex_t void
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_combined_t hash;
|
||||
|
||||
#if (NGX_PCRE)
|
||||
ngx_array_t *regex;
|
||||
#endif
|
||||
|
||||
ngx_flag_t no_referer;
|
||||
ngx_flag_t blocked_referer;
|
||||
|
@ -29,6 +46,8 @@ static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
|
||||
ngx_str_t *value, ngx_str_t *uri);
|
||||
static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
|
||||
ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
|
||||
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
|
||||
const void *two);
|
||||
|
||||
|
@ -81,16 +100,28 @@ static ngx_int_t
|
|||
ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
u_char *p, *ref, *last;
|
||||
size_t len;
|
||||
ngx_str_t *uri;
|
||||
ngx_uint_t i, key;
|
||||
ngx_http_referer_conf_t *rlcf;
|
||||
u_char buf[256];
|
||||
u_char *p, *ref, *last;
|
||||
size_t len;
|
||||
ngx_str_t *uri;
|
||||
ngx_uint_t i, key;
|
||||
ngx_http_referer_conf_t *rlcf;
|
||||
u_char buf[256];
|
||||
#if (NGX_PCRE)
|
||||
ngx_int_t n;
|
||||
ngx_str_t referer;
|
||||
ngx_http_referer_regex_t *regex;
|
||||
#endif
|
||||
|
||||
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
|
||||
|
||||
if (rlcf->hash.buckets == NULL && rlcf->dns_wildcards == NULL) {
|
||||
if (rlcf->hash.hash.buckets == NULL
|
||||
&& rlcf->hash.wc_head == NULL
|
||||
&& rlcf->hash.wc_tail == NULL
|
||||
#if (NGX_PCRE)
|
||||
&& rlcf->regex == NULL
|
||||
#endif
|
||||
)
|
||||
{
|
||||
goto valid;
|
||||
}
|
||||
|
||||
|
@ -133,21 +164,43 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
}
|
||||
}
|
||||
|
||||
len = p - ref;
|
||||
uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
|
||||
|
||||
if (rlcf->hash.buckets) {
|
||||
uri = ngx_hash_find(&rlcf->hash, key, buf, len);
|
||||
if (uri) {
|
||||
goto uri;
|
||||
if (uri) {
|
||||
goto uri;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (rlcf->regex) {
|
||||
|
||||
referer.len = len - 7;
|
||||
referer.data = ref;
|
||||
|
||||
regex = rlcf->regex->elts;
|
||||
|
||||
for (i = 0; i < rlcf->regex->nelts; i++) {
|
||||
n = ngx_regex_exec(regex[i].regex, &referer, NULL, 0);
|
||||
|
||||
if (n == NGX_REGEX_NO_MATCHED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
ngx_regex_exec_n
|
||||
" failed: %d on \"%V\" using \"%V\"",
|
||||
n, &referer, ®ex[i].name);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* match */
|
||||
|
||||
goto valid;
|
||||
}
|
||||
}
|
||||
|
||||
if (rlcf->dns_wildcards) {
|
||||
uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
|
||||
if (uri) {
|
||||
goto uri;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
invalid:
|
||||
|
||||
|
@ -208,7 +261,6 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
if (conf->keys == NULL) {
|
||||
conf->hash = prev->hash;
|
||||
conf->dns_wildcards = prev->dns_wildcards;
|
||||
|
||||
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
|
||||
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
|
||||
|
@ -217,7 +269,9 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
}
|
||||
|
||||
if ((conf->no_referer == 1 || conf->blocked_referer == 1)
|
||||
&& conf->keys->keys.nelts == 0 && conf->keys->dns_wildcards.nelts == 0)
|
||||
&& conf->keys->keys.nelts == 0
|
||||
&& conf->keys->dns_wc_head.nelts == 0
|
||||
&& conf->keys->dns_wc_tail.nelts == 0)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"the \"none\" or \"blocked\" referers are specified "
|
||||
|
@ -233,7 +287,7 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
hash.pool = cf->pool;
|
||||
|
||||
if (conf->keys->keys.nelts) {
|
||||
hash.hash = &conf->hash;
|
||||
hash.hash = &conf->hash.hash;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
|
||||
|
@ -243,24 +297,44 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
}
|
||||
}
|
||||
|
||||
if (conf->keys->dns_wildcards.nelts) {
|
||||
if (conf->keys->dns_wc_head.nelts) {
|
||||
|
||||
ngx_qsort(conf->keys->dns_wildcards.elts,
|
||||
(size_t) conf->keys->dns_wildcards.nelts,
|
||||
ngx_qsort(conf->keys->dns_wc_head.elts,
|
||||
(size_t) conf->keys->dns_wc_head.nelts,
|
||||
sizeof(ngx_hash_key_t),
|
||||
ngx_http_cmp_referer_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = cf->temp_pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wildcards.elts,
|
||||
conf->keys->dns_wildcards.nelts)
|
||||
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts,
|
||||
conf->keys->dns_wc_head.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
|
||||
conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
if (conf->keys->dns_wc_tail.nelts) {
|
||||
|
||||
ngx_qsort(conf->keys->dns_wc_tail.elts,
|
||||
(size_t) conf->keys->dns_wc_tail.nelts,
|
||||
sizeof(ngx_hash_key_t),
|
||||
ngx_http_cmp_referer_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = cf->temp_pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts,
|
||||
conf->keys->dns_wc_tail.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
if (conf->no_referer == NGX_CONF_UNSET) {
|
||||
|
@ -293,7 +367,7 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
name.data = (u_char *) "invalid_referer";
|
||||
|
||||
var = ngx_http_add_variable(cf, &name,
|
||||
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH);
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH);
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -342,6 +416,21 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
sn = cscf->server_names.elts;
|
||||
for (n = 0; n < cscf->server_names.nelts; n++) {
|
||||
|
||||
#if (NGX_PCRE)
|
||||
if (sn[n].regex) {
|
||||
|
||||
if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
|
||||
sn[n].regex)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
|
||||
!= NGX_OK)
|
||||
{
|
||||
|
@ -352,6 +441,15 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (value[i].data[0] == '~') {
|
||||
if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
p = (u_char *) ngx_strchr(value[i].data, '/');
|
||||
|
||||
if (p) {
|
||||
|
@ -373,23 +471,8 @@ static char *
|
|||
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
|
||||
ngx_str_t *value, ngx_str_t *uri)
|
||||
{
|
||||
u_char ch;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *u;
|
||||
ngx_uint_t flags;
|
||||
|
||||
ch = value->data[0];
|
||||
|
||||
if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
|
||||
|| (ch == '.' && value->len < 2))
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid DNS wildcard \"%V\"", value);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *u;
|
||||
|
||||
if (uri->len == 0) {
|
||||
u = NGX_HTTP_REFERER_NO_URI_PART;
|
||||
|
@ -403,12 +486,17 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
|
|||
*u = *uri;
|
||||
}
|
||||
|
||||
rc = ngx_hash_add_key(keys, value, u, flags);
|
||||
rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid hostname or wildcard \"%V\"", value);
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"conflicting parameter \"%V\"", value);
|
||||
|
@ -418,6 +506,64 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
|
||||
ngx_str_t *name, ngx_regex_t *regex)
|
||||
{
|
||||
#if (NGX_PCRE)
|
||||
ngx_str_t err;
|
||||
ngx_http_referer_regex_t *rr;
|
||||
u_char errstr[NGX_MAX_CONF_ERRSTR];
|
||||
|
||||
if (rlcf->regex == NULL) {
|
||||
rlcf->regex = ngx_array_create(cf->pool, 2,
|
||||
sizeof(ngx_http_referer_regex_t));
|
||||
if (rlcf->regex == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
rr = ngx_array_push(rlcf->regex);
|
||||
if (rr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (regex) {
|
||||
rr->regex = regex;
|
||||
rr->name = *name;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
err.len = NGX_MAX_CONF_ERRSTR;
|
||||
err.data = errstr;
|
||||
|
||||
name->len--;
|
||||
name->data++;
|
||||
|
||||
rr->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
|
||||
|
||||
if (rr->regex == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
rr->name = *name;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
#else
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the using of the regex \"%V\" requires PCRE library",
|
||||
name);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int ngx_libc_cdecl
|
||||
ngx_http_cmp_referer_wildcards(const void *one, const void *two)
|
||||
{
|
||||
|
|
|
@ -924,7 +924,7 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
value[1].len--;
|
||||
value[1].data++;
|
||||
|
||||
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
|
||||
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
|
||||
if (v == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
|
|
@ -212,6 +212,7 @@ static ngx_str_t ngx_http_ssi_null_string = ngx_null_string;
|
|||
|
||||
#define NGX_HTTP_SSI_ECHO_VAR 0
|
||||
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
|
||||
#define NGX_HTTP_SSI_ECHO_ENCODING 2
|
||||
|
||||
#define NGX_HTTP_SSI_CONFIG_ERRMSG 0
|
||||
#define NGX_HTTP_SSI_CONFIG_TIMEFMT 1
|
||||
|
@ -237,6 +238,7 @@ static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
|
|||
static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
|
||||
{ ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },
|
||||
{ ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 },
|
||||
{ ngx_string("encoding"), NGX_HTTP_SSI_ECHO_ENCODING, 0, 0 },
|
||||
{ ngx_null_string, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -301,10 +303,10 @@ static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
|
|||
static ngx_http_variable_t ngx_http_ssi_vars[] = {
|
||||
|
||||
{ ngx_string("date_local"), NULL, ngx_http_ssi_date_gmt_local_variable, 0,
|
||||
NGX_HTTP_VAR_NOCACHABLE, 0 },
|
||||
NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("date_gmt"), NULL, ngx_http_ssi_date_gmt_local_variable, 1,
|
||||
NGX_HTTP_VAR_NOCACHABLE, 0 },
|
||||
NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
@ -355,6 +357,7 @@ found:
|
|||
ctx->value_len = slcf->value_len;
|
||||
ctx->last_out = &ctx->out;
|
||||
|
||||
ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
|
||||
ctx->output = 1;
|
||||
|
||||
ctx->params.elts = ctx->params_array;
|
||||
|
@ -439,6 +442,8 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,8 +558,9 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
if (b->in_file) {
|
||||
if (slcf->min_file_chunk < (size_t) (b->last - b->pos))
|
||||
{
|
||||
b->file_last = b->file_pos + (b->last - b->start);
|
||||
b->file_pos += b->pos - b->start;
|
||||
b->file_last = b->file_pos
|
||||
+ (b->last - ctx->buf->pos);
|
||||
b->file_pos += b->pos - ctx->buf->pos;
|
||||
|
||||
} else {
|
||||
b->in_file = 0;
|
||||
|
@ -800,8 +806,14 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
}
|
||||
}
|
||||
|
||||
if (cmd->flush && ctx->out) {
|
||||
rc = ngx_http_ssi_output(r, ctx);
|
||||
if (cmd->flush) {
|
||||
|
||||
if (ctx->out) {
|
||||
rc = ngx_http_ssi_output(r, ctx);
|
||||
|
||||
} else {
|
||||
rc = ngx_http_next_body_filter(r, NULL);
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
|
@ -1020,6 +1032,7 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|||
ch = *p;
|
||||
}
|
||||
|
||||
ctx->state = state;
|
||||
ctx->pos = p;
|
||||
ctx->looked = looked;
|
||||
ctx->copy_end = p;
|
||||
|
@ -1846,6 +1859,8 @@ static ngx_int_t
|
|||
ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
u_char *dst, *src;
|
||||
size_t len;
|
||||
ngx_int_t rc, key;
|
||||
ngx_str_t *uri, *file, *wait, *set, *stub, args;
|
||||
ngx_buf_t *b;
|
||||
|
@ -1915,13 +1930,25 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
args.len = 0;
|
||||
args.data = NULL;
|
||||
flags = 0;
|
||||
dst = uri->data;
|
||||
src = uri->data;
|
||||
|
||||
ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI);
|
||||
|
||||
len = (uri->data + uri->len) - src;
|
||||
if (len) {
|
||||
dst = ngx_copy(dst, src, len);
|
||||
}
|
||||
|
||||
uri->len = dst - uri->data;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"ssi include: \"%V\"", uri);
|
||||
|
||||
args.len = 0;
|
||||
args.data = NULL;
|
||||
flags = 0;
|
||||
|
||||
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
@ -1957,6 +1984,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
|
||||
if (bl[i].count++) {
|
||||
|
||||
out = NULL;
|
||||
ll = &out;
|
||||
|
||||
for (tl = bl[i].bufs; tl; tl = tl->next) {
|
||||
|
@ -2110,10 +2138,12 @@ static ngx_int_t
|
|||
ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
u_char *p;
|
||||
uintptr_t len;
|
||||
ngx_int_t key;
|
||||
ngx_uint_t i;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *var, *value, text;
|
||||
ngx_str_t *var, *value, *enc, text;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
|
@ -2161,6 +2191,69 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
enc = params[NGX_HTTP_SSI_ECHO_ENCODING];
|
||||
|
||||
if (enc) {
|
||||
if (enc->len == 4 && ngx_strncmp(enc->data, "none", 4) == 0) {
|
||||
|
||||
ctx->encoding = NGX_HTTP_SSI_NO_ENCODING;
|
||||
|
||||
} else if (enc->len == 3 && ngx_strncmp(enc->data, "url", 3) == 0) {
|
||||
|
||||
ctx->encoding = NGX_HTTP_SSI_URL_ENCODING;
|
||||
|
||||
} else if (enc->len == 6 && ngx_strncmp(enc->data, "entity", 6) == 0) {
|
||||
|
||||
ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"unknown encoding \"%V\" in the \"echo\" command",
|
||||
enc);
|
||||
}
|
||||
}
|
||||
|
||||
switch (ctx->encoding) {
|
||||
|
||||
case NGX_HTTP_SSI_NO_ENCODING:
|
||||
break;
|
||||
|
||||
case NGX_HTTP_SSI_URL_ENCODING:
|
||||
len = 2 * ngx_escape_uri(NULL, value->data, value->len,
|
||||
NGX_ESCAPE_HTML);
|
||||
|
||||
if (len) {
|
||||
p = ngx_palloc(r->pool, value->len + len);
|
||||
if (p == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
(void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
|
||||
|
||||
value->len += len;
|
||||
value->data = p;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NGX_HTTP_SSI_ENTITY_ENCODING:
|
||||
len = ngx_escape_html(NULL, value->data, value->len);
|
||||
|
||||
if (len) {
|
||||
p = ngx_palloc(r->pool, value->len + len);
|
||||
if (p == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
(void) ngx_escape_html(p, value->data, value->len);
|
||||
|
||||
value->len += len;
|
||||
value->data = p;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
|
@ -2564,15 +2657,16 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
|
|||
char buf[NGX_HTTP_SSI_DATE_LEN];
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
tp = ngx_timeofday();
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
|
||||
|
||||
if (ctx->timefmt.len == sizeof("%s") - 1
|
||||
&& ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's')
|
||||
if (ctx == NULL
|
||||
|| (ctx->timefmt.len == sizeof("%s") - 1
|
||||
&& ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's'))
|
||||
{
|
||||
v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
|
||||
if (v->data == NULL) {
|
||||
|
|
|
@ -13,15 +13,20 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_HTTP_SSI_MAX_PARAMS 16
|
||||
#define NGX_HTTP_SSI_MAX_PARAMS 16
|
||||
|
||||
#define NGX_HTTP_SSI_COMMAND_LEN 32
|
||||
#define NGX_HTTP_SSI_PARAM_LEN 32
|
||||
#define NGX_HTTP_SSI_PARAMS_N 4
|
||||
#define NGX_HTTP_SSI_COMMAND_LEN 32
|
||||
#define NGX_HTTP_SSI_PARAM_LEN 32
|
||||
#define NGX_HTTP_SSI_PARAMS_N 4
|
||||
|
||||
|
||||
#define NGX_HTTP_SSI_COND_IF 1
|
||||
#define NGX_HTTP_SSI_COND_ELSE 2
|
||||
#define NGX_HTTP_SSI_COND_IF 1
|
||||
#define NGX_HTTP_SSI_COND_ELSE 2
|
||||
|
||||
|
||||
#define NGX_HTTP_SSI_NO_ENCODING 0
|
||||
#define NGX_HTTP_SSI_URL_ENCODING 1
|
||||
#define NGX_HTTP_SSI_ENTITY_ENCODING 2
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -60,6 +65,7 @@ typedef struct {
|
|||
ngx_array_t *blocks;
|
||||
|
||||
unsigned conditional:2;
|
||||
unsigned encoding:2;
|
||||
unsigned block:1;
|
||||
unsigned output:1;
|
||||
unsigned output_chosen:1;
|
||||
|
|
|
@ -170,19 +170,19 @@ ngx_module_t ngx_http_ssl_module = {
|
|||
static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||
|
||||
{ ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
|
||||
(uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
(uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
|
||||
{ ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
|
||||
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
|
||||
{ ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
|
||||
(uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
(uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
|
||||
{ ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
|
||||
(uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
(uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
|
||||
{ ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
|
||||
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
@ -197,17 +197,20 @@ ngx_http_ssl_static_variable(ngx_http_request_t *r,
|
|||
{
|
||||
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
|
||||
|
||||
size_t len;
|
||||
size_t len;
|
||||
ngx_str_t s;
|
||||
|
||||
if (r->connection->ssl) {
|
||||
|
||||
(void) handler(r->connection, NULL, (ngx_str_t *) v);
|
||||
(void) handler(r->connection, NULL, &s);
|
||||
|
||||
v->data = s.data;
|
||||
|
||||
for (len = 0; v->data[len]; len++) { /* void */ }
|
||||
|
||||
v->len = len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -225,14 +228,20 @@ ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
{
|
||||
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
|
||||
|
||||
ngx_str_t s;
|
||||
|
||||
if (r->connection->ssl) {
|
||||
if (handler(r->connection, r->pool, (ngx_str_t *) v) != NGX_OK) {
|
||||
|
||||
if (handler(r->connection, r->pool, &s) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->len = s.len;
|
||||
v->data = s.data;
|
||||
|
||||
if (v->len) {
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
|
@ -129,7 +129,7 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
|
|||
return rc;
|
||||
}
|
||||
|
||||
return ngx_http_output_filter(r, &out);;
|
||||
return ngx_http_output_filter(r, &out);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -322,8 +322,8 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
b->recycled = 0;
|
||||
|
||||
if (b->in_file) {
|
||||
b->file_last = b->file_pos + (b->last - b->start);
|
||||
b->file_pos += b->pos - b->start;
|
||||
b->file_last = b->file_pos + (b->last - ctx->buf->pos);
|
||||
b->file_pos += b->pos - ctx->buf->pos;
|
||||
}
|
||||
|
||||
cl->next = NULL;
|
||||
|
@ -369,9 +369,14 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
}
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = ctx->sub.data;
|
||||
b->last = ctx->sub.data + ctx->sub.len;
|
||||
if (ctx->sub.len) {
|
||||
b->memory = 1;
|
||||
b->pos = ctx->sub.data;
|
||||
b->last = ctx->sub.data + ctx->sub.len;
|
||||
|
||||
} else {
|
||||
b->sync = 1;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
cl->next = NULL;
|
||||
|
@ -557,6 +562,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
|
|||
ch = ngx_tolower(ch);
|
||||
}
|
||||
|
||||
ctx->state = state;
|
||||
ctx->pos = p;
|
||||
ctx->looked = looked;
|
||||
ctx->copy_end = p;
|
||||
|
@ -578,9 +584,13 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
|
|||
looked++;
|
||||
|
||||
if (looked == ctx->match.len) {
|
||||
if ((size_t) (p - ctx->pos) < looked) {
|
||||
ctx->saved = 0;
|
||||
}
|
||||
|
||||
ctx->state = sub_start_state;
|
||||
ctx->pos = p + 1;
|
||||
ctx->looked = looked;
|
||||
ctx->looked = 0;
|
||||
ctx->copy_end = copy_end;
|
||||
|
||||
if (ctx->copy_start == NULL && copy_end) {
|
||||
|
|
|
@ -198,9 +198,6 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
|
|||
pc->sockaddr = peer->sockaddr;
|
||||
pc->socklen = peer->socklen;
|
||||
pc->name = &peer->name;
|
||||
#if (NGX_SSL)
|
||||
pc->ssl_session = peer->ssl_session;
|
||||
#endif
|
||||
|
||||
/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
|
||||
|
||||
|
|
|
@ -61,9 +61,11 @@ static char *ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
static char *ngx_http_userid_p3p(ngx_conf_t *cf, void *post, void *data);
|
||||
static char *ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static ngx_int_t ngx_http_userid_init_worker(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
|
||||
static uint32_t start_value;
|
||||
static uint32_t sequencer_v1 = 1;
|
||||
static uint32_t sequencer_v2 = 0x03030302;
|
||||
|
||||
|
@ -173,7 +175,7 @@ ngx_module_t ngx_http_userid_filter_module = {
|
|||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
ngx_http_userid_init_worker, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
|
@ -319,7 +321,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
|||
ctx->uid_set[0] = conf->service;
|
||||
}
|
||||
ctx->uid_set[1] = ngx_time();
|
||||
ctx->uid_set[2] = ngx_pid;
|
||||
ctx->uid_set[2] = start_value;
|
||||
ctx->uid_set[3] = sequencer_v1;
|
||||
sequencer_v1 += 0x100;
|
||||
|
||||
|
@ -346,7 +348,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
|||
}
|
||||
|
||||
ctx->uid_set[1] = htonl(ngx_time());
|
||||
ctx->uid_set[2] = htonl(ngx_pid);
|
||||
ctx->uid_set[2] = htonl(start_value);
|
||||
ctx->uid_set[3] = htonl(sequencer_v2);
|
||||
sequencer_v2 += 0x100;
|
||||
if (sequencer_v2 < 0x03030302) {
|
||||
|
@ -493,7 +495,7 @@ ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
}
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
|
||||
|
@ -706,3 +708,18 @@ ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_userid_init_worker(ngx_cycle_t *cycle)
|
||||
{
|
||||
struct timeval tp;
|
||||
|
||||
ngx_gettimeofday(&tp);
|
||||
|
||||
/* use the most significant usec part that fits to 16 bits */
|
||||
start_value = ((tp.tv_usec / 20) << 16) | ngx_pid;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ our @EXPORT = qw(
|
|||
HTTP_INSUFFICIENT_STORAGE
|
||||
);
|
||||
|
||||
our $VERSION = '0.5.25';
|
||||
our $VERSION = '0.5.38';
|
||||
|
||||
require XSLoader;
|
||||
XSLoader::load('nginx', $VERSION);
|
||||
|
|
|
@ -131,6 +131,8 @@ send_http_header(r, ...)
|
|||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
r->headers_out.content_type_len = r->headers_out.content_type.len;
|
||||
|
||||
} else {
|
||||
if (ngx_http_set_content_type(r) != NGX_OK) {
|
||||
XSRETURN_EMPTY;
|
||||
|
@ -910,7 +912,7 @@ variable(r, name, value = NULL)
|
|||
if (value) {
|
||||
vv->len = val.len;
|
||||
vv->valid = 1;
|
||||
vv->no_cachable = 0;
|
||||
vv->no_cacheable = 0;
|
||||
vv->not_found = 0;
|
||||
vv->data = val.data;
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
|||
static void ngx_http_perl_cleanup_perl(void *data);
|
||||
#endif
|
||||
|
||||
static ngx_int_t ngx_http_perl_init_worker(ngx_cycle_t *cycle);
|
||||
static void ngx_http_perl_exit(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
|
@ -126,7 +127,7 @@ ngx_module_t ngx_http_perl_module = {
|
|||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
ngx_http_perl_init_worker, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
|
@ -335,7 +336,7 @@ ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
if (value.data) {
|
||||
v->len = value.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = value.data;
|
||||
|
||||
|
@ -953,7 +954,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
value[1].len--;
|
||||
value[1].data++;
|
||||
|
||||
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
|
||||
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
|
||||
if (v == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -1004,6 +1005,27 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_perl_init_worker(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_http_perl_main_conf_t *pmcf;
|
||||
|
||||
pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module);
|
||||
|
||||
{
|
||||
|
||||
dTHXa(pmcf->perl);
|
||||
PERL_SET_CONTEXT(pmcf->perl);
|
||||
|
||||
/* set worker's $$ */
|
||||
|
||||
sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), (I32) ngx_pid);
|
||||
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_http_perl_exit(ngx_cycle_t *cycle)
|
||||
{
|
||||
|
|
|
@ -73,7 +73,6 @@ static char *
|
|||
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *rv;
|
||||
u_char ch;
|
||||
ngx_int_t rc, j;
|
||||
ngx_uint_t mi, m, s, l, p, a, i, n;
|
||||
ngx_uint_t find_config_index, use_rewrite, use_access;
|
||||
|
@ -99,6 +98,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_phase_handler_pt checker;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
#if (NGX_PCRE)
|
||||
ngx_uint_t regex;
|
||||
#endif
|
||||
#if (NGX_WIN32)
|
||||
ngx_iocp_conf_t *iocpcf;
|
||||
#endif
|
||||
|
@ -402,6 +404,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
|
||||
cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
|
||||
cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
|
||||
find_config_index = 0;
|
||||
use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0;
|
||||
use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0;
|
||||
|
@ -443,6 +446,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
continue;
|
||||
|
||||
case NGX_HTTP_REWRITE_PHASE:
|
||||
if (cmcf->phase_engine.location_rewrite_index == (ngx_uint_t) -1) {
|
||||
cmcf->phase_engine.location_rewrite_index = n;
|
||||
}
|
||||
checker = ngx_http_core_generic_phase;
|
||||
|
||||
break;
|
||||
|
||||
case NGX_HTTP_POST_REWRITE_PHASE:
|
||||
if (use_rewrite) {
|
||||
ph->checker = ngx_http_core_post_rewrite_phase;
|
||||
|
@ -542,8 +553,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
if (in_addr[a].default_server) {
|
||||
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
|
||||
"the duplicate default server in %V:%d",
|
||||
&lscf[l].file_name, lscf[l].line);
|
||||
"the duplicate default server in %s:%ui",
|
||||
&lscf[l].file_name, lscf[l].line);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -647,36 +658,20 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
regex = 0;
|
||||
#endif
|
||||
|
||||
name = in_addr[a].names.elts;
|
||||
for (s = 0; s < in_addr[a].names.nelts; s++) {
|
||||
|
||||
ch = name[s].name.data[0];
|
||||
|
||||
if (ch == '*' || ch == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
|
||||
0);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"conflicting server name \"%V\" on %s, ignored",
|
||||
&name[s].name, in_addr[a].listen_conf->addr);
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s < in_addr[a].names.nelts; s++) {
|
||||
|
||||
ch = name[s].name.data[0];
|
||||
|
||||
if (ch != '*' && ch != '.') {
|
||||
#if (NGX_PCRE)
|
||||
if (name[s].regex) {
|
||||
regex++;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
|
||||
NGX_HASH_WILDCARD_KEY);
|
||||
|
@ -685,6 +680,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"invalid server name or wildcard \"%V\" on %s",
|
||||
&name[s].name, in_addr[a].listen_conf->addr);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"conflicting server name \"%V\" on %s, ignored",
|
||||
|
@ -709,28 +711,70 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
}
|
||||
|
||||
if (ha.dns_wildcards.nelts) {
|
||||
if (ha.dns_wc_head.nelts) {
|
||||
|
||||
ngx_qsort(ha.dns_wildcards.elts,
|
||||
(size_t) ha.dns_wildcards.nelts,
|
||||
ngx_qsort(ha.dns_wc_head.elts,
|
||||
(size_t) ha.dns_wc_head.nelts,
|
||||
sizeof(ngx_hash_key_t),
|
||||
ngx_http_cmp_dns_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = ha.temp_pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, ha.dns_wildcards.elts,
|
||||
ha.dns_wildcards.nelts)
|
||||
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
|
||||
ha.dns_wc_head.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
in_addr[a].dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
|
||||
in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
if (ha.dns_wc_tail.nelts) {
|
||||
|
||||
ngx_qsort(ha.dns_wc_tail.elts,
|
||||
(size_t) ha.dns_wc_tail.nelts,
|
||||
sizeof(ngx_hash_key_t),
|
||||
ngx_http_cmp_dns_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = ha.temp_pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
|
||||
ha.dns_wc_tail.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (regex == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
in_addr[a].nregex = regex;
|
||||
in_addr[a].regex = ngx_palloc(cf->pool,
|
||||
regex * sizeof(ngx_http_server_name_t));
|
||||
|
||||
if (in_addr[a].regex == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) {
|
||||
if (name[s].regex) {
|
||||
in_addr[a].regex[i++] = name[s];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
|
@ -848,8 +892,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
|
||||
|
||||
if (in_addr[i].hash.buckets == NULL
|
||||
&& (in_addr[i].dns_wildcards == NULL
|
||||
|| in_addr[i].dns_wildcards->hash.buckets == NULL))
|
||||
&& (in_addr[i].wc_head == NULL
|
||||
|| in_addr[i].wc_head->hash.buckets == NULL)
|
||||
&& (in_addr[i].wc_head == NULL
|
||||
|| in_addr[i].wc_head->hash.buckets == NULL))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -860,8 +906,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
hip->addrs[i].virtual_names = vn;
|
||||
|
||||
vn->hash = in_addr[i].hash;
|
||||
vn->dns_wildcards = in_addr[i].dns_wildcards;
|
||||
vn->names.hash = in_addr[i].hash;
|
||||
vn->names.wc_head = in_addr[i].wc_head;
|
||||
vn->names.wc_tail = in_addr[i].wc_tail;
|
||||
#if (NGX_PCRE)
|
||||
vn->nregex = in_addr[i].nregex;
|
||||
vn->regex = in_addr[i].regex;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (done) {
|
||||
|
@ -920,7 +971,8 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
|
|||
|
||||
if (in_port->addrs.elts == NULL) {
|
||||
if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
|
||||
sizeof(ngx_http_conf_in_addr_t)) != NGX_OK)
|
||||
sizeof(ngx_http_conf_in_addr_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -934,8 +986,13 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
|
|||
in_addr->addr = lscf->addr;
|
||||
in_addr->hash.buckets = NULL;
|
||||
in_addr->hash.size = 0;
|
||||
in_addr->dns_wildcards = NULL;
|
||||
in_addr->wc_head = NULL;
|
||||
in_addr->wc_tail = NULL;
|
||||
in_addr->names.elts = NULL;
|
||||
#if (NGX_PCRE)
|
||||
in_addr->nregex = 0;
|
||||
in_addr->regex = NULL;
|
||||
#endif
|
||||
in_addr->core_srv_conf = cscf;
|
||||
in_addr->default_server = lscf->conf.default_server;
|
||||
in_addr->bind = lscf->conf.bind;
|
||||
|
@ -968,13 +1025,15 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
|
|||
|
||||
if (in_addr->names.elts == NULL) {
|
||||
if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
|
||||
sizeof(ngx_http_server_name_t)) != NGX_OK)
|
||||
sizeof(ngx_http_server_name_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
server_names = cscf->server_names.elts;
|
||||
|
||||
for (i = 0; i < cscf->server_names.nelts; i++) {
|
||||
|
||||
for (n = 0; n < server_names[i].name.len; n++) {
|
||||
|
@ -985,7 +1044,6 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
|
|||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"name: %V", &server_names[i].name);
|
||||
|
||||
|
||||
name = ngx_array_push(&in_addr->names);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
|
@ -64,7 +64,8 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
|
|||
#endif
|
||||
|
||||
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
|
||||
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r,
|
||||
ngx_uint_t merge_slashes);
|
||||
ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags);
|
||||
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b);
|
||||
|
@ -112,9 +113,4 @@ extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
|
|||
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;
|
||||
|
||||
|
||||
/* STUB */
|
||||
ngx_int_t ngx_http_log_handler(ngx_http_request_t *r);
|
||||
/**/
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_H_INCLUDED_ */
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
|
||||
|
||||
static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc,
|
||||
int lock);
|
||||
static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc,
|
||||
int lock);
|
||||
|
||||
|
||||
int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
|
||||
|
@ -60,12 +60,12 @@ int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
|
|||
}
|
||||
|
||||
|
||||
int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc, int lock)
|
||||
int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc, int lock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ngx_http_busy_lock_look_cachable(bl, bc, lock);
|
||||
rc = ngx_http_busy_lock_look_cacheable(bl, bc, lock);
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, bc->event->log, 0,
|
||||
"http busylock: %d w:%d mw::%d",
|
||||
|
@ -121,22 +121,22 @@ void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
|
|||
|
||||
if (bl->md5) {
|
||||
bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
|
||||
bl->cachable--;
|
||||
bl->cacheable--;
|
||||
}
|
||||
|
||||
bl->busy--;
|
||||
}
|
||||
|
||||
|
||||
static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc,
|
||||
int lock)
|
||||
static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc,
|
||||
int lock)
|
||||
{
|
||||
int i, b, cachable, free;
|
||||
int i, b, cacheable, free;
|
||||
u_int mask;
|
||||
|
||||
b = 0;
|
||||
cachable = 0;
|
||||
cacheable = 0;
|
||||
free = -1;
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
|
@ -153,15 +153,15 @@ static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
|
|||
if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
cachable++;
|
||||
cacheable++;
|
||||
|
||||
} else if (free == -1) {
|
||||
free = i;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (cachable == bl->cachable) {
|
||||
if (free == -1 && cachable < bl->max_busy) {
|
||||
if (cacheable == bl->cacheable) {
|
||||
if (free == -1 && cacheable < bl->max_busy) {
|
||||
free = i + 1;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
|
|||
bl->md5_mask[free / 8] |= 1 << (free & 7);
|
||||
bc->slot = free;
|
||||
|
||||
bl->cachable++;
|
||||
bl->cacheable++;
|
||||
bl->busy++;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
typedef struct {
|
||||
u_char *md5_mask;
|
||||
char *md5;
|
||||
int cachable;
|
||||
int cacheable;
|
||||
|
||||
int busy;
|
||||
int max_busy;
|
||||
|
@ -41,8 +41,8 @@ typedef struct {
|
|||
|
||||
|
||||
int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc);
|
||||
int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc, int lock);
|
||||
int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc, int lock);
|
||||
void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
|
||||
ngx_http_busy_lock_ctx_t *bc);
|
||||
|
||||
|
|
|
@ -117,6 +117,10 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
r->buffered |= NGX_HTTP_COPY_BUFFERED;
|
||||
}
|
||||
|
||||
if (r != r->main) {
|
||||
r->out = ctx->in;
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
|
||||
|
|
|
@ -183,6 +183,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("merge_slashes"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_srv_conf_t, merge_slashes),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("location"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
|
||||
ngx_http_core_location,
|
||||
|
@ -425,6 +432,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server_tokens"),
|
||||
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_core_loc_conf_t, server_tokens),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("error_page"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_2MORE,
|
||||
|
@ -620,6 +634,8 @@ ngx_int_t
|
|||
ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
||||
ngx_http_phase_handler_t *ph)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_int_t rc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
@ -660,7 +676,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
|||
&& clcf->client_max_body_size < r->headers_in.content_length_n)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client intented to send too large body: %O bytes",
|
||||
"client intended to send too large body: %O bytes",
|
||||
r->headers_in.content_length_n);
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
|
||||
|
@ -680,7 +696,25 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
|||
* r->headers_out.location->key fields
|
||||
*/
|
||||
|
||||
r->headers_out.location->value = clcf->name;
|
||||
if (r->args.len == 0) {
|
||||
r->headers_out.location->value = clcf->name;
|
||||
|
||||
} else {
|
||||
len = clcf->name.len + 1 + r->args.len;
|
||||
p = ngx_palloc(r->pool, len);
|
||||
|
||||
if (p == NULL) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
r->headers_out.location->value.len = len;
|
||||
r->headers_out.location->value.data = p;
|
||||
|
||||
p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
|
||||
*p++ = '?';
|
||||
ngx_memcpy(p, r->args.data, r->args.len);
|
||||
}
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
|
||||
return NGX_OK;
|
||||
|
@ -857,7 +891,7 @@ ngx_http_core_content_phase(ngx_http_request_t *r,
|
|||
|
||||
if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"directory index of \"%V\" is forbidden", &path);
|
||||
"directory index of \"%s\" is forbidden", path.data);
|
||||
}
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
|
||||
|
@ -933,25 +967,29 @@ ngx_http_core_find_location(ngx_http_request_t *r,
|
|||
ngx_array_t *locations, ngx_uint_t regex_start, size_t len)
|
||||
{
|
||||
ngx_int_t n, rc;
|
||||
ngx_uint_t i, found, noregex;
|
||||
ngx_uint_t i, found;
|
||||
ngx_http_core_loc_conf_t *clcf, **clcfp;
|
||||
#if (NGX_PCRE)
|
||||
ngx_uint_t noregex;
|
||||
#endif
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"find location for \"%V\"", &r->uri);
|
||||
|
||||
found = 0;
|
||||
#if (NGX_PCRE)
|
||||
noregex = 0;
|
||||
#endif
|
||||
|
||||
clcfp = locations->elts;
|
||||
for (i = 0; i < locations->nelts; i++) {
|
||||
|
||||
if (clcfp[i]->noname
|
||||
#if (NGX_PCRE)
|
||||
if (clcfp[i]->regex) {
|
||||
break;
|
||||
}
|
||||
|| clcfp[i]->regex
|
||||
#endif
|
||||
|
||||
if (clcfp[i]->noname) {
|
||||
|| clcfp[i]->named)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -999,9 +1037,12 @@ ngx_http_core_find_location(ngx_http_request_t *r,
|
|||
break;
|
||||
}
|
||||
|
||||
r->loc_conf = clcfp[i]->loc_conf;
|
||||
noregex = clcfp[i]->noregex;
|
||||
found = 1;
|
||||
|
||||
r->loc_conf = clcfp[i]->loc_conf;
|
||||
#if (NGX_PCRE)
|
||||
noregex = clcfp[i]->noregex;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1069,7 @@ ngx_http_core_find_location(ngx_http_request_t *r,
|
|||
|
||||
for (i = regex_start; i < locations->nelts; i++) {
|
||||
|
||||
if (clcfp[i]->noname) {
|
||||
if (!clcfp[i]->regex) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1513,6 +1554,51 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t **clcfp;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
clcfp = cscf->locations.elts;
|
||||
|
||||
for (i = cscf->named_start; i < cscf->locations.nelts; i++) {
|
||||
|
||||
if (name->len != clcfp[i]->name.len
|
||||
|| ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"named location: %V \"%V?%V\"", name, &r->uri, &r->args);
|
||||
|
||||
r->internal = 1;
|
||||
|
||||
r->loc_conf = clcfp[i]->loc_conf;
|
||||
|
||||
ngx_http_update_location_config(r);
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
r->phase_handler = cmcf->phase_engine.location_rewrite_index;
|
||||
ngx_http_core_run_phases(r);
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"could not find named location \"%V\"", name);
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
ngx_http_cleanup_t *
|
||||
ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
|
||||
{
|
||||
|
@ -1557,10 +1643,8 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||
ngx_http_module_t *module;
|
||||
ngx_http_conf_ctx_t *ctx, *http_ctx;
|
||||
ngx_http_core_srv_conf_t *cscf, **cscfp;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
#if (NGX_PCRE)
|
||||
ngx_http_core_loc_conf_t **clcfp;
|
||||
#endif
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
|
@ -1644,10 +1728,11 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||
ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
|
||||
sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
|
||||
|
||||
clcfp = cscf->locations.elts;
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
cscf->regex_start = cscf->locations.nelts;
|
||||
clcfp = cscf->locations.elts;
|
||||
|
||||
for (i = 0; i < cscf->locations.nelts; i++) {
|
||||
if (clcfp[i]->regex) {
|
||||
|
@ -1658,6 +1743,15 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||
|
||||
#endif
|
||||
|
||||
cscf->named_start = cscf->locations.nelts;
|
||||
|
||||
for (i = 0; i < cscf->locations.nelts; i++) {
|
||||
if (clcfp[i]->named) {
|
||||
cscf->named_start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1758,7 +1852,12 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
clcf->name = value[1];
|
||||
|
||||
if (value[1].data[0] == '@') {
|
||||
clcf->named = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
|
||||
|
@ -1784,6 +1883,14 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (pclcf->named) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"location \"%V\" could not be inside "
|
||||
"the named location \"%V\"",
|
||||
&clcf->name, &pclcf->name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
if (clcf->regex == NULL
|
||||
&& ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
|
||||
|
@ -1861,6 +1968,20 @@ ngx_http_core_cmp_locations(const void *one, const void *two)
|
|||
first = *(ngx_http_core_loc_conf_t **) one;
|
||||
second = *(ngx_http_core_loc_conf_t **) two;
|
||||
|
||||
if (first->named && !second->named) {
|
||||
/* shift named locations to the end */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!first->named && second->named) {
|
||||
/* shift named locations to the end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (first->named && second->named) {
|
||||
return ngx_strcmp(first->name.data, second->name.data);
|
||||
}
|
||||
|
||||
if (first->noname && !second->noname) {
|
||||
/* shift no named locations to the end */
|
||||
return 1;
|
||||
|
@ -2106,6 +2227,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
|
|||
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
cscf->optimize_server_names = NGX_CONF_UNSET;
|
||||
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
|
||||
cscf->merge_slashes = NGX_CONF_UNSET;
|
||||
|
||||
return cscf;
|
||||
}
|
||||
|
@ -2139,7 +2261,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
#endif
|
||||
ls->family = AF_INET;
|
||||
|
||||
ls->conf.backlog = -1;
|
||||
ls->conf.backlog = NGX_LISTEN_BACKLOG;
|
||||
ls->conf.rcvbuf = -1;
|
||||
ls->conf.sndbuf = -1;
|
||||
}
|
||||
|
@ -2165,9 +2287,12 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
sn->regex = NULL;
|
||||
#endif
|
||||
sn->core_srv_conf = conf;
|
||||
sn->name.len = conf->server_name.len;
|
||||
sn->name.data = conf->server_name.data;
|
||||
sn->core_srv_conf = conf;
|
||||
}
|
||||
|
||||
ngx_conf_merge_size_value(conf->connection_pool_size,
|
||||
|
@ -2195,6 +2320,8 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->ignore_invalid_headers,
|
||||
prev->ignore_invalid_headers, 1);
|
||||
|
||||
ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
@ -2250,6 +2377,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
|||
lcf->msie_refresh = NGX_CONF_UNSET;
|
||||
lcf->log_not_found = NGX_CONF_UNSET;
|
||||
lcf->recursive_error_pages = NGX_CONF_UNSET;
|
||||
lcf->server_tokens = NGX_CONF_UNSET;
|
||||
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
|
||||
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
|
||||
|
||||
|
@ -2434,6 +2562,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
|
||||
ngx_conf_merge_value(conf->recursive_error_pages,
|
||||
prev->recursive_error_pages, 0);
|
||||
ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
|
||||
|
||||
if (conf->open_files == NULL) {
|
||||
conf->open_files = prev->open_files;
|
||||
|
@ -2468,7 +2597,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
u.listen = 1;
|
||||
u.default_port = 80;
|
||||
|
||||
if (ngx_parse_url(cf, &u) != NGX_OK) {
|
||||
if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in \"%V\" of the \"listen\" directive",
|
||||
|
@ -2488,9 +2617,9 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ls->family = AF_INET;
|
||||
ls->addr = u.addr.in_addr;
|
||||
ls->port = u.port;
|
||||
ls->file_name = cf->conf_file->file.name;
|
||||
ls->file_name = cf->conf_file->file.name.data;
|
||||
ls->line = cf->conf_file->line;
|
||||
ls->conf.backlog = -1;
|
||||
ls->conf.backlog = NGX_LISTEN_BACKLOG;
|
||||
ls->conf.rcvbuf = -1;
|
||||
ls->conf.sndbuf = -1;
|
||||
|
||||
|
@ -2612,19 +2741,30 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_str_t *value, name;
|
||||
ngx_uint_t i;
|
||||
ngx_http_server_name_t *sn;
|
||||
#if (NGX_PCRE)
|
||||
ngx_str_t err;
|
||||
u_char errstr[NGX_MAX_CONF_ERRSTR];
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
ch = value[1].data[0];
|
||||
|
||||
if (cscf->server_name.data == NULL && value[1].len) {
|
||||
if (ch == '*') {
|
||||
if (ngx_strchr(value[1].data, '*')) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"first server name \"%V\" must not be wildcard",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (value[1].data[0] == '~') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"first server name \"%V\" "
|
||||
"must not be regular expression", &value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
name = value[1];
|
||||
|
||||
if (ch == '.') {
|
||||
|
@ -2668,9 +2808,42 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
sn->regex = NULL;
|
||||
#endif
|
||||
sn->core_srv_conf = cscf;
|
||||
sn->name.len = value[i].len;
|
||||
sn->name.data = value[i].data;
|
||||
sn->core_srv_conf = cscf;
|
||||
|
||||
if (value[i].data[0] != '~') {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
err.len = NGX_MAX_CONF_ERRSTR;
|
||||
err.data = errstr;
|
||||
|
||||
value[i].len--;
|
||||
value[i].data++;
|
||||
|
||||
sn->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
|
||||
&err);
|
||||
|
||||
if (sn->regex == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
sn->name.len = value[i].len;
|
||||
sn->name.data = value[i].data;
|
||||
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the using of the regex \"%V\" "
|
||||
"requires PCRE library", &value[i]);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
@ -2706,6 +2879,14 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (lcf->named && alias) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the \"alias\" directive may not be used "
|
||||
"inside named location");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (lcf->regex && alias) {
|
||||
|
|
|
@ -38,8 +38,8 @@ typedef struct {
|
|||
in_port_t port;
|
||||
int family;
|
||||
|
||||
ngx_str_t file_name;
|
||||
ngx_int_t line;
|
||||
u_char *file_name;
|
||||
ngx_uint_t line;
|
||||
|
||||
ngx_http_listen_conf_t conf;
|
||||
} ngx_http_listen_t;
|
||||
|
@ -79,6 +79,7 @@ struct ngx_http_phase_handler_s {
|
|||
typedef struct {
|
||||
ngx_http_phase_handler_t *handlers;
|
||||
ngx_uint_t server_rewrite_index;
|
||||
ngx_uint_t location_rewrite_index;
|
||||
} ngx_http_phase_engine_t;
|
||||
|
||||
|
||||
|
@ -117,7 +118,8 @@ typedef struct {
|
|||
*/
|
||||
ngx_array_t locations;
|
||||
|
||||
unsigned regex_start:16;
|
||||
unsigned regex_start:15;
|
||||
unsigned named_start:15;
|
||||
unsigned wildcard:1;
|
||||
|
||||
/* array of the ngx_http_listen_t, "listen" directive */
|
||||
|
@ -141,6 +143,7 @@ typedef struct {
|
|||
|
||||
ngx_flag_t optimize_server_names;
|
||||
ngx_flag_t ignore_invalid_headers;
|
||||
ngx_flag_t merge_slashes;
|
||||
} ngx_http_core_srv_conf_t;
|
||||
|
||||
|
||||
|
@ -149,8 +152,10 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
in_addr_t addr;
|
||||
|
||||
/* the default server configuration for this address:port */
|
||||
ngx_http_core_srv_conf_t *core_srv_conf;
|
||||
|
||||
ngx_http_virtual_names_t *virtual_names;
|
||||
} ngx_http_in_addr_t;
|
||||
|
||||
|
@ -173,10 +178,16 @@ typedef struct {
|
|||
in_addr_t addr;
|
||||
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
ngx_hash_wildcard_t *wc_head;
|
||||
ngx_hash_wildcard_t *wc_tail;
|
||||
|
||||
ngx_array_t names; /* array of ngx_http_server_name_t */
|
||||
|
||||
#if (NGX_PCRE)
|
||||
ngx_uint_t nregex;
|
||||
ngx_http_server_name_t *regex;
|
||||
#endif
|
||||
|
||||
/* the default server configuration for this address:port */
|
||||
ngx_http_core_srv_conf_t *core_srv_conf;
|
||||
|
||||
|
@ -187,10 +198,13 @@ typedef struct {
|
|||
} ngx_http_conf_in_addr_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
struct ngx_http_server_name_s {
|
||||
#if (NGX_PCRE)
|
||||
ngx_regex_t *regex;
|
||||
#endif
|
||||
ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */
|
||||
} ngx_http_server_name_t;
|
||||
ngx_str_t name;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -211,9 +225,10 @@ struct ngx_http_core_loc_conf_s {
|
|||
ngx_regex_t *regex;
|
||||
#endif
|
||||
|
||||
unsigned regex_start:16;
|
||||
unsigned regex_start:15;
|
||||
|
||||
unsigned noname:1; /* "if () {}" block */
|
||||
unsigned noname:1; /* "if () {}" block or limit_except */
|
||||
unsigned named:1;
|
||||
|
||||
unsigned exact_match:1;
|
||||
unsigned noregex:1;
|
||||
|
@ -270,6 +285,7 @@ struct ngx_http_core_loc_conf_s {
|
|||
ngx_flag_t msie_refresh; /* msie_refresh */
|
||||
ngx_flag_t log_not_found; /* log_not_found */
|
||||
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
|
||||
ngx_flag_t server_tokens; /* server_tokens */
|
||||
|
||||
ngx_array_t *error_pages; /* error_page */
|
||||
|
||||
|
@ -313,6 +329,8 @@ ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
|
|||
ngx_http_post_subrequest_t *psr, ngx_uint_t flags);
|
||||
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args);
|
||||
ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name);
|
||||
|
||||
|
||||
ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size);
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ ngx_module_t ngx_http_header_filter_module = {
|
|||
};
|
||||
|
||||
|
||||
static char ngx_http_server_string[] = "Server: " NGINX_VER CRLF;
|
||||
static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
||||
static ngx_str_t ngx_http_status_lines[] = {
|
||||
|
@ -237,8 +238,11 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
len += ngx_http_status_lines[status].len;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
len += sizeof(ngx_http_server_string) - 1;
|
||||
len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1:
|
||||
sizeof(ngx_http_server_string) - 1;
|
||||
}
|
||||
|
||||
if (r->headers_out.date == NULL) {
|
||||
|
@ -268,8 +272,6 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->headers_out.location
|
||||
&& r->headers_out.location->value.len
|
||||
&& r->headers_out.location->value.data[0] == '/')
|
||||
|
@ -365,8 +367,16 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
b->last = ngx_cpymem(b->last, ngx_http_server_string,
|
||||
sizeof(ngx_http_server_string) - 1);
|
||||
if (clcf->server_tokens) {
|
||||
p = (u_char *) ngx_http_server_full_string;
|
||||
len = sizeof(ngx_http_server_full_string) - 1;
|
||||
|
||||
} else {
|
||||
p = (u_char *) ngx_http_server_string;
|
||||
len = sizeof(ngx_http_server_string) - 1;
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, p, len);
|
||||
}
|
||||
|
||||
if (r->headers_out.date == NULL) {
|
||||
|
|
|
@ -124,6 +124,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
sw_major_digit,
|
||||
sw_first_minor_digit,
|
||||
sw_minor_digit,
|
||||
sw_spaces_after_digit,
|
||||
sw_almost_done
|
||||
} state;
|
||||
|
||||
|
@ -335,18 +336,26 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
break;
|
||||
}
|
||||
|
||||
r->host_end = p;
|
||||
|
||||
switch (ch) {
|
||||
case ':':
|
||||
r->host_end = p;
|
||||
state = sw_port;
|
||||
break;
|
||||
case '/':
|
||||
r->host_end = p;
|
||||
r->uri_start = p;
|
||||
state = sw_after_slash_in_uri;
|
||||
break;
|
||||
case ' ':
|
||||
/*
|
||||
* use single "/" from request line to preserve pointers,
|
||||
* if request line will be copied to large client buffer
|
||||
*/
|
||||
r->uri_start = r->schema_end + 1;
|
||||
r->uri_end = r->schema_end + 2;
|
||||
state = sw_http_09;
|
||||
break;
|
||||
default:
|
||||
r->host_end = p;
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
break;
|
||||
|
@ -362,6 +371,16 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
r->uri_start = p;
|
||||
state = sw_after_slash_in_uri;
|
||||
break;
|
||||
case ' ':
|
||||
r->port_end = p;
|
||||
/*
|
||||
* use single "/" from request line to preserve pointers,
|
||||
* if request line will be copied to large client buffer
|
||||
*/
|
||||
r->uri_start = r->schema_end + 1;
|
||||
r->uri_end = r->schema_end + 2;
|
||||
state = sw_http_09;
|
||||
break;
|
||||
default:
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
|
@ -618,6 +637,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (ch == ' ') {
|
||||
state = sw_spaces_after_digit;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') {
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
|
@ -625,6 +649,20 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
r->http_minor = r->http_minor * 10 + ch - '0';
|
||||
break;
|
||||
|
||||
case sw_spaces_after_digit:
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
break;
|
||||
case CR:
|
||||
state = sw_almost_done;
|
||||
break;
|
||||
case LF:
|
||||
goto done;
|
||||
default:
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
break;
|
||||
|
||||
/* end of request line */
|
||||
case sw_almost_done:
|
||||
r->request_end = p - 1;
|
||||
|
@ -700,6 +738,7 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
|
||||
/* first char */
|
||||
case sw_start:
|
||||
r->header_name_start = p;
|
||||
r->invalid_header = 0;
|
||||
|
||||
switch (ch) {
|
||||
|
@ -712,7 +751,6 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
goto header_done;
|
||||
default:
|
||||
state = sw_name;
|
||||
r->header_name_start = p;
|
||||
|
||||
c = lowcase[ch];
|
||||
|
||||
|
@ -890,7 +928,7 @@ header_done:
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
|
||||
{
|
||||
u_char c, ch, decoded, *p, *u;
|
||||
enum {
|
||||
|
@ -998,8 +1036,12 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
switch(ch) {
|
||||
#if (NGX_WIN32)
|
||||
case '\\':
|
||||
break;
|
||||
#endif
|
||||
case '/':
|
||||
if (!merge_slashes) {
|
||||
*u++ = ch;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
state = sw_dot;
|
||||
|
@ -1081,11 +1123,15 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
#endif
|
||||
case '/':
|
||||
state = sw_slash;
|
||||
u -= 4;
|
||||
if (u < r->uri.data) {
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
while (*(u - 1) != '/') {
|
||||
u -= 5;
|
||||
for ( ;; ) {
|
||||
if (u < r->uri.data) {
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
if (*u == '/') {
|
||||
u++;
|
||||
break;
|
||||
}
|
||||
u--;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
time_t ngx_http_parse_time(u_char *value, size_t len)
|
||||
time_t
|
||||
ngx_http_parse_time(u_char *value, size_t len)
|
||||
{
|
||||
u_char *p, *end;
|
||||
int day, month, year, hour, min, sec;
|
||||
|
@ -247,7 +248,7 @@ time_t ngx_http_parse_time(u_char *value, size_t len)
|
|||
year -= 1;
|
||||
}
|
||||
|
||||
/* Gauss's formula for Grigorian days from 1 March 1 BC */
|
||||
/* Gauss's formula for Grigorian days from March 1, 1 BC */
|
||||
|
||||
return (365 * year + year / 4 - year / 100 + year / 400
|
||||
+ 367 * month / 12 - 31
|
||||
|
|
|
@ -168,7 +168,7 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
|
|||
pr = r->postponed;
|
||||
|
||||
if (pr == NULL) {
|
||||
return NGX_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pr->request) {
|
||||
|
@ -196,7 +196,7 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
if (pr == NULL) {
|
||||
return NGX_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
out = pr->out;
|
||||
|
@ -215,6 +215,17 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
|
|||
|
||||
r->postponed = r->postponed->next;
|
||||
}
|
||||
|
||||
if (r->out) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter out again \"%V?%V\"",
|
||||
&r->uri, &r->args);
|
||||
|
||||
r->connection->data = r;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
|
|||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
|
||||
|
@ -34,6 +36,7 @@ static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
|
|||
static void ngx_http_writer(ngx_http_request_t *r);
|
||||
|
||||
static void ngx_http_block_read(ngx_http_request_t *r);
|
||||
static void ngx_http_test_read(ngx_http_request_t *r);
|
||||
static void ngx_http_set_keepalive(ngx_http_request_t *r);
|
||||
static void ngx_http_keepalive_handler(ngx_event_t *ev);
|
||||
static void ngx_http_set_lingering_close(ngx_http_request_t *r);
|
||||
|
@ -71,11 +74,11 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
|||
ngx_http_process_unique_header_line },
|
||||
|
||||
{ ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
|
||||
ngx_http_process_unique_header_line },
|
||||
ngx_http_process_connection },
|
||||
|
||||
{ ngx_string("If-Modified-Since"),
|
||||
offsetof(ngx_http_headers_in_t, if_modified_since),
|
||||
ngx_http_process_header_line },
|
||||
ngx_http_process_unique_header_line },
|
||||
|
||||
{ ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
|
||||
ngx_http_process_header_line },
|
||||
|
@ -94,6 +97,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
|||
{ ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
|
||||
ngx_http_process_header_line },
|
||||
|
||||
{ ngx_string("If-Range"),
|
||||
offsetof(ngx_http_headers_in_t, if_range),
|
||||
ngx_http_process_unique_header_line },
|
||||
|
||||
{ ngx_string("Transfer-Encoding"),
|
||||
offsetof(ngx_http_headers_in_t, transfer_encoding),
|
||||
ngx_http_process_header_line },
|
||||
|
@ -600,10 +607,11 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||
static void
|
||||
ngx_http_process_request_line(ngx_event_t *rev)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_int_t rc, rv;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ssize_t n;
|
||||
ngx_int_t rc, rv;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
c = rev->data;
|
||||
r = c->data;
|
||||
|
@ -655,7 +663,9 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
rc = ngx_http_parse_complex_uri(r);
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
|
||||
|
||||
if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
|
@ -836,7 +846,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
|
|||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
"client sent too long header line: \"%V\"",
|
||||
&header);
|
||||
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
|
||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -948,7 +958,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
|
|||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
"client sent invalid header line: \"%V\\r...\"",
|
||||
&header);
|
||||
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
|
||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1145,6 +1155,10 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
|||
r->args_start = new + (r->args_start - old);
|
||||
}
|
||||
|
||||
if (r->http_protocol.data) {
|
||||
r->http_protocol.data = new + (r->http_protocol.data - old);
|
||||
}
|
||||
|
||||
} else {
|
||||
r->header_name_start = new;
|
||||
r->header_name_end = new + (r->header_name_end - old);
|
||||
|
@ -1198,6 +1212,21 @@ ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
|
||||
r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
|
||||
|
||||
} else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
|
||||
r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
|
@ -1294,7 +1323,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->method & (NGX_HTTP_TRACE)) {
|
||||
if (r->method & NGX_HTTP_TRACE) {
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent TRACE method");
|
||||
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
|
||||
|
@ -1302,7 +1331,8 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
if (r->headers_in.transfer_encoding
|
||||
&& ngx_strstr(r->headers_in.transfer_encoding->value.data, "chunked"))
|
||||
&& ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
|
||||
"chunked", 7 - 1))
|
||||
{
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent \"Transfer-Encoding: chunked\" header");
|
||||
|
@ -1310,33 +1340,11 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->plain_http) {
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent plain HTTP request to HTTPS port");
|
||||
ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->headers_in.connection) {
|
||||
if (r->headers_in.connection->value.len == 5
|
||||
&& ngx_strcasecmp(r->headers_in.connection->value.data,
|
||||
(u_char *) "close")
|
||||
== 0)
|
||||
{
|
||||
r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
|
||||
|
||||
} else if (r->headers_in.connection->value.len == 10
|
||||
&& ngx_strcasecmp(r->headers_in.connection->value.data,
|
||||
(u_char *) "keep-alive")
|
||||
== 0)
|
||||
{
|
||||
r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
|
||||
|
||||
if (r->headers_in.keep_alive) {
|
||||
r->headers_in.keep_alive_n =
|
||||
ngx_atotm(r->headers_in.keep_alive->value.data,
|
||||
r->headers_in.keep_alive->value.len);
|
||||
}
|
||||
if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
|
||||
if (r->headers_in.keep_alive) {
|
||||
r->headers_in.keep_alive_n =
|
||||
ngx_atotm(r->headers_in.keep_alive->value.data,
|
||||
r->headers_in.keep_alive->value.len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1349,7 +1357,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
|||
|
||||
user_agent = r->headers_in.user_agent->value.data;
|
||||
|
||||
ua = (u_char *) ngx_strstr(user_agent, "MSIE");
|
||||
ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
|
||||
|
||||
if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) {
|
||||
|
||||
|
@ -1367,7 +1375,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (ngx_strstr(user_agent, "Opera")) {
|
||||
if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
|
||||
r->headers_in.opera = 1;
|
||||
r->headers_in.msie = 0;
|
||||
r->headers_in.msie4 = 0;
|
||||
|
@ -1375,10 +1383,10 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
|||
|
||||
if (!r->headers_in.msie && !r->headers_in.opera) {
|
||||
|
||||
if (ngx_strstr(user_agent, "Gecko/")) {
|
||||
if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
|
||||
r->headers_in.gecko = 1;
|
||||
|
||||
} else if (ngx_strstr(user_agent, "Konqueror")) {
|
||||
} else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
|
||||
r->headers_in.konqueror = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1399,6 +1407,13 @@ ngx_http_process_request(ngx_http_request_t *r)
|
|||
|
||||
c = r->connection;
|
||||
|
||||
if (r->plain_http) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
"client sent plain HTTP request to HTTPS port");
|
||||
ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
|
||||
if (c->ssl) {
|
||||
|
@ -1453,26 +1468,55 @@ static void
|
|||
ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len,
|
||||
ngx_uint_t hash)
|
||||
{
|
||||
ngx_http_virtual_names_t *vn;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
#if (NGX_PCRE)
|
||||
ngx_int_t n;
|
||||
ngx_uint_t i;
|
||||
ngx_str_t name;
|
||||
ngx_http_server_name_t *sn;
|
||||
#endif
|
||||
|
||||
vn = r->virtual_names;
|
||||
cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, host, len);
|
||||
|
||||
if (cscf) {
|
||||
goto found;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (r->virtual_names->nregex) {
|
||||
|
||||
name.len = len;
|
||||
name.data = host;
|
||||
|
||||
sn = r->virtual_names->regex;
|
||||
|
||||
for (i = 0; i < r->virtual_names->nregex; i++) {
|
||||
|
||||
n = ngx_regex_exec(sn[i].regex, &name, NULL, 0);
|
||||
|
||||
if (n == NGX_REGEX_NO_MATCHED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
ngx_regex_exec_n
|
||||
" failed: %d on \"%V\" using \"%V\"",
|
||||
n, &name, &sn[i].name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* match */
|
||||
|
||||
cscf = sn[i].core_srv_conf;
|
||||
|
||||
if (vn->hash.buckets) {
|
||||
cscf = ngx_hash_find(&vn->hash, hash, host, len);
|
||||
if (cscf) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (vn->dns_wildcards && vn->dns_wildcards->hash.buckets) {
|
||||
cscf = ngx_hash_find_wildcard(vn->dns_wildcards, host, len);
|
||||
|
||||
if (cscf) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
|
@ -1710,7 +1754,7 @@ ngx_http_set_write_handler(ngx_http_request_t *r)
|
|||
|
||||
r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
|
||||
|
||||
r->read_event_handler = ngx_http_block_read;
|
||||
r->read_event_handler = ngx_http_test_read;
|
||||
r->write_event_handler = ngx_http_writer;
|
||||
|
||||
wev = r->connection->write;
|
||||
|
@ -1822,6 +1866,26 @@ ngx_http_writer(ngx_http_request_t *r)
|
|||
|
||||
static void
|
||||
ngx_http_block_read(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http read blocked");
|
||||
|
||||
/* aio does not call this handler */
|
||||
|
||||
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
|
||||
&& r->connection->read->active)
|
||||
{
|
||||
if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
ngx_http_close_request(r, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_test_read(ngx_http_request_t *r)
|
||||
{
|
||||
int n;
|
||||
char buf[1];
|
||||
|
@ -1832,7 +1896,7 @@ ngx_http_block_read(ngx_http_request_t *r)
|
|||
c = r->connection;
|
||||
rev = c->read;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http read blocked");
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test read");
|
||||
|
||||
#if (NGX_HAVE_KQUEUE)
|
||||
|
||||
|
@ -1982,7 +2046,8 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
|||
hc->pipeline = 1;
|
||||
c->log->action = "reading client pipelined request line";
|
||||
|
||||
ngx_http_init_request(rev);
|
||||
rev->handler = ngx_http_init_request;
|
||||
ngx_post_event(rev, &ngx_posted_events);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2021,7 +2086,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
|||
|
||||
if (hc->free) {
|
||||
for (i = 0; i < hc->nfree; i++) {
|
||||
ngx_pfree(c->pool, hc->free[i]);
|
||||
ngx_pfree(c->pool, hc->free[i]->start);
|
||||
hc->free[i] = NULL;
|
||||
}
|
||||
|
||||
|
@ -2033,7 +2098,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
|||
|
||||
if (hc->busy) {
|
||||
for (i = 0; i < hc->nbusy; i++) {
|
||||
ngx_pfree(c->pool, hc->busy[i]);
|
||||
ngx_pfree(c->pool, hc->busy[i]->start);
|
||||
hc->busy[i] = NULL;
|
||||
}
|
||||
|
||||
|
@ -2092,7 +2157,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
|||
c->idle = 1;
|
||||
|
||||
if (rev->ready) {
|
||||
ngx_http_keepalive_handler(rev);
|
||||
ngx_post_event(rev, &ngx_posted_events);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2543,28 +2608,21 @@ ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
|
|||
buf = p;
|
||||
}
|
||||
|
||||
if (r->unparsed_uri.data) {
|
||||
p = ngx_snprintf(buf, len, ", URL: \"%V\"", &r->unparsed_uri);
|
||||
if (r->request_line.data == NULL && r->request_start) {
|
||||
for (p = r->request_start; p < r->header_in->last; p++) {
|
||||
if (*p == CR || *p == LF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r->request_line.len = p - r->request_start;
|
||||
r->request_line.data = r->request_start;
|
||||
}
|
||||
|
||||
if (r->request_line.len) {
|
||||
p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
|
||||
len -= p - buf;
|
||||
buf = p;
|
||||
|
||||
} else {
|
||||
if (r->request_line.data == NULL && r->request_start) {
|
||||
for (p = r->request_start; p < r->header_in->last; p++) {
|
||||
if (*p == CR || *p == LF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r->request_line.len = p - r->request_start;
|
||||
r->request_line.data = r->request_start;
|
||||
}
|
||||
|
||||
if (r->request_line.len) {
|
||||
p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
|
||||
len -= p - buf;
|
||||
buf = p;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != sr) {
|
||||
|
|
|
@ -168,6 +168,7 @@ typedef struct {
|
|||
ngx_table_elt_t *content_type;
|
||||
|
||||
ngx_table_elt_t *range;
|
||||
ngx_table_elt_t *if_range;
|
||||
|
||||
ngx_table_elt_t *transfer_encoding;
|
||||
|
||||
|
@ -275,9 +276,14 @@ typedef struct {
|
|||
} ngx_http_connection_t;
|
||||
|
||||
|
||||
typedef struct ngx_http_server_name_s ngx_http_server_name_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
ngx_hash_combined_t names;
|
||||
|
||||
ngx_uint_t nregex;
|
||||
ngx_http_server_name_t *regex;
|
||||
} ngx_http_virtual_names_t;
|
||||
|
||||
|
||||
|
@ -444,7 +450,7 @@ struct ngx_http_request_s {
|
|||
unsigned limit_zone_set:1;
|
||||
|
||||
#if 0
|
||||
unsigned cachable:1;
|
||||
unsigned cacheable:1;
|
||||
#endif
|
||||
|
||||
unsigned pipeline:1;
|
||||
|
|
|
@ -88,6 +88,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
post_handler(r);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
|
|||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
for (i = 0; i < cmcf->variables.nelts; i++) {
|
||||
if (r->variables[i].no_cachable) {
|
||||
if (r->variables[i].no_cacheable) {
|
||||
r->variables[i].valid = 0;
|
||||
r->variables[i].not_found = 0;
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
|
|||
|
||||
|
||||
void
|
||||
ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
|
||||
ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
|
||||
ngx_array_t *indices)
|
||||
{
|
||||
ngx_uint_t n, *index;
|
||||
|
@ -359,7 +359,7 @@ ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
|
|||
if (indices) {
|
||||
index = indices->elts;
|
||||
for (n = 0; n < indices->nelts; n++) {
|
||||
if (r->variables[index[n]].no_cachable) {
|
||||
if (r->variables[index[n]].no_cacheable) {
|
||||
r->variables[index[n]].valid = 0;
|
||||
r->variables[index[n]].not_found = 0;
|
||||
}
|
||||
|
@ -750,7 +750,8 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
|
|||
dst = e->buf.data;
|
||||
src = e->buf.data;
|
||||
|
||||
ngx_unescape_uri(&dst, &src, e->pos - e->buf.data, NGX_UNESCAPE_URI);
|
||||
ngx_unescape_uri(&dst, &src, e->pos - e->buf.data,
|
||||
NGX_UNESCAPE_REDIRECT);
|
||||
|
||||
if (src < e->pos) {
|
||||
dst = ngx_copy(dst, src, e->pos - src);
|
||||
|
@ -1125,7 +1126,7 @@ ngx_http_script_value_code(ngx_http_script_engine_t *e)
|
|||
e->sp->data = (u_char *) code->text_data;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script value: \"%V\"", e->sp);
|
||||
"http script value: \"%v\"", e->sp);
|
||||
|
||||
e->sp++;
|
||||
}
|
||||
|
@ -1150,7 +1151,7 @@ ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
|
|||
|
||||
r->variables[code->index].len = e->sp->len;
|
||||
r->variables[code->index].valid = 1;
|
||||
r->variables[code->index].no_cachable = 0;
|
||||
r->variables[code->index].no_cacheable = 0;
|
||||
r->variables[code->index].not_found = 0;
|
||||
r->variables[code->index].data = e->sp->data;
|
||||
}
|
||||
|
@ -1191,7 +1192,7 @@ ngx_http_script_var_code(ngx_http_script_engine_t *e)
|
|||
|
||||
if (value && !value->not_found) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script var: \"%V\"", value);
|
||||
"http script var: \"%v\"", value);
|
||||
|
||||
*e->sp = *value;
|
||||
e->sp++;
|
||||
|
|
|
@ -181,7 +181,7 @@ ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value);
|
|||
ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);
|
||||
u_char *ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
|
||||
void *code_lengths, size_t reserved, void *code_values);
|
||||
void ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
|
||||
void ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
|
||||
ngx_array_t *indices);
|
||||
|
||||
void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,
|
||||
|
|
|
@ -10,13 +10,27 @@
|
|||
#include <nginx.h>
|
||||
|
||||
|
||||
static u_char error_tail[] =
|
||||
static ngx_int_t ngx_http_send_error_page(ngx_http_request_t *r,
|
||||
ngx_http_err_page_t *err_page);
|
||||
static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r,
|
||||
ngx_http_core_loc_conf_t *clcf, ngx_uint_t err);
|
||||
static ngx_int_t ngx_http_send_refresh(ngx_http_request_t *r);
|
||||
|
||||
|
||||
static u_char ngx_http_error_full_tail[] =
|
||||
"<hr><center>" NGINX_VER "</center>" CRLF
|
||||
"</body>" CRLF
|
||||
"</html>" CRLF
|
||||
;
|
||||
|
||||
|
||||
static u_char ngx_http_error_tail[] =
|
||||
"<hr><center>nginx</center>" CRLF
|
||||
"</body>" CRLF
|
||||
"</html>" CRLF
|
||||
;
|
||||
|
||||
|
||||
static u_char ngx_http_msie_stub[] =
|
||||
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
|
||||
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
|
||||
|
@ -35,7 +49,7 @@ static u_char ngx_http_msie_refresh_tail[] =
|
|||
"\"></head><body></body></html>" CRLF;
|
||||
|
||||
|
||||
static char error_301_page[] =
|
||||
static char ngx_http_error_301_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>301 Moved Permanently</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -43,7 +57,7 @@ static char error_301_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_302_page[] =
|
||||
static char ngx_http_error_302_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>302 Found</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -51,7 +65,7 @@ static char error_302_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_400_page[] =
|
||||
static char ngx_http_error_400_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>400 Bad Request</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -59,7 +73,7 @@ static char error_400_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_401_page[] =
|
||||
static char ngx_http_error_401_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>401 Authorization Required</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -67,7 +81,7 @@ static char error_401_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_402_page[] =
|
||||
static char ngx_http_error_402_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>402 Payment Required</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -75,7 +89,7 @@ static char error_402_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_403_page[] =
|
||||
static char ngx_http_error_403_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>403 Forbidden</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -83,7 +97,7 @@ static char error_403_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_404_page[] =
|
||||
static char ngx_http_error_404_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>404 Not Found</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -91,7 +105,7 @@ static char error_404_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_405_page[] =
|
||||
static char ngx_http_error_405_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>405 Not Allowed</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -99,7 +113,7 @@ static char error_405_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_406_page[] =
|
||||
static char ngx_http_error_406_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>406 Not Acceptable</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -107,7 +121,7 @@ static char error_406_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_408_page[] =
|
||||
static char ngx_http_error_408_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>408 Request Time-out</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -115,7 +129,7 @@ static char error_408_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_409_page[] =
|
||||
static char ngx_http_error_409_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>409 Conflict</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -123,7 +137,7 @@ static char error_409_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_410_page[] =
|
||||
static char ngx_http_error_410_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>410 Gone</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -131,7 +145,7 @@ static char error_410_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_411_page[] =
|
||||
static char ngx_http_error_411_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>411 Length Required</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -139,7 +153,7 @@ static char error_411_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_412_page[] =
|
||||
static char ngx_http_error_412_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>412 Precondition Failed</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -147,7 +161,7 @@ static char error_412_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_413_page[] =
|
||||
static char ngx_http_error_413_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>413 Request Entity Too Large</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -155,7 +169,7 @@ static char error_413_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_414_page[] =
|
||||
static char ngx_http_error_414_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>414 Request-URI Too Large</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -163,7 +177,7 @@ static char error_414_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_415_page[] =
|
||||
static char ngx_http_error_415_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>415 Unsupported Media Type</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -171,7 +185,7 @@ static char error_415_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_416_page[] =
|
||||
static char ngx_http_error_416_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -179,7 +193,7 @@ static char error_416_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_495_page[] =
|
||||
static char ngx_http_error_495_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>400 The SSL certificate error</title></head>"
|
||||
CRLF
|
||||
|
@ -189,7 +203,7 @@ CRLF
|
|||
;
|
||||
|
||||
|
||||
static char error_496_page[] =
|
||||
static char ngx_http_error_496_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>400 No required SSL certificate was sent</title></head>"
|
||||
CRLF
|
||||
|
@ -199,7 +213,7 @@ CRLF
|
|||
;
|
||||
|
||||
|
||||
static char error_497_page[] =
|
||||
static char ngx_http_error_497_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>"
|
||||
CRLF
|
||||
|
@ -209,7 +223,7 @@ CRLF
|
|||
;
|
||||
|
||||
|
||||
static char error_500_page[] =
|
||||
static char ngx_http_error_500_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>500 Internal Server Error</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -217,7 +231,7 @@ static char error_500_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_501_page[] =
|
||||
static char ngx_http_error_501_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>501 Method Not Implemented</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -225,7 +239,7 @@ static char error_501_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_502_page[] =
|
||||
static char ngx_http_error_502_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>502 Bad Gateway</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -233,7 +247,7 @@ static char error_502_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_503_page[] =
|
||||
static char ngx_http_error_503_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -241,7 +255,7 @@ static char error_503_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_504_page[] =
|
||||
static char ngx_http_error_504_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>504 Gateway Time-out</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -249,7 +263,7 @@ static char error_504_page[] =
|
|||
;
|
||||
|
||||
|
||||
static char error_507_page[] =
|
||||
static char ngx_http_error_507_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>507 Insufficient Storage</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
|
@ -257,53 +271,53 @@ static char error_507_page[] =
|
|||
;
|
||||
|
||||
|
||||
static ngx_str_t error_pages[] = {
|
||||
static ngx_str_t ngx_http_error_pages[] = {
|
||||
|
||||
ngx_null_string, /* 201, 204 */
|
||||
ngx_null_string, /* 201, 204 */
|
||||
|
||||
#define NGX_HTTP_LEVEL_200 1
|
||||
|
||||
/* ngx_null_string, */ /* 300 */
|
||||
ngx_string(error_301_page),
|
||||
ngx_string(error_302_page),
|
||||
ngx_null_string, /* 303 */
|
||||
/* ngx_null_string, */ /* 300 */
|
||||
ngx_string(ngx_http_error_301_page),
|
||||
ngx_string(ngx_http_error_302_page),
|
||||
ngx_null_string, /* 303 */
|
||||
|
||||
#define NGX_HTTP_LEVEL_300 3
|
||||
|
||||
ngx_string(error_400_page),
|
||||
ngx_string(error_401_page),
|
||||
ngx_string(error_402_page),
|
||||
ngx_string(error_403_page),
|
||||
ngx_string(error_404_page),
|
||||
ngx_string(error_405_page),
|
||||
ngx_string(error_406_page),
|
||||
ngx_null_string, /* 407 */
|
||||
ngx_string(error_408_page),
|
||||
ngx_string(error_409_page),
|
||||
ngx_string(error_410_page),
|
||||
ngx_string(error_411_page),
|
||||
ngx_string(error_412_page),
|
||||
ngx_string(error_413_page),
|
||||
ngx_string(error_414_page),
|
||||
ngx_string(error_415_page),
|
||||
ngx_string(error_416_page),
|
||||
ngx_string(ngx_http_error_400_page),
|
||||
ngx_string(ngx_http_error_401_page),
|
||||
ngx_string(ngx_http_error_402_page),
|
||||
ngx_string(ngx_http_error_403_page),
|
||||
ngx_string(ngx_http_error_404_page),
|
||||
ngx_string(ngx_http_error_405_page),
|
||||
ngx_string(ngx_http_error_406_page),
|
||||
ngx_null_string, /* 407 */
|
||||
ngx_string(ngx_http_error_408_page),
|
||||
ngx_string(ngx_http_error_409_page),
|
||||
ngx_string(ngx_http_error_410_page),
|
||||
ngx_string(ngx_http_error_411_page),
|
||||
ngx_string(ngx_http_error_412_page),
|
||||
ngx_string(ngx_http_error_413_page),
|
||||
ngx_string(ngx_http_error_414_page),
|
||||
ngx_string(ngx_http_error_415_page),
|
||||
ngx_string(ngx_http_error_416_page),
|
||||
|
||||
#define NGX_HTTP_LEVEL_400 17
|
||||
|
||||
ngx_string(error_495_page), /* 495, https certificate error */
|
||||
ngx_string(error_496_page), /* 496, https no certificate */
|
||||
ngx_string(error_497_page), /* 497, http to https */
|
||||
ngx_string(error_404_page), /* 498, invalid host name */
|
||||
ngx_null_string, /* 499, client had closed connection */
|
||||
ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
|
||||
ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
|
||||
ngx_string(ngx_http_error_497_page), /* 497, http to https */
|
||||
ngx_string(ngx_http_error_404_page), /* 498, canceled */
|
||||
ngx_null_string, /* 499, client has closed connection */
|
||||
|
||||
ngx_string(error_500_page),
|
||||
ngx_string(error_501_page),
|
||||
ngx_string(error_502_page),
|
||||
ngx_string(error_503_page),
|
||||
ngx_string(error_504_page),
|
||||
ngx_null_string, /* 505 */
|
||||
ngx_null_string, /* 506 */
|
||||
ngx_string(error_507_page)
|
||||
ngx_string(ngx_http_error_500_page),
|
||||
ngx_string(ngx_http_error_501_page),
|
||||
ngx_string(ngx_http_error_502_page),
|
||||
ngx_string(ngx_http_error_503_page),
|
||||
ngx_string(ngx_http_error_504_page),
|
||||
ngx_null_string, /* 505 */
|
||||
ngx_null_string, /* 506 */
|
||||
ngx_string(ngx_http_error_507_page)
|
||||
};
|
||||
|
||||
|
||||
|
@ -313,13 +327,8 @@ static ngx_str_t ngx_http_get_name = { 3, (u_char *) "GET " };
|
|||
ngx_int_t
|
||||
ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
||||
{
|
||||
u_char *p;
|
||||
size_t msie_refresh;
|
||||
ngx_int_t rc;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *uri, *location;
|
||||
ngx_uint_t i, n, err, msie_padding;
|
||||
ngx_chain_t *out, *cl;
|
||||
ngx_uint_t i, err;
|
||||
ngx_http_err_page_t *err_page;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
|
@ -370,64 +379,20 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
|||
err_page = clcf->error_pages->elts;
|
||||
|
||||
for (i = 0; i < clcf->error_pages->nelts; i++) {
|
||||
|
||||
if (err_page[i].status == error) {
|
||||
r->err_status = err_page[i].overwrite;
|
||||
|
||||
r->method = NGX_HTTP_GET;
|
||||
r->method_name = ngx_http_get_name;
|
||||
|
||||
uri = &err_page[i].uri;
|
||||
|
||||
if (err_page[i].uri_lengths) {
|
||||
if (ngx_http_script_run(r, uri,
|
||||
err_page[i].uri_lengths->elts, 0,
|
||||
err_page[i].uri_values->elts)
|
||||
== NULL)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->zero_in_uri) {
|
||||
for (n = 0; n < uri->len; n++) {
|
||||
if (uri->data[n] == '\0') {
|
||||
goto zero;
|
||||
}
|
||||
}
|
||||
|
||||
r->zero_in_uri = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
r->zero_in_uri = 0;
|
||||
}
|
||||
|
||||
zero:
|
||||
|
||||
if (uri->data[0] == '/') {
|
||||
return ngx_http_internal_redirect(r, uri, NULL);
|
||||
}
|
||||
|
||||
r->headers_out.location =
|
||||
ngx_list_push(&r->headers_out.headers);
|
||||
|
||||
if (r->headers_out.location) {
|
||||
error = NGX_HTTP_MOVED_TEMPORARILY;
|
||||
|
||||
r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->key.len = sizeof("Location") - 1;
|
||||
r->headers_out.location->key.data = (u_char *) "Location";
|
||||
r->headers_out.location->value = *uri;
|
||||
|
||||
} else {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
return ngx_http_send_error_page(r, &err_page[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clcf->msie_refresh
|
||||
&& r->headers_in.msie
|
||||
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|
||||
|| error == NGX_HTTP_MOVED_TEMPORARILY))
|
||||
{
|
||||
return ngx_http_send_refresh(r);
|
||||
}
|
||||
|
||||
if (error == NGX_HTTP_CREATED) {
|
||||
/* 201 */
|
||||
err = 0;
|
||||
|
@ -456,29 +421,150 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
|||
case NGX_HTTPS_CERT_ERROR:
|
||||
case NGX_HTTPS_NO_CERT:
|
||||
r->err_status = NGX_HTTP_BAD_REQUEST;
|
||||
error = NGX_HTTP_BAD_REQUEST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_http_send_special_response(r, clcf, err);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
|
||||
{
|
||||
u_char ch, *p, *last;
|
||||
ngx_str_t *uri, *args, u, a;
|
||||
ngx_table_elt_t *location;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
r->err_status = err_page->overwrite;
|
||||
|
||||
r->method = NGX_HTTP_GET;
|
||||
r->method_name = ngx_http_get_name;
|
||||
|
||||
r->zero_in_uri = 0;
|
||||
|
||||
args = NULL;
|
||||
|
||||
if (err_page->uri_lengths) {
|
||||
if (ngx_http_script_run(r, &u, err_page->uri_lengths->elts, 0,
|
||||
err_page->uri_values->elts)
|
||||
== NULL)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = u.data;
|
||||
uri = &u;
|
||||
|
||||
if (*p == '/') {
|
||||
|
||||
last = p + uri->len;
|
||||
|
||||
while (p < last) {
|
||||
|
||||
ch = *p++;
|
||||
|
||||
if (ch == '?') {
|
||||
a.len = last - p;
|
||||
a.data = p;
|
||||
args = &a;
|
||||
|
||||
u.len = p - 1 - u.data;
|
||||
|
||||
while (p < last) {
|
||||
if (*p++ == '\0') {
|
||||
r->zero_in_uri = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '\0') {
|
||||
r->zero_in_uri = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
uri = &err_page->uri;
|
||||
}
|
||||
|
||||
if (uri->data[0] == '/') {
|
||||
return ngx_http_internal_redirect(r, uri, args);
|
||||
}
|
||||
|
||||
if (uri->data[0] == '@') {
|
||||
return ngx_http_named_location(r, uri);
|
||||
}
|
||||
|
||||
location = ngx_list_push(&r->headers_out.headers);
|
||||
|
||||
if (location == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
|
||||
|
||||
location->hash = 1;
|
||||
location->key.len = sizeof("Location") - 1;
|
||||
location->key.data = (u_char *) "Location";
|
||||
location->value = *uri;
|
||||
|
||||
r->headers_out.location = location;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (clcf->msie_refresh && r->headers_in.msie) {
|
||||
return ngx_http_send_refresh(r);
|
||||
}
|
||||
|
||||
return ngx_http_send_special_response(r, clcf, NGX_HTTP_MOVED_TEMPORARILY
|
||||
- NGX_HTTP_MOVED_PERMANENTLY
|
||||
+ NGX_HTTP_LEVEL_200);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_send_special_response(ngx_http_request_t *r,
|
||||
ngx_http_core_loc_conf_t *clcf, ngx_uint_t err)
|
||||
{
|
||||
u_char *tail;
|
||||
size_t len;
|
||||
ngx_int_t rc;
|
||||
ngx_buf_t *b;
|
||||
ngx_uint_t msie_padding;
|
||||
ngx_chain_t out[3];
|
||||
|
||||
if (clcf->server_tokens) {
|
||||
len = sizeof(ngx_http_error_full_tail) - 1;
|
||||
tail = ngx_http_error_full_tail;
|
||||
|
||||
} else {
|
||||
len = sizeof(ngx_http_error_tail) - 1;
|
||||
tail = ngx_http_error_tail;
|
||||
}
|
||||
|
||||
msie_padding = 0;
|
||||
|
||||
if (!r->zero_body) {
|
||||
if (error_pages[err].len) {
|
||||
r->headers_out.content_length_n = error_pages[err].len
|
||||
+ sizeof(error_tail) - 1;
|
||||
|
||||
if (ngx_http_error_pages[err].len) {
|
||||
r->headers_out.content_length_n = ngx_http_error_pages[err].len
|
||||
+ len;
|
||||
if (clcf->msie_padding
|
||||
&& r->headers_in.msie
|
||||
&& r->http_version >= NGX_HTTP_VERSION_10
|
||||
&& error >= NGX_HTTP_BAD_REQUEST
|
||||
&& error != NGX_HTTP_REQUEST_URI_TOO_LARGE)
|
||||
&& err >= NGX_HTTP_LEVEL_300)
|
||||
{
|
||||
r->headers_out.content_length_n +=
|
||||
sizeof(ngx_http_msie_stub) - 1;
|
||||
msie_padding = 1;
|
||||
}
|
||||
|
||||
r->headers_out.content_type_len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type.len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type.data = (u_char *) "text/html";
|
||||
|
||||
|
@ -496,24 +582,102 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
|||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
msie_refresh = 0;
|
||||
location = NULL;
|
||||
ngx_http_clear_accept_ranges(r);
|
||||
ngx_http_clear_last_modified(r);
|
||||
|
||||
if (clcf->msie_refresh
|
||||
&& r->headers_in.msie
|
||||
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|
||||
|| error == NGX_HTTP_MOVED_TEMPORARILY))
|
||||
{
|
||||
location = &r->headers_out.location->value;
|
||||
msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
|
||||
+ location->len
|
||||
+ sizeof(ngx_http_msie_refresh_tail) - 1;
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
r->err_status = NGX_HTTP_OK;
|
||||
r->headers_out.content_type_len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_length_n = msie_refresh;
|
||||
r->headers_out.location->hash = 0;
|
||||
r->headers_out.location = NULL;
|
||||
if (rc == NGX_ERROR || r->header_only) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ngx_http_error_pages[err].len == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = ngx_http_error_pages[err].data;
|
||||
b->last = ngx_http_error_pages[err].data + ngx_http_error_pages[err].len;
|
||||
|
||||
out[0].buf = b;
|
||||
out[0].next = &out[1];
|
||||
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
|
||||
b->pos = tail;
|
||||
b->last = tail + len;
|
||||
|
||||
out[1].buf = b;
|
||||
out[1].next = NULL;;
|
||||
|
||||
if (msie_padding) {
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = ngx_http_msie_stub;
|
||||
b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
|
||||
|
||||
out[1].next = &out[2];
|
||||
out[2].buf = b;
|
||||
out[2].next = NULL;;
|
||||
}
|
||||
|
||||
if (r == r->main) {
|
||||
b->last_buf = 1;
|
||||
}
|
||||
|
||||
b->last_in_chain = 1;
|
||||
|
||||
return ngx_http_output_filter(r, &out[0]);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_send_refresh(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *p, *location;
|
||||
size_t len, size;
|
||||
uintptr_t escape;
|
||||
ngx_int_t rc;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t out;
|
||||
|
||||
len = r->headers_out.location->value.len;
|
||||
location = r->headers_out.location->value.data;
|
||||
|
||||
escape = 2 * ngx_escape_uri(NULL, location, len, NGX_ESCAPE_REFRESH);
|
||||
|
||||
size = sizeof(ngx_http_msie_refresh_head) - 1
|
||||
+ escape + len
|
||||
+ sizeof(ngx_http_msie_refresh_tail) - 1;
|
||||
|
||||
r->err_status = NGX_HTTP_OK;
|
||||
|
||||
r->headers_out.content_type_len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type.len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type.data = (u_char *) "text/html";
|
||||
|
||||
r->headers_out.location->hash = 0;
|
||||
r->headers_out.location = NULL;
|
||||
|
||||
r->headers_out.content_length_n = size;
|
||||
|
||||
if (r->headers_out.content_length) {
|
||||
r->headers_out.content_length->hash = 0;
|
||||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
ngx_http_clear_accept_ranges(r);
|
||||
|
@ -525,97 +689,29 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
|||
return rc;
|
||||
}
|
||||
|
||||
b = ngx_create_temp_buf(r->pool, size);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (msie_refresh == 0) {
|
||||
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
|
||||
sizeof(ngx_http_msie_refresh_head) - 1);
|
||||
|
||||
if (error_pages[err].len == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = error_pages[err].data;
|
||||
b->last = error_pages[err].data + error_pages[err].len;
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
out = cl;
|
||||
|
||||
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = error_tail;
|
||||
b->last = error_tail + sizeof(error_tail) - 1;
|
||||
|
||||
cl->next = ngx_alloc_chain_link(r->pool);
|
||||
if (cl->next == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl = cl->next;
|
||||
cl->buf = b;
|
||||
|
||||
if (msie_padding) {
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = ngx_http_msie_stub;
|
||||
b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
|
||||
|
||||
cl->next = ngx_alloc_chain_link(r->pool);
|
||||
if (cl->next == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl = cl->next;
|
||||
cl->buf = b;
|
||||
}
|
||||
if (escape == 0) {
|
||||
p = ngx_cpymem(p, location, len);
|
||||
|
||||
} else {
|
||||
b = ngx_create_temp_buf(r->pool, msie_refresh);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
|
||||
sizeof(ngx_http_msie_refresh_head) - 1);
|
||||
|
||||
p = ngx_cpymem(p, location->data, location->len);
|
||||
|
||||
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
|
||||
sizeof(ngx_http_msie_refresh_tail) - 1);
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
out = cl;
|
||||
p = (u_char *) ngx_escape_uri(p, location, len, NGX_ESCAPE_REFRESH);
|
||||
}
|
||||
|
||||
if (r == r->main) {
|
||||
b->last_buf = 1;
|
||||
}
|
||||
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
|
||||
sizeof(ngx_http_msie_refresh_tail) - 1);
|
||||
|
||||
b->last_buf = 1;
|
||||
b->last_in_chain = 1;
|
||||
|
||||
cl->next = NULL;
|
||||
out.buf = b;
|
||||
out.next = NULL;
|
||||
|
||||
return ngx_http_output_filter(r, out);
|
||||
return ngx_http_output_filter(r, &out);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
|
|||
ssize_t bytes);
|
||||
static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
|
||||
static void ngx_http_upstream_process_body(ngx_event_t *ev);
|
||||
static void ngx_http_upstream_store(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static void ngx_http_upstream_dummy_handler(ngx_event_t *wev);
|
||||
static void ngx_http_upstream_next(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u, ngx_uint_t ft_type);
|
||||
|
@ -116,6 +118,12 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
|||
ngx_http_upstream_copy_header_line,
|
||||
offsetof(ngx_http_headers_out_t, date), 0 },
|
||||
|
||||
{ ngx_string("Last-Modified"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, last_modified),
|
||||
ngx_http_upstream_copy_header_line,
|
||||
offsetof(ngx_http_headers_out_t, last_modified), 0 },
|
||||
|
||||
{ ngx_string("Server"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, server),
|
||||
|
@ -364,6 +372,8 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||
cln->data = r;
|
||||
u->cleanup = &cln->handler;
|
||||
|
||||
u->store = (u->conf->store || u->conf->store_lengths);
|
||||
|
||||
ngx_http_upstream_connect(r, u);
|
||||
}
|
||||
|
||||
|
@ -424,7 +434,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
|||
ev->error = 1;
|
||||
}
|
||||
|
||||
if (!u->cachable && u->peer.connection) {
|
||||
if (!u->cacheable && !u->store && u->peer.connection) {
|
||||
ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
|
||||
"kevent() reported that client closed prematurely "
|
||||
"connection, so upstream connection is closed too");
|
||||
|
@ -490,7 +500,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
|||
ev->eof = 1;
|
||||
c->error = 1;
|
||||
|
||||
if (!u->cachable && u->peer.connection) {
|
||||
if (!u->cacheable && !u->store && u->peer.connection) {
|
||||
ngx_log_error(NGX_LOG_INFO, ev->log, err,
|
||||
"client closed prematurely connection, "
|
||||
"so upstream connection is closed too");
|
||||
|
@ -571,7 +581,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
c->write->handler = ngx_http_upstream_send_request_handler;
|
||||
c->read->handler = ngx_http_upstream_process_header;
|
||||
|
||||
c->sendfile = r->connection->sendfile;
|
||||
c->sendfile &= r->connection->sendfile;
|
||||
|
||||
c->pool = r->pool;
|
||||
c->read->log = c->write->log = c->log = r->connection->log;
|
||||
|
@ -657,7 +667,7 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
|||
c->sendfile = 0;
|
||||
u->output.sendfile = 0;
|
||||
|
||||
if (ngx_ssl_set_session(c, u->peer.ssl_session) != NGX_OK) {
|
||||
if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
@ -968,8 +978,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
#endif
|
||||
}
|
||||
|
||||
n = u->peer.connection->recv(u->peer.connection, u->buffer.last,
|
||||
u->buffer.end - u->buffer.last);
|
||||
n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
#if 0
|
||||
|
@ -1032,7 +1041,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
@ -1226,6 +1235,8 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
r->headers_out.status = u->headers_in.status_n;
|
||||
r->headers_out.status_line = u->headers_in.status_line;
|
||||
|
||||
u->headers_in.content_length_n = r->headers_out.content_length_n;
|
||||
|
||||
if (r->headers_out.content_length_n != -1) {
|
||||
u->length = (size_t) r->headers_out.content_length_n;
|
||||
|
||||
|
@ -1278,6 +1289,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
|
|||
|
||||
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
|
||||
if (c->write->pending_eof) {
|
||||
c->log->action = "connecting to upstream";
|
||||
(void) ngx_connection_error(c, c->write->kq_errno,
|
||||
"kevent() reported that connect() failed");
|
||||
return NGX_ERROR;
|
||||
|
@ -1301,6 +1313,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
|
|||
}
|
||||
|
||||
if (err) {
|
||||
c->log->action = "connecting to upstream";
|
||||
(void) ngx_connection_error(c, err, "connect() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -1478,6 +1491,11 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->peer.connection->read->ready) {
|
||||
ngx_http_upstream_process_non_buffered_body(
|
||||
u->peer.connection->read);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1495,7 +1513,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
}
|
||||
}
|
||||
|
||||
if (u->cachable) {
|
||||
if (u->cacheable) {
|
||||
header = (ngx_http_cache_header_t *) u->buffer->start;
|
||||
|
||||
header->expires = u->cache->ctx.expires;
|
||||
|
@ -1523,7 +1541,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
p->pool = r->pool;
|
||||
p->log = c->log;
|
||||
|
||||
p->cachable = u->cachable;
|
||||
p->cacheable = u->cacheable || u->store;
|
||||
|
||||
p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
|
||||
if (p->temp_file == NULL) {
|
||||
|
@ -1536,8 +1554,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
p->temp_file->path = u->conf->temp_path;
|
||||
p->temp_file->pool = r->pool;
|
||||
|
||||
if (u->cachable) {
|
||||
if (u->cacheable || u->store) {
|
||||
p->temp_file->persistent = 1;
|
||||
|
||||
} else {
|
||||
p->temp_file->log_level = NGX_LOG_WARN;
|
||||
p->temp_file->warn = "an upstream response is buffered "
|
||||
|
@ -1552,18 +1571,21 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
p->preread_bufs->buf = &u->buffer;
|
||||
p->preread_bufs->next = NULL;
|
||||
u->buffer.recycled = 1;
|
||||
|
||||
p->preread_size = u->buffer.last - u->buffer.pos;
|
||||
|
||||
if (u->cachable) {
|
||||
if (u->cacheable) {
|
||||
|
||||
p->buf_to_file = ngx_calloc_buf(r->pool);
|
||||
if (p->buf_to_file == NULL) {
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
p->buf_to_file->pos = u->buffer.start;
|
||||
p->buf_to_file->last = u->buffer.pos;
|
||||
p->buf_to_file->temporary = 1;
|
||||
|
@ -1818,6 +1840,7 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
|
|||
static void
|
||||
ngx_http_upstream_process_body(ngx_event_t *ev)
|
||||
{
|
||||
ngx_temp_file_t *tf;
|
||||
ngx_event_pipe_t *p;
|
||||
ngx_connection_t *c, *downstream;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
|
@ -1910,16 +1933,41 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
|
|||
|
||||
if (u->peer.connection) {
|
||||
|
||||
if (u->store) {
|
||||
|
||||
tf = u->pipe->temp_file;
|
||||
|
||||
if (p->upstream_eof
|
||||
&& u->headers_in.status_n == NGX_HTTP_OK
|
||||
&& (u->headers_in.content_length_n == -1
|
||||
|| (u->headers_in.content_length_n == tf->offset)))
|
||||
{
|
||||
ngx_http_upstream_store(r, u);
|
||||
|
||||
} else if ((p->upstream_error
|
||||
|| (p->upstream_eof
|
||||
&& u->headers_in.status_n != NGX_HTTP_OK))
|
||||
&& tf->file.fd != NGX_INVALID_FILE)
|
||||
{
|
||||
if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
||||
ngx_delete_file_n " \"%s\" failed",
|
||||
u->pipe->temp_file->file.name.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_FILE_CACHE)
|
||||
|
||||
if (p->upstream_done && u->cachable) {
|
||||
if (p->upstream_done && u->cacheable) {
|
||||
if (ngx_http_cache_update(r) == NGX_ERROR) {
|
||||
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (p->upstream_eof && u->cachable) {
|
||||
} else if (p->upstream_eof && u->cacheable) {
|
||||
|
||||
/* TODO: check length & update cache */
|
||||
|
||||
|
@ -1947,13 +1995,150 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http upstream downstream error");
|
||||
|
||||
if (!u->cachable && u->peer.connection) {
|
||||
if (!u->cacheable && u->peer.connection) {
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
{
|
||||
char *failed;
|
||||
u_char *name;
|
||||
size_t root;
|
||||
time_t lm;
|
||||
ngx_err_t err;
|
||||
ngx_str_t *temp, path, *last_modified;
|
||||
ngx_temp_file_t *tf;
|
||||
|
||||
if (u->pipe->temp_file->file.fd == NGX_INVALID_FILE) {
|
||||
|
||||
/* create file for empty 200 response */
|
||||
|
||||
tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
|
||||
if (tf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
tf->file.fd = NGX_INVALID_FILE;
|
||||
tf->file.log = r->connection->log;
|
||||
tf->path = u->conf->temp_path;
|
||||
tf->pool = r->pool;
|
||||
tf->persistent = 1;
|
||||
|
||||
if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
|
||||
tf->persistent, tf->clean, tf->access)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
u->pipe->temp_file = tf;
|
||||
}
|
||||
|
||||
temp = &u->pipe->temp_file->file.name;
|
||||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
if (ngx_change_file_access(temp->data, u->conf->store_access)
|
||||
== NGX_FILE_ERROR)
|
||||
{
|
||||
err = ngx_errno;
|
||||
failed = ngx_change_file_access_n;
|
||||
name = temp->data;
|
||||
|
||||
goto failed;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (r->upstream->headers_in.last_modified) {
|
||||
|
||||
last_modified = &r->upstream->headers_in.last_modified->value;
|
||||
|
||||
lm = ngx_http_parse_time(last_modified->data, last_modified->len);
|
||||
|
||||
if (lm != NGX_ERROR) {
|
||||
if (ngx_set_file_time(temp->data, u->pipe->temp_file->file.fd, lm)
|
||||
!= NGX_OK)
|
||||
{
|
||||
err = ngx_errno;
|
||||
failed = ngx_set_file_time_n;
|
||||
name = temp->data;
|
||||
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (u->conf->store_lengths == NULL) {
|
||||
|
||||
ngx_http_map_uri_to_path(r, &path, &root, 0);
|
||||
|
||||
} else {
|
||||
if (ngx_http_script_run(r, &path, u->conf->store_lengths->elts, 0,
|
||||
u->conf->store_values->elts)
|
||||
== NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"upstream stores \"%s\" to \"%s\"", temp->data, path.data);
|
||||
|
||||
failed = ngx_rename_file_n;
|
||||
name = path.data;
|
||||
|
||||
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
err = ngx_errno;
|
||||
|
||||
if (err == NGX_ENOENT) {
|
||||
|
||||
err = ngx_create_full_path(path.data,
|
||||
ngx_dir_access(u->conf->store_access));
|
||||
if (err == 0) {
|
||||
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
err = ngx_errno;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_WIN32)
|
||||
|
||||
if (err == NGX_EEXIST) {
|
||||
if (ngx_win32_rename_file(temp, &path, r->pool) != NGX_ERROR) {
|
||||
|
||||
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
err = ngx_errno;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
failed:
|
||||
|
||||
if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
||||
ngx_delete_file_n " \"%s\" failed",
|
||||
temp->data);
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
|
||||
"%s \"%s\" failed", failed, name);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_dummy_handler(ngx_event_t *wev)
|
||||
{
|
||||
|
@ -2157,8 +2342,17 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||
|
||||
r->connection->log->action = "sending to client";
|
||||
|
||||
if (rc == 0 && r == r->main && !r->post_action) {
|
||||
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
|
||||
if (rc == 0) {
|
||||
if (r == r->main) {
|
||||
if (!r->post_action) {
|
||||
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (r->out) {
|
||||
rc = NGX_AGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngx_http_finalize_request(r, rc);
|
||||
|
@ -2349,6 +2543,10 @@ ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
|
|||
|
||||
while (*++p == ' ') { /* void */ }
|
||||
|
||||
if (*p == '\0') {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2444,7 +2642,7 @@ ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
|
|||
|
||||
if (r->upstream->rewrite_redirect) {
|
||||
|
||||
p = (u_char *) ngx_strstr(ho->value.data, "url=");
|
||||
p = ngx_strcasestrn(ho->value.data, "url=", 4 - 1);
|
||||
|
||||
if (p) {
|
||||
rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data);
|
||||
|
@ -2523,7 +2721,7 @@ ngx_http_upstream_addr_variable(ngx_http_request_t *r,
|
|||
ngx_http_upstream_state_t *state;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
|
||||
|
@ -2594,7 +2792,7 @@ ngx_http_upstream_status_variable(ngx_http_request_t *r,
|
|||
ngx_http_upstream_state_t *state;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
|
||||
|
@ -2660,7 +2858,7 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
|||
ngx_http_upstream_state_t *state;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
|
||||
|
@ -2874,7 +3072,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
u.url = value[1];
|
||||
u.default_port = 80;
|
||||
|
||||
if (ngx_parse_url(cf, &u) != NGX_OK) {
|
||||
if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in upstream \"%V\"", u.err, &u.url);
|
||||
|
@ -2978,7 +3176,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
|
|||
|
||||
if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
|
||||
|
||||
if (ngx_parse_url(cf, u) != NGX_OK) {
|
||||
if (ngx_parse_url(cf->pool, u) != NGX_OK) {
|
||||
if (u->err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in upstream \"%V\"", u->err, &u->url);
|
||||
|
@ -3020,7 +3218,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
|
|||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"upstream \"%V\" may not have port %d in %s:%ui",
|
||||
&u->host, uscfp[i]->port,
|
||||
uscfp[i]->file_name.data, uscfp[i]->line);
|
||||
uscfp[i]->file_name, uscfp[i]->line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3028,6 +3226,12 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (uscfp[i]->default_port && u->default_port
|
||||
&& uscfp[i]->default_port != u->default_port)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return uscfp[i];
|
||||
}
|
||||
|
||||
|
@ -3038,7 +3242,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
|
|||
|
||||
uscf->flags = flags;
|
||||
uscf->host = u->host;
|
||||
uscf->file_name = cf->conf_file->file.name;
|
||||
uscf->file_name = cf->conf_file->file.name.data;
|
||||
uscf->line = cf->conf_file->line;
|
||||
uscf->port = u->port;
|
||||
uscf->default_port = u->default_port;
|
||||
|
@ -3072,6 +3276,113 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
|
||||
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
|
||||
ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
|
||||
{
|
||||
ngx_str_t *h;
|
||||
ngx_uint_t i, j;
|
||||
ngx_array_t hide_headers;
|
||||
ngx_hash_key_t *hk;
|
||||
|
||||
if (conf->hide_headers == NGX_CONF_UNSET_PTR
|
||||
&& conf->pass_headers == NGX_CONF_UNSET_PTR)
|
||||
{
|
||||
conf->hide_headers_hash = prev->hide_headers_hash;
|
||||
|
||||
if (conf->hide_headers_hash.buckets) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
conf->hide_headers = prev->hide_headers;
|
||||
conf->pass_headers = prev->pass_headers;
|
||||
|
||||
} else {
|
||||
if (conf->hide_headers == NGX_CONF_UNSET_PTR) {
|
||||
conf->hide_headers = prev->hide_headers;
|
||||
}
|
||||
|
||||
if (conf->pass_headers == NGX_CONF_UNSET_PTR) {
|
||||
conf->pass_headers = prev->pass_headers;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (h = default_hide_headers; h->len; h++) {
|
||||
hk = ngx_array_push(&hide_headers);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *h;
|
||||
hk->key_hash = ngx_hash_key_lc(h->data, h->len);
|
||||
hk->value = (void *) 1;
|
||||
}
|
||||
|
||||
if (conf->hide_headers != NGX_CONF_UNSET_PTR) {
|
||||
|
||||
h = conf->hide_headers->elts;
|
||||
|
||||
for (i = 0; i < conf->hide_headers->nelts; i++) {
|
||||
|
||||
hk = hide_headers.elts;
|
||||
|
||||
for (j = 0; j < hide_headers.nelts; j++) {
|
||||
if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
|
||||
goto exist;
|
||||
}
|
||||
}
|
||||
|
||||
hk = ngx_array_push(&hide_headers);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = h[i];
|
||||
hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);
|
||||
hk->value = (void *) 1;
|
||||
|
||||
exist:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->pass_headers != NGX_CONF_UNSET_PTR) {
|
||||
|
||||
h = conf->pass_headers->elts;
|
||||
hk = hide_headers.elts;
|
||||
|
||||
for (i = 0; i < conf->pass_headers->nelts; i++) {
|
||||
for (j = 0; j < hide_headers.nelts; j++) {
|
||||
|
||||
if (hk[j].key.data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
|
||||
hk[j].key.data = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hash->hash = &conf->hide_headers_hash;
|
||||
hash->key = ngx_hash_key_lc;
|
||||
hash->pool = cf->pool;
|
||||
hash->temp_pool = NULL;
|
||||
|
||||
return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
|
@ -91,7 +91,7 @@ struct ngx_http_upstream_srv_conf_s {
|
|||
|
||||
ngx_uint_t flags;
|
||||
ngx_str_t host;
|
||||
ngx_str_t file_name;
|
||||
u_char *file_name;
|
||||
ngx_uint_t line;
|
||||
in_port_t port;
|
||||
in_port_t default_port;
|
||||
|
@ -118,6 +118,7 @@ typedef struct {
|
|||
size_t temp_file_write_size_conf;
|
||||
|
||||
ngx_uint_t next_upstream;
|
||||
ngx_uint_t store_access;
|
||||
|
||||
ngx_bufs_t bufs;
|
||||
|
||||
|
@ -140,6 +141,10 @@ typedef struct {
|
|||
ngx_str_t location;
|
||||
ngx_str_t url; /* used in proxy_rewrite_location */
|
||||
|
||||
ngx_array_t *store_lengths;
|
||||
ngx_array_t *store_values;
|
||||
|
||||
signed store:2;
|
||||
unsigned intercept_404:1;
|
||||
unsigned change_buffering:1;
|
||||
|
||||
|
@ -189,6 +194,8 @@ typedef struct {
|
|||
ngx_table_elt_t *content_encoding;
|
||||
#endif
|
||||
|
||||
off_t content_length_n;
|
||||
|
||||
ngx_array_t cache_control;
|
||||
} ngx_http_upstream_headers_in_t;
|
||||
|
||||
|
@ -237,7 +244,8 @@ struct ngx_http_upstream_s {
|
|||
|
||||
ngx_http_cleanup_pt *cleanup;
|
||||
|
||||
unsigned cachable:1;
|
||||
unsigned store:1;
|
||||
unsigned cacheable:1;
|
||||
unsigned accel:1;
|
||||
|
||||
unsigned buffering:1;
|
||||
|
@ -253,6 +261,9 @@ ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
|||
void ngx_http_upstream_init(ngx_http_request_t *r);
|
||||
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
||||
ngx_url_t *u, ngx_uint_t flags);
|
||||
ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
|
||||
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
|
||||
ngx_str_t *default_hide_headers, ngx_hash_init_t *hash);
|
||||
|
||||
|
||||
#define ngx_http_conf_upstream_srv_conf(uscf, module) \
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue