Merged with the default branch.
This commit is contained in:
commit
217bec97be
18 changed files with 813 additions and 358 deletions
|
@ -4,87 +4,62 @@
|
||||||
|
|
||||||
|
|
||||||
if [ $PCRE != NONE ]; then
|
if [ $PCRE != NONE ]; then
|
||||||
CORE_INCS="$CORE_INCS $PCRE"
|
|
||||||
|
|
||||||
case "$NGX_CC_NAME" in
|
if [ -f $PCRE/src/pcre2.h.generic ]; then
|
||||||
|
|
||||||
msvc | owc | bcc)
|
PCRE_LIBRARY=PCRE2
|
||||||
have=NGX_PCRE . auto/have
|
|
||||||
|
have=NGX_PCRE . auto/have
|
||||||
|
have=NGX_PCRE2 . auto/have
|
||||||
|
|
||||||
|
if [ "$NGX_PLATFORM" = win32 ]; then
|
||||||
|
have=PCRE2_STATIC . auto/have
|
||||||
|
fi
|
||||||
|
|
||||||
|
CORE_INCS="$CORE_INCS $PCRE/src/"
|
||||||
|
CORE_DEPS="$CORE_DEPS $PCRE/src/pcre2.h"
|
||||||
|
|
||||||
|
case "$NGX_CC_NAME" in
|
||||||
|
|
||||||
|
msvc)
|
||||||
|
LINK_DEPS="$LINK_DEPS $PCRE/src/pcre2-8.lib"
|
||||||
|
CORE_LIBS="$CORE_LIBS $PCRE/src/pcre2-8.lib"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre2-8.a"
|
||||||
|
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre2-8.a"
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
PCRE_LIBRARY=PCRE
|
||||||
|
|
||||||
|
have=NGX_PCRE . auto/have
|
||||||
|
|
||||||
|
if [ "$NGX_PLATFORM" = win32 ]; then
|
||||||
have=PCRE_STATIC . auto/have
|
have=PCRE_STATIC . auto/have
|
||||||
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
|
fi
|
||||||
LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
|
|
||||||
;;
|
|
||||||
|
|
||||||
icc)
|
CORE_INCS="$CORE_INCS $PCRE"
|
||||||
have=NGX_PCRE . auto/have
|
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
|
||||||
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
|
|
||||||
|
|
||||||
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
|
case "$NGX_CC_NAME" in
|
||||||
|
|
||||||
echo $ngx_n "checking for PCRE library ...$ngx_c"
|
msvc | owc | bcc)
|
||||||
|
LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
|
||||||
|
CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
|
||||||
|
;;
|
||||||
|
|
||||||
if [ -f $PCRE/pcre.h ]; then
|
*)
|
||||||
ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
|
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
|
||||||
| sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
|
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
|
||||||
|
;;
|
||||||
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"
|
|
||||||
|
|
||||||
# to allow -ipo optimization we link with the *.o but not library
|
|
||||||
|
|
||||||
case "$ngx_pcre_ver" in
|
|
||||||
4|5)
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
|
|
||||||
;;
|
|
||||||
|
|
||||||
6)
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/pcre_newline.o"
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
have=NGX_PCRE . auto/have
|
|
||||||
|
|
||||||
if [ "$NGX_PLATFORM" = win32 ]; then
|
|
||||||
have=PCRE_STATIC . auto/have
|
|
||||||
fi
|
|
||||||
|
|
||||||
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
|
|
||||||
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
|
|
||||||
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $PCRE_JIT = YES ]; then
|
if [ $PCRE_JIT = YES ]; then
|
||||||
have=NGX_HAVE_PCRE_JIT . auto/have
|
have=NGX_HAVE_PCRE_JIT . auto/have
|
||||||
|
@ -94,8 +69,48 @@ if [ $PCRE != NONE ]; then
|
||||||
else
|
else
|
||||||
|
|
||||||
if [ "$NGX_PLATFORM" != win32 ]; then
|
if [ "$NGX_PLATFORM" != win32 ]; then
|
||||||
|
|
||||||
PCRE=NO
|
PCRE=NO
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $PCRE = NO -a $PCRE2 != DISABLED ]; then
|
||||||
|
|
||||||
|
ngx_feature="PCRE2 library"
|
||||||
|
ngx_feature_name="NGX_PCRE2"
|
||||||
|
ngx_feature_run=no
|
||||||
|
ngx_feature_incs="#define PCRE2_CODE_UNIT_WIDTH 8
|
||||||
|
#include <pcre2.h>"
|
||||||
|
ngx_feature_path=
|
||||||
|
ngx_feature_libs="-lpcre2-8"
|
||||||
|
ngx_feature_test="pcre2_code *re;
|
||||||
|
re = pcre2_compile(NULL, 0, 0, NULL, NULL, NULL);
|
||||||
|
if (re == NULL) return 1"
|
||||||
|
. auto/feature
|
||||||
|
|
||||||
|
if [ $ngx_found = no ]; then
|
||||||
|
|
||||||
|
# pcre2-config
|
||||||
|
|
||||||
|
ngx_pcre2_prefix=`pcre2-config --prefix 2>/dev/null`
|
||||||
|
|
||||||
|
if [ -n "$ngx_pcre2_prefix" ]; then
|
||||||
|
ngx_feature="PCRE2 library in $ngx_pcre2_prefix"
|
||||||
|
ngx_feature_path=`pcre2-config --cflags \
|
||||||
|
| sed -n -e 's/.*-I *\([^ ][^ ]*\).*/\1/p'`
|
||||||
|
ngx_feature_libs=`pcre2-config --libs8`
|
||||||
|
. auto/feature
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $ngx_found = yes ]; then
|
||||||
|
have=NGX_PCRE . auto/have
|
||||||
|
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
||||||
|
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||||
|
PCRE=YES
|
||||||
|
PCRE_LIBRARY=PCRE2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $PCRE = NO ]; then
|
||||||
|
|
||||||
ngx_feature="PCRE library"
|
ngx_feature="PCRE library"
|
||||||
ngx_feature_name="NGX_PCRE"
|
ngx_feature_name="NGX_PCRE"
|
||||||
|
@ -171,6 +186,7 @@ else
|
||||||
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
||||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||||
PCRE=YES
|
PCRE=YES
|
||||||
|
PCRE_LIBRARY=PCRE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $PCRE = YES ]; then
|
if [ $PCRE = YES ]; then
|
||||||
|
|
|
@ -3,36 +3,138 @@
|
||||||
# Copyright (C) Nginx, Inc.
|
# Copyright (C) Nginx, Inc.
|
||||||
|
|
||||||
|
|
||||||
case "$NGX_CC_NAME" in
|
if [ $PCRE_LIBRARY = PCRE2 ]; then
|
||||||
|
|
||||||
msvc)
|
# PCRE2
|
||||||
ngx_makefile=makefile.msvc
|
|
||||||
ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
|
|
||||||
ngx_pcre="PCRE=\"$PCRE\""
|
|
||||||
;;
|
|
||||||
|
|
||||||
owc)
|
if [ $NGX_CC_NAME = msvc ]; then
|
||||||
ngx_makefile=makefile.owc
|
|
||||||
ngx_opt="CPU_OPT=\"$CPU_OPT\""
|
|
||||||
ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
|
|
||||||
;;
|
|
||||||
|
|
||||||
bcc)
|
# With PCRE2, it is not possible to compile all sources.
|
||||||
ngx_makefile=makefile.bcc
|
# Since list of source files changes between versions, we
|
||||||
ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
|
# test files which might not be present.
|
||||||
ngx_pcre=`echo \-DPCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
ngx_pcre_srcs="pcre2_auto_possess.c \
|
||||||
ngx_makefile=
|
pcre2_chartables.c \
|
||||||
;;
|
pcre2_compile.c \
|
||||||
|
pcre2_config.c \
|
||||||
|
pcre2_context.c \
|
||||||
|
pcre2_dfa_match.c \
|
||||||
|
pcre2_error.c \
|
||||||
|
pcre2_jit_compile.c \
|
||||||
|
pcre2_maketables.c \
|
||||||
|
pcre2_match.c \
|
||||||
|
pcre2_match_data.c \
|
||||||
|
pcre2_newline.c \
|
||||||
|
pcre2_ord2utf.c \
|
||||||
|
pcre2_pattern_info.c \
|
||||||
|
pcre2_string_utils.c \
|
||||||
|
pcre2_study.c \
|
||||||
|
pcre2_substitute.c \
|
||||||
|
pcre2_substring.c \
|
||||||
|
pcre2_tables.c \
|
||||||
|
pcre2_ucd.c \
|
||||||
|
pcre2_valid_utf.c \
|
||||||
|
pcre2_xclass.c"
|
||||||
|
|
||||||
esac
|
ngx_pcre_test="pcre2_convert.c \
|
||||||
|
pcre2_extuni.c \
|
||||||
|
pcre2_find_bracket.c \
|
||||||
|
pcre2_script_run.c \
|
||||||
|
pcre2_serialize.c"
|
||||||
|
|
||||||
|
for ngx_src in $ngx_pcre_test
|
||||||
|
do
|
||||||
|
if [ -f $PCRE/src/$ngx_src ]; then
|
||||||
|
ngx_pcre_srcs="$ngx_pcre_srcs $ngx_src"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
ngx_pcre_objs=`echo $ngx_pcre_srcs \
|
||||||
|
| sed -e "s#\([^ ]*\.\)c#\1$ngx_objext#g"`
|
||||||
|
|
||||||
|
ngx_pcre_srcs=`echo $ngx_pcre_srcs \
|
||||||
|
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g"`
|
||||||
|
ngx_pcre_objs=`echo $ngx_pcre_objs \
|
||||||
|
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g"`
|
||||||
|
|
||||||
|
cat << END >> $NGX_MAKEFILE
|
||||||
|
|
||||||
|
PCRE_CFLAGS = -O2 -Ob1 -Oi -Gs $LIBC $CPU_OPT
|
||||||
|
PCRE_FLAGS = -DHAVE_CONFIG_H -DPCRE2_STATIC -DPCRE2_CODE_UNIT_WIDTH=8 \\
|
||||||
|
-DHAVE_MEMMOVE
|
||||||
|
|
||||||
|
PCRE_SRCS = $ngx_pcre_srcs
|
||||||
|
PCRE_OBJS = $ngx_pcre_objs
|
||||||
|
|
||||||
|
$PCRE/src/pcre2.h:
|
||||||
|
cd $PCRE/src \\
|
||||||
|
&& copy /y config.h.generic config.h \\
|
||||||
|
&& copy /y pcre2.h.generic pcre2.h \\
|
||||||
|
&& copy /y pcre2_chartables.c.dist pcre2_chartables.c
|
||||||
|
|
||||||
|
$PCRE/src/pcre2-8.lib: $PCRE/src/pcre2.h $NGX_MAKEFILE
|
||||||
|
cd $PCRE/src \\
|
||||||
|
&& cl -nologo -c \$(PCRE_CFLAGS) -I . \$(PCRE_FLAGS) \$(PCRE_SRCS) \\
|
||||||
|
&& link -lib -out:pcre2-8.lib -verbose:lib \$(PCRE_OBJS)
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cat << END >> $NGX_MAKEFILE
|
||||||
|
|
||||||
|
$PCRE/src/pcre2.h: $PCRE/Makefile
|
||||||
|
|
||||||
|
$PCRE/Makefile: $NGX_MAKEFILE
|
||||||
|
cd $PCRE \\
|
||||||
|
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
|
||||||
|
&& CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
|
||||||
|
./configure --disable-shared $PCRE_CONF_OPT
|
||||||
|
|
||||||
|
$PCRE/.libs/libpcre2-8.a: $PCRE/Makefile
|
||||||
|
cd $PCRE \\
|
||||||
|
&& \$(MAKE) libpcre2-8.la
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ -n "$ngx_makefile" ]; then
|
else
|
||||||
|
|
||||||
cat << END >> $NGX_MAKEFILE
|
# PCRE
|
||||||
|
|
||||||
|
case "$NGX_CC_NAME" in
|
||||||
|
|
||||||
|
msvc)
|
||||||
|
ngx_makefile=makefile.msvc
|
||||||
|
ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
|
||||||
|
ngx_pcre="PCRE=\"$PCRE\""
|
||||||
|
;;
|
||||||
|
|
||||||
|
owc)
|
||||||
|
ngx_makefile=makefile.owc
|
||||||
|
ngx_opt="CPU_OPT=\"$CPU_OPT\""
|
||||||
|
ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
|
||||||
|
;;
|
||||||
|
|
||||||
|
bcc)
|
||||||
|
ngx_makefile=makefile.bcc
|
||||||
|
ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
|
||||||
|
ngx_pcre=`echo \-DPCRE=\"$PCRE\" \
|
||||||
|
| sed -e "s/\//$ngx_regex_dirsep/g"`
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
ngx_makefile=
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$ngx_makefile" ]; then
|
||||||
|
|
||||||
|
cat << END >> $NGX_MAKEFILE
|
||||||
|
|
||||||
`echo "$PCRE/pcre.lib: $PCRE/pcre.h $NGX_MAKEFILE" \
|
`echo "$PCRE/pcre.lib: $PCRE/pcre.h $NGX_MAKEFILE" \
|
||||||
| sed -e "s/\//$ngx_regex_dirsep/g"`
|
| sed -e "s/\//$ngx_regex_dirsep/g"`
|
||||||
|
@ -43,9 +145,9 @@ if [ -n "$ngx_makefile" ]; then
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
cat << END >> $NGX_MAKEFILE
|
cat << END >> $NGX_MAKEFILE
|
||||||
|
|
||||||
$PCRE/pcre.h: $PCRE/Makefile
|
$PCRE/pcre.h: $PCRE/Makefile
|
||||||
|
|
||||||
|
@ -61,4 +163,6 @@ $PCRE/.libs/libpcre.a: $PCRE/Makefile
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -150,6 +150,7 @@ PCRE=NONE
|
||||||
PCRE_OPT=
|
PCRE_OPT=
|
||||||
PCRE_CONF_OPT=
|
PCRE_CONF_OPT=
|
||||||
PCRE_JIT=NO
|
PCRE_JIT=NO
|
||||||
|
PCRE2=YES
|
||||||
|
|
||||||
USE_OPENSSL=NO
|
USE_OPENSSL=NO
|
||||||
USE_OPENSSL_QUIC=NO
|
USE_OPENSSL_QUIC=NO
|
||||||
|
@ -368,6 +369,7 @@ use the \"--with-mail_ssl_module\" option instead"
|
||||||
--with-pcre=*) PCRE="$value" ;;
|
--with-pcre=*) PCRE="$value" ;;
|
||||||
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
||||||
--with-pcre-jit) PCRE_JIT=YES ;;
|
--with-pcre-jit) PCRE_JIT=YES ;;
|
||||||
|
--without-pcre2) PCRE2=DISABLED ;;
|
||||||
|
|
||||||
--with-openssl=*) OPENSSL="$value" ;;
|
--with-openssl=*) OPENSSL="$value" ;;
|
||||||
--with-openssl-opt=*) OPENSSL_OPT="$value" ;;
|
--with-openssl-opt=*) OPENSSL_OPT="$value" ;;
|
||||||
|
@ -588,6 +590,7 @@ cat << END
|
||||||
--with-pcre=DIR set path to PCRE library sources
|
--with-pcre=DIR set path to PCRE library sources
|
||||||
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
||||||
--with-pcre-jit build PCRE with JIT compilation support
|
--with-pcre-jit build PCRE with JIT compilation support
|
||||||
|
--without-pcre2 do not use PCRE2 library
|
||||||
|
|
||||||
--with-zlib=DIR set path to zlib library sources
|
--with-zlib=DIR set path to zlib library sources
|
||||||
--with-zlib-opt=OPTIONS set additional build options for zlib
|
--with-zlib-opt=OPTIONS set additional build options for zlib
|
||||||
|
|
|
@ -44,12 +44,10 @@ if [ $osreldate -gt 300007 ]; then
|
||||||
CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
|
CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $NGX_FILE_AIO = YES ]; then
|
if [ $osreldate -gt 1100093 ]; then
|
||||||
if [ $osreldate -gt 502103 ]; then
|
echo " + sendfile()'s SF_NODISKIO found"
|
||||||
echo " + sendfile()'s SF_NODISKIO found"
|
|
||||||
|
|
||||||
have=NGX_HAVE_AIO_SENDFILE . auto/have
|
have=NGX_HAVE_SENDFILE_NODISKIO . auto/have
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# POSIX semaphores
|
# POSIX semaphores
|
||||||
|
|
|
@ -16,9 +16,9 @@ if [ $USE_PCRE = DISABLED ]; then
|
||||||
|
|
||||||
else
|
else
|
||||||
case $PCRE in
|
case $PCRE in
|
||||||
YES) echo " + using system PCRE library" ;;
|
YES) echo " + using system $PCRE_LIBRARY library" ;;
|
||||||
NONE) echo " + PCRE library is not used" ;;
|
NONE) echo " + PCRE library is not used" ;;
|
||||||
*) echo " + using PCRE library: $PCRE" ;;
|
*) echo " + using $PCRE_LIBRARY library: $PCRE" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,58 @@
|
||||||
<change_log title="nginx">
|
<change_log title="nginx">
|
||||||
|
|
||||||
|
|
||||||
|
<changes ver="1.21.5" date="2021-12-28">
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь nginx по умолчанию собирается с библиотекой PCRE2.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now nginx is built with the PCRE2 library by default.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь nginx всегда использует sendfile(SF_NODISKIO) на FreeBSD.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now nginx always uses sendfile(SF_NODISKIO) on FreeBSD.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para lang="ru">
|
||||||
|
поддержка sendfile(SF_NOCACHE) на FreeBSD.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
support for sendfile(SF_NOCACHE) on FreeBSD.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para lang="ru">
|
||||||
|
переменная $ssl_curve.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
the $ssl_curve variable.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
при использовании HTTP/2 без SSL вместе с директивами sendfile и aio
|
||||||
|
соединения могли зависать.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
connections might hang
|
||||||
|
when using HTTP/2 without SSL with the "sendfile" and "aio" directives.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.21.4" date="2021-11-02">
|
<changes ver="1.21.4" date="2021-11-02">
|
||||||
|
|
||||||
<change type="change">
|
<change type="change">
|
||||||
|
|
|
@ -6,9 +6,9 @@ TEMP = tmp
|
||||||
|
|
||||||
CC = cl
|
CC = cl
|
||||||
OBJS = objs.msvc8
|
OBJS = objs.msvc8
|
||||||
OPENSSL = openssl-1.1.1l
|
OPENSSL = openssl-1.1.1m
|
||||||
ZLIB = zlib-1.2.11
|
ZLIB = zlib-1.2.11
|
||||||
PCRE = pcre-8.44
|
PCRE = pcre2-10.39
|
||||||
|
|
||||||
|
|
||||||
release: export
|
release: export
|
||||||
|
|
|
@ -90,9 +90,6 @@ struct ngx_output_chain_ctx_s {
|
||||||
|
|
||||||
#if (NGX_HAVE_FILE_AIO || NGX_COMPAT)
|
#if (NGX_HAVE_FILE_AIO || NGX_COMPAT)
|
||||||
ngx_output_chain_aio_pt aio_handler;
|
ngx_output_chain_aio_pt aio_handler;
|
||||||
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
|
|
||||||
ssize_t (*aio_preload)(ngx_buf_t *file);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (NGX_THREADS || NGX_COMPAT)
|
#if (NGX_THREADS || NGX_COMPAT)
|
||||||
|
|
|
@ -190,7 +190,7 @@ struct ngx_connection_s {
|
||||||
|
|
||||||
unsigned need_last_buf:1;
|
unsigned need_last_buf:1;
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
|
#if (NGX_HAVE_SENDFILE_NODISKIO || NGX_COMPAT)
|
||||||
unsigned busy_count:2;
|
unsigned busy_count:2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#define NGX_MODULE_SIGNATURE_3 "0"
|
#define NGX_MODULE_SIGNATURE_3 "0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
|
#if (NGX_HAVE_SENDFILE_NODISKIO || NGX_COMPAT)
|
||||||
#define NGX_MODULE_SIGNATURE_4 "1"
|
#define NGX_MODULE_SIGNATURE_4 "1"
|
||||||
#else
|
#else
|
||||||
#define NGX_MODULE_SIGNATURE_4 "0"
|
#define NGX_MODULE_SIGNATURE_4 "0"
|
||||||
|
|
|
@ -29,10 +29,6 @@
|
||||||
|
|
||||||
static ngx_inline ngx_int_t
|
static ngx_inline ngx_int_t
|
||||||
ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf);
|
ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf);
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
static ngx_int_t ngx_output_chain_aio_setup(ngx_output_chain_ctx_t *ctx,
|
|
||||||
ngx_file_t *file);
|
|
||||||
#endif
|
|
||||||
static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool,
|
static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool,
|
||||||
ngx_chain_t **chain, ngx_chain_t *in);
|
ngx_chain_t **chain, ngx_chain_t *in);
|
||||||
static ngx_int_t ngx_output_chain_align_file_buf(ngx_output_chain_ctx_t *ctx,
|
static ngx_int_t ngx_output_chain_align_file_buf(ngx_output_chain_ctx_t *ctx,
|
||||||
|
@ -260,10 +256,6 @@ ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (buf->in_file && buf->file->directio) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendfile = ctx->sendfile;
|
sendfile = ctx->sendfile;
|
||||||
|
|
||||||
#if (NGX_SENDFILE_LIMIT)
|
#if (NGX_SENDFILE_LIMIT)
|
||||||
|
@ -272,6 +264,19 @@ ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
|
||||||
sendfile = 0;
|
sendfile = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With DIRECTIO, disable sendfile() unless sendfile(SF_NOCACHE)
|
||||||
|
* is available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (buf->in_file && buf->file->directio) {
|
||||||
|
sendfile = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!sendfile) {
|
if (!sendfile) {
|
||||||
|
@ -283,12 +288,6 @@ ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
|
||||||
buf->in_file = 0;
|
buf->in_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
if (ctx->aio_preload && buf->in_file) {
|
|
||||||
(void) ngx_output_chain_aio_setup(ctx, buf->file);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ctx->need_in_memory && !ngx_buf_in_memory(buf)) {
|
if (ctx->need_in_memory && !ngx_buf_in_memory(buf)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -301,28 +300,6 @@ ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_output_chain_aio_setup(ngx_output_chain_ctx_t *ctx, ngx_file_t *file)
|
|
||||||
{
|
|
||||||
ngx_event_aio_t *aio;
|
|
||||||
|
|
||||||
if (file->aio == NULL && ngx_file_aio_init(file, ctx->pool) != NGX_OK) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
aio = file->aio;
|
|
||||||
|
|
||||||
aio->data = ctx->filter_ctx;
|
|
||||||
aio->preload_handler = ctx->aio_preload;
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
|
ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
|
||||||
ngx_chain_t *in)
|
ngx_chain_t *in)
|
||||||
|
|
|
@ -10,15 +10,22 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_flag_t pcre_jit;
|
ngx_flag_t pcre_jit;
|
||||||
|
ngx_list_t *studies;
|
||||||
} ngx_regex_conf_t;
|
} ngx_regex_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_inline void ngx_regex_malloc_init(ngx_pool_t *pool);
|
||||||
|
static ngx_inline void ngx_regex_malloc_done(void);
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
static void * ngx_libc_cdecl ngx_regex_malloc(size_t size, void *data);
|
||||||
|
static void ngx_libc_cdecl ngx_regex_free(void *p, void *data);
|
||||||
|
#else
|
||||||
static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
|
static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
|
||||||
static void ngx_libc_cdecl ngx_regex_free(void *p);
|
static void ngx_libc_cdecl ngx_regex_free(void *p);
|
||||||
#if (NGX_HAVE_PCRE_JIT)
|
|
||||||
static void ngx_pcre_free_studies(void *data);
|
|
||||||
#endif
|
#endif
|
||||||
|
static void ngx_regex_cleanup(void *data);
|
||||||
|
|
||||||
static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
|
static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
|
||||||
|
|
||||||
|
@ -65,32 +72,197 @@ ngx_module_t ngx_regex_module = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static ngx_pool_t *ngx_pcre_pool;
|
static ngx_pool_t *ngx_regex_pool;
|
||||||
static ngx_list_t *ngx_pcre_studies;
|
static ngx_list_t *ngx_regex_studies;
|
||||||
|
static ngx_uint_t ngx_regex_direct_alloc;
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
static pcre2_compile_context *ngx_regex_compile_context;
|
||||||
|
static pcre2_match_data *ngx_regex_match_data;
|
||||||
|
static ngx_uint_t ngx_regex_match_data_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ngx_regex_init(void)
|
ngx_regex_init(void)
|
||||||
{
|
{
|
||||||
|
#if !(NGX_PCRE2)
|
||||||
pcre_malloc = ngx_regex_malloc;
|
pcre_malloc = ngx_regex_malloc;
|
||||||
pcre_free = ngx_regex_free;
|
pcre_free = ngx_regex_free;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_inline void
|
static ngx_inline void
|
||||||
ngx_regex_malloc_init(ngx_pool_t *pool)
|
ngx_regex_malloc_init(ngx_pool_t *pool)
|
||||||
{
|
{
|
||||||
ngx_pcre_pool = pool;
|
ngx_regex_pool = pool;
|
||||||
|
ngx_regex_direct_alloc = (pool == NULL) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_inline void
|
static ngx_inline void
|
||||||
ngx_regex_malloc_done(void)
|
ngx_regex_malloc_done(void)
|
||||||
{
|
{
|
||||||
ngx_pcre_pool = NULL;
|
ngx_regex_pool = NULL;
|
||||||
|
ngx_regex_direct_alloc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_regex_compile(ngx_regex_compile_t *rc)
|
||||||
|
{
|
||||||
|
int n, errcode;
|
||||||
|
char *p;
|
||||||
|
u_char errstr[128];
|
||||||
|
size_t erroff;
|
||||||
|
uint32_t options;
|
||||||
|
pcre2_code *re;
|
||||||
|
ngx_regex_elt_t *elt;
|
||||||
|
pcre2_general_context *gctx;
|
||||||
|
pcre2_compile_context *cctx;
|
||||||
|
|
||||||
|
if (ngx_regex_compile_context == NULL) {
|
||||||
|
/*
|
||||||
|
* Allocate a compile context if not yet allocated. This uses
|
||||||
|
* direct allocations from heap, so the result can be cached
|
||||||
|
* even at runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ngx_regex_malloc_init(NULL);
|
||||||
|
|
||||||
|
gctx = pcre2_general_context_create(ngx_regex_malloc, ngx_regex_free,
|
||||||
|
NULL);
|
||||||
|
if (gctx == NULL) {
|
||||||
|
ngx_regex_malloc_done();
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
cctx = pcre2_compile_context_create(gctx);
|
||||||
|
if (cctx == NULL) {
|
||||||
|
pcre2_general_context_free(gctx);
|
||||||
|
ngx_regex_malloc_done();
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_regex_compile_context = cctx;
|
||||||
|
|
||||||
|
pcre2_general_context_free(gctx);
|
||||||
|
ngx_regex_malloc_done();
|
||||||
|
}
|
||||||
|
|
||||||
|
options = 0;
|
||||||
|
|
||||||
|
if (rc->options & NGX_REGEX_CASELESS) {
|
||||||
|
options |= PCRE2_CASELESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc->options & NGX_REGEX_MULTILINE) {
|
||||||
|
options |= PCRE2_MULTILINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc->options & ~(NGX_REGEX_CASELESS|NGX_REGEX_MULTILINE)) {
|
||||||
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
|
"regex \"%V\" compilation failed: invalid options",
|
||||||
|
&rc->pattern)
|
||||||
|
- rc->err.data;
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_regex_malloc_init(rc->pool);
|
||||||
|
|
||||||
|
re = pcre2_compile(rc->pattern.data, rc->pattern.len, options,
|
||||||
|
&errcode, &erroff, ngx_regex_compile_context);
|
||||||
|
|
||||||
|
/* ensure that there is no current pool */
|
||||||
|
ngx_regex_malloc_done();
|
||||||
|
|
||||||
|
if (re == NULL) {
|
||||||
|
pcre2_get_error_message(errcode, errstr, 128);
|
||||||
|
|
||||||
|
if ((size_t) erroff == rc->pattern.len) {
|
||||||
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
|
"pcre2_compile() failed: %s in \"%V\"",
|
||||||
|
errstr, &rc->pattern)
|
||||||
|
- rc->err.data;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
|
"pcre2_compile() failed: %s in \"%V\" at \"%s\"",
|
||||||
|
errstr, &rc->pattern, rc->pattern.data + erroff)
|
||||||
|
- rc->err.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->regex = re;
|
||||||
|
|
||||||
|
/* do not study at runtime */
|
||||||
|
|
||||||
|
if (ngx_regex_studies != NULL) {
|
||||||
|
elt = ngx_list_push(ngx_regex_studies);
|
||||||
|
if (elt == NULL) {
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
elt->regex = rc->regex;
|
||||||
|
elt->name = rc->pattern.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &rc->captures);
|
||||||
|
if (n < 0) {
|
||||||
|
p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_CAPTURECOUNT) failed: %d";
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc->captures == 0) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &rc->named_captures);
|
||||||
|
if (n < 0) {
|
||||||
|
p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_NAMECOUNT) failed: %d";
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc->named_captures == 0) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = pcre2_pattern_info(re, PCRE2_INFO_NAMEENTRYSIZE, &rc->name_size);
|
||||||
|
if (n < 0) {
|
||||||
|
p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_NAMEENTRYSIZE) failed: %d";
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = pcre2_pattern_info(re, PCRE2_INFO_NAMETABLE, &rc->names);
|
||||||
|
if (n < 0) {
|
||||||
|
p = "pcre2_pattern_info(\"%V\", PCRE2_INFO_NAMETABLE) failed: %d";
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
|
||||||
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
|
||||||
|
- rc->err.data;
|
||||||
|
return NGX_ERROR;
|
||||||
|
|
||||||
|
nomem:
|
||||||
|
|
||||||
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
|
"regex \"%V\" compilation failed: no memory",
|
||||||
|
&rc->pattern)
|
||||||
|
- rc->err.data;
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_regex_compile(ngx_regex_compile_t *rc)
|
ngx_regex_compile(ngx_regex_compile_t *rc)
|
||||||
{
|
{
|
||||||
|
@ -98,11 +270,30 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
|
||||||
char *p;
|
char *p;
|
||||||
pcre *re;
|
pcre *re;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
ngx_uint_t options;
|
||||||
ngx_regex_elt_t *elt;
|
ngx_regex_elt_t *elt;
|
||||||
|
|
||||||
|
options = 0;
|
||||||
|
|
||||||
|
if (rc->options & NGX_REGEX_CASELESS) {
|
||||||
|
options |= PCRE_CASELESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc->options & NGX_REGEX_MULTILINE) {
|
||||||
|
options |= PCRE_MULTILINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc->options & ~(NGX_REGEX_CASELESS|NGX_REGEX_MULTILINE)) {
|
||||||
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
|
"regex \"%V\" compilation failed: invalid options",
|
||||||
|
&rc->pattern)
|
||||||
|
- rc->err.data;
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ngx_regex_malloc_init(rc->pool);
|
ngx_regex_malloc_init(rc->pool);
|
||||||
|
|
||||||
re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
|
re = pcre_compile((const char *) rc->pattern.data, (int) options,
|
||||||
&errstr, &erroff, NULL);
|
&errstr, &erroff, NULL);
|
||||||
|
|
||||||
/* ensure that there is no current pool */
|
/* ensure that there is no current pool */
|
||||||
|
@ -113,13 +304,13 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
|
||||||
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
"pcre_compile() failed: %s in \"%V\"",
|
"pcre_compile() failed: %s in \"%V\"",
|
||||||
errstr, &rc->pattern)
|
errstr, &rc->pattern)
|
||||||
- rc->err.data;
|
- rc->err.data;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
|
||||||
"pcre_compile() failed: %s in \"%V\" at \"%s\"",
|
"pcre_compile() failed: %s in \"%V\" at \"%s\"",
|
||||||
errstr, &rc->pattern, rc->pattern.data + erroff)
|
errstr, &rc->pattern, rc->pattern.data + erroff)
|
||||||
- rc->err.data;
|
- rc->err.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
|
@ -134,8 +325,8 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
|
||||||
|
|
||||||
/* do not study at runtime */
|
/* do not study at runtime */
|
||||||
|
|
||||||
if (ngx_pcre_studies != NULL) {
|
if (ngx_regex_studies != NULL) {
|
||||||
elt = ngx_list_push(ngx_pcre_studies);
|
elt = ngx_list_push(ngx_regex_studies);
|
||||||
if (elt == NULL) {
|
if (elt == NULL) {
|
||||||
goto nomem;
|
goto nomem;
|
||||||
}
|
}
|
||||||
|
@ -193,6 +384,83 @@ nomem:
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_uint_t size)
|
||||||
|
{
|
||||||
|
size_t *ov;
|
||||||
|
ngx_int_t rc;
|
||||||
|
ngx_uint_t n, i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The pcre2_match() function might allocate memory for backtracking
|
||||||
|
* frames, typical allocations are from 40k and above. So the allocator
|
||||||
|
* is configured to do direct allocations from heap during matching.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ngx_regex_malloc_init(NULL);
|
||||||
|
|
||||||
|
if (ngx_regex_match_data == NULL
|
||||||
|
|| size > ngx_regex_match_data_size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Allocate a match data if not yet allocated or smaller than
|
||||||
|
* needed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ngx_regex_match_data) {
|
||||||
|
pcre2_match_data_free(ngx_regex_match_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_regex_match_data_size = size;
|
||||||
|
ngx_regex_match_data = pcre2_match_data_create(size / 3, NULL);
|
||||||
|
|
||||||
|
if (ngx_regex_match_data == NULL) {
|
||||||
|
rc = PCRE2_ERROR_NOMEMORY;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = pcre2_match(re, s->data, s->len, 0, 0, ngx_regex_match_data, NULL);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = pcre2_get_ovector_count(ngx_regex_match_data);
|
||||||
|
ov = pcre2_get_ovector_pointer(ngx_regex_match_data);
|
||||||
|
|
||||||
|
if (n > size / 3) {
|
||||||
|
n = size / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
captures[i * 2] = ov[i * 2];
|
||||||
|
captures[i * 2 + 1] = ov[i * 2 + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
failed:
|
||||||
|
|
||||||
|
ngx_regex_malloc_done();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_uint_t size)
|
||||||
|
{
|
||||||
|
return pcre_exec(re->code, re->extra, (const char *) s->data, s->len,
|
||||||
|
0, 0, captures, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
|
ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
|
||||||
|
@ -227,14 +495,40 @@ ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
|
||||||
|
static void * ngx_libc_cdecl
|
||||||
|
ngx_regex_malloc(size_t size, void *data)
|
||||||
|
{
|
||||||
|
if (ngx_regex_pool) {
|
||||||
|
return ngx_palloc(ngx_regex_pool, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_regex_direct_alloc) {
|
||||||
|
return ngx_alloc(size, ngx_cycle->log);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ngx_libc_cdecl
|
||||||
|
ngx_regex_free(void *p, void *data)
|
||||||
|
{
|
||||||
|
if (ngx_regex_direct_alloc) {
|
||||||
|
ngx_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
static void * ngx_libc_cdecl
|
static void * ngx_libc_cdecl
|
||||||
ngx_regex_malloc(size_t size)
|
ngx_regex_malloc(size_t size)
|
||||||
{
|
{
|
||||||
ngx_pool_t *pool;
|
if (ngx_regex_pool) {
|
||||||
pool = ngx_pcre_pool;
|
return ngx_palloc(ngx_regex_pool, size);
|
||||||
|
|
||||||
if (pool) {
|
|
||||||
return ngx_palloc(pool, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -247,19 +541,20 @@ ngx_regex_free(void *p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (NGX_HAVE_PCRE_JIT)
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_pcre_free_studies(void *data)
|
ngx_regex_cleanup(void *data)
|
||||||
{
|
{
|
||||||
ngx_list_t *studies = data;
|
#if (NGX_PCRE2 || NGX_HAVE_PCRE_JIT)
|
||||||
|
ngx_regex_conf_t *rcf = data;
|
||||||
|
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_list_part_t *part;
|
ngx_list_part_t *part;
|
||||||
ngx_regex_elt_t *elts;
|
ngx_regex_elt_t *elts;
|
||||||
|
|
||||||
part = &studies->part;
|
part = &rcf->studies->part;
|
||||||
elts = part->elts;
|
elts = part->elts;
|
||||||
|
|
||||||
for (i = 0; /* void */ ; i++) {
|
for (i = 0; /* void */ ; i++) {
|
||||||
|
@ -274,56 +569,83 @@ ngx_pcre_free_studies(void *data)
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The PCRE JIT compiler uses mmap for its executable codes, so we
|
||||||
|
* have to explicitly call the pcre_free_study() function to free
|
||||||
|
* this memory. In PCRE2, we call the pcre2_code_free() function
|
||||||
|
* for the same reason.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
pcre2_code_free(elts[i].regex);
|
||||||
|
#else
|
||||||
if (elts[i].regex->extra != NULL) {
|
if (elts[i].regex->extra != NULL) {
|
||||||
pcre_free_study(elts[i].regex->extra);
|
pcre_free_study(elts[i].regex->extra);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On configuration parsing errors ngx_regex_module_init() will not
|
||||||
|
* be called. Make sure ngx_regex_studies is properly cleared anyway.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ngx_regex_studies = NULL;
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free compile context and match data. If needed at runtime by
|
||||||
|
* the new cycle, these will be re-allocated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ngx_regex_compile_context) {
|
||||||
|
pcre2_compile_context_free(ngx_regex_compile_context);
|
||||||
|
ngx_regex_compile_context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_regex_match_data) {
|
||||||
|
pcre2_match_data_free(ngx_regex_match_data);
|
||||||
|
ngx_regex_match_data = NULL;
|
||||||
|
ngx_regex_match_data_size = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_regex_module_init(ngx_cycle_t *cycle)
|
ngx_regex_module_init(ngx_cycle_t *cycle)
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
const char *errstr;
|
#if !(NGX_PCRE2)
|
||||||
ngx_uint_t i;
|
const char *errstr;
|
||||||
ngx_list_part_t *part;
|
#endif
|
||||||
ngx_regex_elt_t *elts;
|
ngx_uint_t i;
|
||||||
|
ngx_list_part_t *part;
|
||||||
|
ngx_regex_elt_t *elts;
|
||||||
|
ngx_regex_conf_t *rcf;
|
||||||
|
|
||||||
opt = 0;
|
opt = 0;
|
||||||
|
|
||||||
#if (NGX_HAVE_PCRE_JIT)
|
|
||||||
{
|
|
||||||
ngx_regex_conf_t *rcf;
|
|
||||||
ngx_pool_cleanup_t *cln;
|
|
||||||
|
|
||||||
rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
|
rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
|
||||||
|
|
||||||
|
#if (NGX_PCRE2 || NGX_HAVE_PCRE_JIT)
|
||||||
|
|
||||||
if (rcf->pcre_jit) {
|
if (rcf->pcre_jit) {
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
opt = 1;
|
||||||
|
#else
|
||||||
opt = PCRE_STUDY_JIT_COMPILE;
|
opt = PCRE_STUDY_JIT_COMPILE;
|
||||||
|
#endif
|
||||||
/*
|
|
||||||
* The PCRE JIT compiler uses mmap for its executable codes, so we
|
|
||||||
* have to explicitly call the pcre_free_study() function to free
|
|
||||||
* this memory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
cln = ngx_pool_cleanup_add(cycle->pool, 0);
|
|
||||||
if (cln == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
cln->handler = ngx_pcre_free_studies;
|
|
||||||
cln->data = ngx_pcre_studies;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ngx_regex_malloc_init(cycle->pool);
|
ngx_regex_malloc_init(cycle->pool);
|
||||||
|
|
||||||
part = &ngx_pcre_studies->part;
|
part = &rcf->studies->part;
|
||||||
elts = part->elts;
|
elts = part->elts;
|
||||||
|
|
||||||
for (i = 0; /* void */ ; i++) {
|
for (i = 0; /* void */ ; i++) {
|
||||||
|
@ -338,6 +660,23 @@ ngx_regex_module_init(ngx_cycle_t *cycle)
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
|
||||||
|
if (opt) {
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = pcre2_jit_compile(elts[i].regex, PCRE2_JIT_COMPLETE);
|
||||||
|
|
||||||
|
if (n != 0) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
|
||||||
|
"pcre2_jit_compile() failed: %d in \"%s\", "
|
||||||
|
"ignored",
|
||||||
|
n, elts[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
|
elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
|
||||||
|
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
|
@ -360,12 +699,16 @@ ngx_regex_module_init(ngx_cycle_t *cycle)
|
||||||
elts[i].name);
|
elts[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_regex_malloc_done();
|
ngx_regex_malloc_done();
|
||||||
|
|
||||||
ngx_pcre_studies = NULL;
|
ngx_regex_studies = NULL;
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
ngx_regex_compile_context = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
@ -374,7 +717,8 @@ ngx_regex_module_init(ngx_cycle_t *cycle)
|
||||||
static void *
|
static void *
|
||||||
ngx_regex_create_conf(ngx_cycle_t *cycle)
|
ngx_regex_create_conf(ngx_cycle_t *cycle)
|
||||||
{
|
{
|
||||||
ngx_regex_conf_t *rcf;
|
ngx_regex_conf_t *rcf;
|
||||||
|
ngx_pool_cleanup_t *cln;
|
||||||
|
|
||||||
rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
|
rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
|
||||||
if (rcf == NULL) {
|
if (rcf == NULL) {
|
||||||
|
@ -383,11 +727,21 @@ ngx_regex_create_conf(ngx_cycle_t *cycle)
|
||||||
|
|
||||||
rcf->pcre_jit = NGX_CONF_UNSET;
|
rcf->pcre_jit = NGX_CONF_UNSET;
|
||||||
|
|
||||||
ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
|
cln = ngx_pool_cleanup_add(cycle->pool, 0);
|
||||||
if (ngx_pcre_studies == NULL) {
|
if (cln == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cln->handler = ngx_regex_cleanup;
|
||||||
|
cln->data = rcf;
|
||||||
|
|
||||||
|
rcf->studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
|
||||||
|
if (rcf->studies == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_regex_studies = rcf->studies;
|
||||||
|
|
||||||
return rcf;
|
return rcf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +766,21 @@ ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data)
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (NGX_HAVE_PCRE_JIT)
|
#if (NGX_PCRE2)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
uint32_t jit;
|
||||||
|
|
||||||
|
jit = 0;
|
||||||
|
r = pcre2_config(PCRE2_CONFIG_JIT, &jit);
|
||||||
|
|
||||||
|
if (r != 0 || jit != 1) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"PCRE2 library does not support JIT");
|
||||||
|
*fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif (NGX_HAVE_PCRE_JIT)
|
||||||
{
|
{
|
||||||
int jit, r;
|
int jit, r;
|
||||||
|
|
||||||
|
|
|
@ -12,24 +12,38 @@
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_PCRE2)
|
||||||
|
|
||||||
|
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||||
|
#include <pcre2.h>
|
||||||
|
|
||||||
|
#define NGX_REGEX_NO_MATCHED PCRE2_ERROR_NOMATCH /* -1 */
|
||||||
|
|
||||||
|
typedef pcre2_code ngx_regex_t;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#include <pcre.h>
|
#include <pcre.h>
|
||||||
|
|
||||||
|
#define NGX_REGEX_NO_MATCHED PCRE_ERROR_NOMATCH /* -1 */
|
||||||
#define NGX_REGEX_NO_MATCHED PCRE_ERROR_NOMATCH /* -1 */
|
|
||||||
|
|
||||||
#define NGX_REGEX_CASELESS PCRE_CASELESS
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
pcre *code;
|
pcre *code;
|
||||||
pcre_extra *extra;
|
pcre_extra *extra;
|
||||||
} ngx_regex_t;
|
} ngx_regex_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define NGX_REGEX_CASELESS 0x00000001
|
||||||
|
#define NGX_REGEX_MULTILINE 0x00000002
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_str_t pattern;
|
ngx_str_t pattern;
|
||||||
ngx_pool_t *pool;
|
ngx_pool_t *pool;
|
||||||
ngx_int_t options;
|
ngx_uint_t options;
|
||||||
|
|
||||||
ngx_regex_t *regex;
|
ngx_regex_t *regex;
|
||||||
int captures;
|
int captures;
|
||||||
|
@ -49,10 +63,14 @@ typedef struct {
|
||||||
void ngx_regex_init(void);
|
void ngx_regex_init(void);
|
||||||
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
|
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
|
||||||
|
|
||||||
#define ngx_regex_exec(re, s, captures, size) \
|
ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures,
|
||||||
pcre_exec(re->code, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
|
ngx_uint_t size);
|
||||||
captures, size)
|
|
||||||
#define ngx_regex_exec_n "pcre_exec()"
|
#if (NGX_PCRE2)
|
||||||
|
#define ngx_regex_exec_n "pcre2_match()"
|
||||||
|
#else
|
||||||
|
#define ngx_regex_exec_n "pcre_exec()"
|
||||||
|
#endif
|
||||||
|
|
||||||
ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
|
ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
|
||||||
|
|
||||||
|
|
|
@ -147,10 +147,6 @@ struct ngx_event_aio_s {
|
||||||
|
|
||||||
ngx_fd_t fd;
|
ngx_fd_t fd;
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
|
|
||||||
ssize_t (*preload_handler)(ngx_buf_t *file);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (NGX_HAVE_EVENTFD)
|
#if (NGX_HAVE_EVENTFD)
|
||||||
int64_t res;
|
int64_t res;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2942,7 +2942,7 @@ ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||||
{
|
{
|
||||||
#ifdef BIO_get_ktls_send
|
#ifdef BIO_get_ktls_send
|
||||||
|
|
||||||
int sslerr;
|
int sslerr, flags;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
|
|
||||||
|
@ -2954,8 +2954,20 @@ ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||||
|
|
||||||
ngx_set_errno(0);
|
ngx_set_errno(0);
|
||||||
|
|
||||||
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
|
|
||||||
|
flags = (c->busy_count <= 2) ? SF_NODISKIO : 0;
|
||||||
|
|
||||||
|
if (file->file->directio) {
|
||||||
|
flags |= SF_NOCACHE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
flags = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
n = SSL_sendfile(c->ssl->connection, file->file->fd, file->file_pos,
|
n = SSL_sendfile(c->ssl->connection, file->file->fd, file->file_pos,
|
||||||
size, 0);
|
size, flags);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_sendfile: %d", n);
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_sendfile: %d", n);
|
||||||
|
|
||||||
|
@ -2974,6 +2986,10 @@ ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||||
ngx_post_event(c->read, &ngx_posted_events);
|
ngx_post_event(c->read, &ngx_posted_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
|
c->busy_count = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
c->sent += n;
|
c->sent += n;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -3038,6 +3054,23 @@ ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||||
ngx_post_event(c->read, &ngx_posted_events);
|
ngx_post_event(c->read, &ngx_posted_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
|
|
||||||
|
if (ngx_errno == EBUSY) {
|
||||||
|
c->busy_count++;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
|
"SSL_sendfile() busy, count:%d", c->busy_count);
|
||||||
|
|
||||||
|
if (c->write->posted) {
|
||||||
|
ngx_delete_posted_event(c->write);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_post_event(c->write, &ngx_posted_next_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
c->write->ready = 0;
|
c->write->ready = 0;
|
||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,6 @@ typedef struct {
|
||||||
static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx,
|
static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx,
|
||||||
ngx_file_t *file);
|
ngx_file_t *file);
|
||||||
static void ngx_http_copy_aio_event_handler(ngx_event_t *ev);
|
static void ngx_http_copy_aio_event_handler(ngx_event_t *ev);
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
static ssize_t ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file);
|
|
||||||
static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_THREADS)
|
#if (NGX_THREADS)
|
||||||
static ngx_int_t ngx_http_copy_thread_handler(ngx_thread_task_t *task,
|
static ngx_int_t ngx_http_copy_thread_handler(ngx_thread_task_t *task,
|
||||||
|
@ -128,9 +124,6 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||||
#if (NGX_HAVE_FILE_AIO)
|
#if (NGX_HAVE_FILE_AIO)
|
||||||
if (ngx_file_aio && clcf->aio == NGX_HTTP_AIO_ON) {
|
if (ngx_file_aio && clcf->aio == NGX_HTTP_AIO_ON) {
|
||||||
ctx->aio_handler = ngx_http_copy_aio_handler;
|
ctx->aio_handler = ngx_http_copy_aio_handler;
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
ctx->aio_preload = ngx_http_copy_aio_sendfile_preload;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -207,81 +200,6 @@ ngx_http_copy_aio_event_handler(ngx_event_t *ev)
|
||||||
ngx_http_run_posted_requests(c);
|
ngx_http_run_posted_requests(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file)
|
|
||||||
{
|
|
||||||
ssize_t n;
|
|
||||||
static u_char buf[1];
|
|
||||||
ngx_event_aio_t *aio;
|
|
||||||
ngx_http_request_t *r;
|
|
||||||
ngx_output_chain_ctx_t *ctx;
|
|
||||||
|
|
||||||
aio = file->file->aio;
|
|
||||||
r = aio->data;
|
|
||||||
|
|
||||||
if (r->aio) {
|
|
||||||
/*
|
|
||||||
* tolerate sendfile() calls if another operation is already
|
|
||||||
* running; this can happen due to subrequests, multiple calls
|
|
||||||
* of the next body filter from a filter, or in HTTP/2 due to
|
|
||||||
* a write event on the main connection
|
|
||||||
*/
|
|
||||||
|
|
||||||
return NGX_AGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL);
|
|
||||||
|
|
||||||
if (n == NGX_AGAIN) {
|
|
||||||
aio->handler = ngx_http_copy_aio_sendfile_event_handler;
|
|
||||||
|
|
||||||
r->main->blocked++;
|
|
||||||
r->aio = 1;
|
|
||||||
|
|
||||||
ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
|
|
||||||
ctx->aio = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev)
|
|
||||||
{
|
|
||||||
ngx_event_aio_t *aio;
|
|
||||||
ngx_connection_t *c;
|
|
||||||
ngx_http_request_t *r;
|
|
||||||
|
|
||||||
aio = ev->data;
|
|
||||||
r = aio->data;
|
|
||||||
c = r->connection;
|
|
||||||
|
|
||||||
r->main->blocked--;
|
|
||||||
r->aio = 0;
|
|
||||||
ev->complete = 0;
|
|
||||||
|
|
||||||
#if (NGX_HTTP_V2)
|
|
||||||
|
|
||||||
if (r->stream) {
|
|
||||||
/*
|
|
||||||
* for HTTP/2, update write event to make sure processing will
|
|
||||||
* reach the main connection to handle sendfile() preload
|
|
||||||
*/
|
|
||||||
|
|
||||||
c->write->ready = 1;
|
|
||||||
c->write->active = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
c->write->handler(c->write);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4588,19 +4588,6 @@ ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
|
|
||||||
if (ngx_strcmp(value[1].data, "sendfile") == 0) {
|
|
||||||
clcf->aio = NGX_HTTP_AIO_ON;
|
|
||||||
|
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
|
||||||
"the \"sendfile\" parameter of "
|
|
||||||
"the \"aio\" directive is deprecated");
|
|
||||||
return NGX_CONF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ngx_strncmp(value[1].data, "threads", 7) == 0
|
if (ngx_strncmp(value[1].data, "threads", 7) == 0
|
||||||
&& (value[1].len == 7 || value[1].data[7] == '='))
|
&& (value[1].len == 7 || value[1].data[7] == '='))
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,23 +32,22 @@
|
||||||
ngx_chain_t *
|
ngx_chain_t *
|
||||||
ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||||
{
|
{
|
||||||
int rc, flags;
|
int rc, flags;
|
||||||
off_t send, prev_send, sent;
|
off_t send, prev_send, sent;
|
||||||
size_t file_size;
|
size_t file_size;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_uint_t eintr, eagain;
|
ngx_err_t err;
|
||||||
ngx_err_t err;
|
ngx_buf_t *file;
|
||||||
ngx_buf_t *file;
|
ngx_uint_t eintr, eagain;
|
||||||
ngx_event_t *wev;
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
ngx_chain_t *cl;
|
ngx_uint_t ebusy;
|
||||||
ngx_iovec_t header, trailer;
|
|
||||||
struct sf_hdtr hdtr;
|
|
||||||
struct iovec headers[NGX_IOVS_PREALLOCATE];
|
|
||||||
struct iovec trailers[NGX_IOVS_PREALLOCATE];
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
|
||||||
ngx_uint_t ebusy;
|
|
||||||
ngx_event_aio_t *aio;
|
|
||||||
#endif
|
#endif
|
||||||
|
ngx_event_t *wev;
|
||||||
|
ngx_chain_t *cl;
|
||||||
|
ngx_iovec_t header, trailer;
|
||||||
|
struct sf_hdtr hdtr;
|
||||||
|
struct iovec headers[NGX_IOVS_PREALLOCATE];
|
||||||
|
struct iovec trailers[NGX_IOVS_PREALLOCATE];
|
||||||
|
|
||||||
wev = c->write;
|
wev = c->write;
|
||||||
|
|
||||||
|
@ -77,11 +76,6 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||||
eagain = 0;
|
eagain = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE && NGX_SUPPRESS_WARN)
|
|
||||||
aio = NULL;
|
|
||||||
file = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
header.iovs = headers;
|
header.iovs = headers;
|
||||||
header.nalloc = NGX_IOVS_PREALLOCATE;
|
header.nalloc = NGX_IOVS_PREALLOCATE;
|
||||||
|
|
||||||
|
@ -90,7 +84,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
eintr = 0;
|
eintr = 0;
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
ebusy = 0;
|
ebusy = 0;
|
||||||
#endif
|
#endif
|
||||||
prev_send = send;
|
prev_send = send;
|
||||||
|
@ -179,9 +173,14 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||||
|
|
||||||
sent = 0;
|
sent = 0;
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
aio = file->file->aio;
|
|
||||||
flags = (aio && aio->preload_handler) ? SF_NODISKIO : 0;
|
flags = (c->busy_count <= 2) ? SF_NODISKIO : 0;
|
||||||
|
|
||||||
|
if (file->file->directio) {
|
||||||
|
flags |= SF_NOCACHE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rc = sendfile(file->file->fd, c->fd, file->file_pos,
|
rc = sendfile(file->file->fd, c->fd, file->file_pos,
|
||||||
|
@ -199,7 +198,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||||
eintr = 1;
|
eintr = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
case NGX_EBUSY:
|
case NGX_EBUSY:
|
||||||
ebusy = 1;
|
ebusy = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -252,41 +251,30 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||||
|
|
||||||
in = ngx_chain_update_sent(in, sent);
|
in = ngx_chain_update_sent(in, sent);
|
||||||
|
|
||||||
#if (NGX_HAVE_AIO_SENDFILE)
|
#if (NGX_HAVE_SENDFILE_NODISKIO)
|
||||||
|
|
||||||
if (ebusy) {
|
if (ebusy) {
|
||||||
if (sent == 0) {
|
if (sent == 0) {
|
||||||
c->busy_count++;
|
c->busy_count++;
|
||||||
|
|
||||||
if (c->busy_count > 2) {
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
"sendfile() busy, count:%d", c->busy_count);
|
||||||
"sendfile(%V) returned busy again",
|
|
||||||
&file->file->name);
|
|
||||||
|
|
||||||
c->busy_count = 0;
|
|
||||||
aio->preload_handler = NULL;
|
|
||||||
|
|
||||||
send = prev_send;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
c->busy_count = 0;
|
c->busy_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = aio->preload_handler(file);
|
if (wev->posted) {
|
||||||
|
ngx_delete_posted_event(wev);
|
||||||
if (n > 0) {
|
|
||||||
send = prev_send + sent;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_post_event(wev, &ngx_posted_next_events);
|
||||||
|
|
||||||
|
wev->ready = 0;
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags == SF_NODISKIO) {
|
c->busy_count = 0;
|
||||||
c->busy_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue