# HG changeset patch # User Igor Sysoev # Date 1069793096 0 # Node ID 8dee38ea911753b548dee7f410fede00b98f3f78 # Parent 2357fa41738a0d2b5263c034db6859118465721c nginx-0.0.1-2003-11-25-23:44:56 import diff --git a/auto/cc b/auto/cc new file mode 100644 --- /dev/null +++ b/auto/cc @@ -0,0 +1,109 @@ + +case $CC in + + *gcc) + + # optimization + #CFLAGS="$CFLAGS -O2 -fomit-frame-pointer" + + # warnings + CFLAGS="$CFLAGS -O -W" + CFLAGS="$CFLAGS -Wall -Wpointer-arith" + #CFLAGS="$CFLAGS -Wconversion" + #CFLAGS="$CFLAGS -Winline" + + # we have a lot of the unused function arguments + CFLAGS="$CFLAGS -Wno-unused" + + # stop on warning + CFLAGS="$CFLAGS -Werror" + + # ANSI C warnings + #CFLAGS="$CFLAGS -pedantic" + + # debug + CFLAGS="$CFLAGS -g" + + OBJEXT=o + OBJOUT="-o " + BINOUT="-o " + + CC_STRONG="$CC -Wall -Werror" + ;; + + + *icc) + # Intel C++ compiler 7.1 + + # optimization + CFLAGS="$CFLAGS -O" + # optimize for Pentium Pro, Pentium II and Pentium III + #CFLAGS="$CFLAGS -mcpu=pentiumpro" + # optimize for Pentium 4, default + #CFLAGS="$CFLAGS -mcpu=pentium4" + + # warnings + CFLAGS="$CFLAGS -w1" + + # stop on warning + CFLAGS="$CFLAGS -Werror" + + OBJEXT=o + OBJOUT="-o " + BINOUT="-o " + + CC_STRONG="$CC -w1 -Werror" + ;; + + + cl) + # MSVC 6.0 SP2 + + # optimization + + # maximize speed + CFLAGS="$CFLAGS -O2" + # enable global optimization + CFLAGS="$CFLAGS -Og" + # enable intrinsic functions + CFLAGS="$CFLAGS -Oi" + # inline expansion + CFLAGS="$CFLAGS -Ob1" + # enable frame pointer omission + CFLAGS="$CFLAGS -Oy" + # disable stack checking calls + CFLAGS="$CFLAGS -Gs" + # optimize for Pentium Pro + CFLAGS="$CFLAGS -G6" + + # warnings + CFLAGS="$CFLAGS -W3" + #CFLAGS="$CFLAGS -W4" + + # stop on warning + CFLAGS="$CFLAGS -WX" + + # multithreaded + CFLAGS="$CFLAGS -MT" + + # disable logo + CFLAGS="$CFLAGS -nologo" + + # link flags + CORE_LINK="$CORE_LINK -link" + CORE_LINK="$CORE_LINK -nodefaultlib:msvcrt" + CORE_LINK="$CORE_LINK -nodefaultlib:libcpmt" + CORE_LINK="$CORE_LINK -verbose:lib" + + # debug + CFLAGS="$CFLAGS -Yd" + CORE_LINK="$CORE_LINK -debug -debugtype:coff" + + OBJEXT=obj + OBJOUT="-Fo" + BINOUT="-Fe" + + CC_STRONG="$CC -W3 -WX" + ;; + +esac diff --git a/auto/configure b/auto/configure --- a/auto/configure +++ b/auto/configure @@ -1,53 +1,17 @@ -CC=cc -CC_STRONG="$CC -Wall -Werror" -CPP="$CC -E" +. auto/options +. auto/init +. auto/sources -NGX_AUTO_CONFIG_H=ngx_auto_config.h +. auto/os/conf + +. auto/cc +. auto/lib/lib +. auto/make +. auto/lib/make echo > $NGX_AUTO_CONFIG_H - -CC_WARN=$CC_STRONG - -NGX_FMT_NAME=OFF_FMT -NGX_TYPE="off_t"; . auto/types/sizeof -NGX_FORMATS="%ld %lld %qd"; . auto/fmt/fmt - -NGX_FMT_NAME=TIME_FMT -NGX_TYPE="time_t"; . auto/types/sizeof -NGX_FORMATS="%d %ld %lld %qd"; . auto/fmt/fmt - - -CC_WARN=$CC - -exit - - -NGX_TYPE="long"; . auto/types/sizeof; NGX_MAX_LONG=$NGX_MAX_SIZE -NGX_FORMATS="l"; . auto/fmt/fmt - - -NGX_TYPE="long long"; . auto/types/sizeof; NGX_MAX_LONG_LONG=$NGX_MAX_SIZE -NGX_FORMATS="ll q"; . auto/fmt/fmt - - -CC_WARN=$CC_STRONG - -NGX_TYPE="off_t"; . auto/types/sizeof -NGX_FORMATS="l ll q"; . auto/fmt/fmt - - -CC_WARN=$CC - -#NGX_TYPE="__int64_t"; . auto/types/typedef; NGX_TIME_T_FMT=$NGX_FMT - -#NGX_TYPE="time_t"; . auto/types/typedef; NGX_TIME_T_FMT=$NGX_FMT - - -#exit - -. auto/types/uint64_t -. auto/types/uintptr_t - -. auto/types/socklen_t +if [ "$PLATFORM" != win32 ]; then + . auto/unix +fi diff --git a/auto/fmt/fmt b/auto/fmt/fmt --- a/auto/fmt/fmt +++ b/auto/fmt/fmt @@ -1,22 +1,27 @@ -echo "Checking for $NGX_TYPE printf() format" +echo "checking for $NGX_TYPE printf() format" NGX_FMT=NO for FMT in $NGX_FORMATS do - echo "#include " > autotest.c echo "#include " >> autotest.c echo "#include " >> autotest.c echo "int main() {" >> autotest.c echo "printf(\"${FMT}\", ($NGX_TYPE) $NGX_MAX_SIZE);" >> autotest.c echo "return 0; }" >> autotest.c - eval "${CC_WARN} -o autotest autotest.c > /dev/null 2>&1" + eval "$CC_WARN $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1" + + MAX_SIZE=`echo $NGX_MAX_SIZE | sed -e "s/L*\$//"` if [ -x ./autotest ]; then - if [ "`./autotest`" = $NGX_MAX_SIZE ]; then - echo " + \"${FMT}\" used" + if [ "`./autotest`" = $MAX_SIZE ]; then + if [ $NGX_FMT_COLLECT = YES ]; then + echo " + \"${FMT}\" is appropriate" + else + echo " + \"${FMT}\" used" + fi NGX_FMT=$FMT fi fi @@ -24,7 +29,12 @@ do rm autotest* if [ $NGX_FMT != NO ]; then - break + if [ $NGX_FMT_COLLECT = YES ]; then + eval "NGX_${NGX_BYTES}_FMT=\"\${NGX_${NGX_BYTES}_FMT} \$NGX_FMT\"" + continue + else + break + fi fi echo " + \"${FMT}\" is not appropriate" @@ -32,12 +42,14 @@ done if [ $NGX_FMT = NO ]; then - echo "printf() $NGX_TYPE format not found" + echo "$0: error: printf() $NGX_TYPE format not found" exit 1 fi -echo "#ifndef $NGX_FMT_NAME" >> $NGX_AUTO_CONFIG_H -echo "#define $NGX_FMT_NAME \"$NGX_FMT\"" >> $NGX_AUTO_CONFIG_H -echo "#endif" >> $NGX_AUTO_CONFIG_H -echo >> $NGX_AUTO_CONFIG_H +if [ $NGX_FMT_COLLECT = NO ]; then + echo "#ifndef $NGX_FMT_NAME" >> $NGX_AUTO_CONFIG_H + echo "#define $NGX_FMT_NAME \"$NGX_FMT\"" >> $NGX_AUTO_CONFIG_H + echo "#endif" >> $NGX_AUTO_CONFIG_H + echo >> $NGX_AUTO_CONFIG_H +fi diff --git a/auto/fmt/longlong b/auto/fmt/longlong deleted file mode 100644 --- a/auto/fmt/longlong +++ /dev/null @@ -1,45 +0,0 @@ - -echo "Checking for printf() long long format" - -NGX_LONG_LONG_FMT=NO - - echo "int main() {" > autotest.c - echo "printf(\"%llu\", (unsigned long long) -1);" >> autotest.c - echo "return 0; }" >> autotest.c - - eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - - if [ -x ./autotest -a "`./autotest`" = $NGX_MAX_LONG_LONG ]; then - echo " + \"%ll\" used" - NGX_LONG_LONG_FMT="ll" - else - echo " + \"%ll\" is not appropriate" - fi - - rm autotest* - - -if [ $NGX_LONG_LONG_FMT = NO ]; then - - echo "int main() {" > autotest.c - echo "printf(\"%qu\", (unsigned long long) -1);" >> autotest.c - echo "return 0; }" >> autotest.c - - eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - - if [ -x ./autotest -a "`./autotest`" = $NGX_MAX_LONG_LONG ]; then - echo " + \"%q\" used" - NGX_LONG_LONG_FMT="q" - else - echo " + \"%q\" is not appropriate" - fi - - rm autotest* - -fi - - -if [ $NGX_LONG_LONG_FMT = NO ]; then - echo "printf() long long format not found" - exit 1 -fi diff --git a/auto/func b/auto/func new file mode 100644 --- /dev/null +++ b/auto/func @@ -0,0 +1,21 @@ + +echo "checking for $NGX_FUNC" + +echo "$NGX_UNISTD_H" > autotest.c +echo "$NGX_FUNC_INC" >> autotest.c +echo "int main() { $NGX_FUNC_TEST; return 0; }" >> autotest.c + +eval "${CC} -o autotest autotest.c > /dev/null 2>&1" + +if [ -x autotest ]; then + echo " + $NGX_FUNC found" + + echo "#ifndef $NGX_HAVE" >> $NGX_AUTO_CONFIG_H + echo "#define $NGX_HAVE 1" >> $NGX_AUTO_CONFIG_H + echo "#endif" >> $NGX_AUTO_CONFIG_H + echo >> $NGX_AUTO_CONFIG_H +else + echo " + $NGX_FUNC not found" +fi + +rm autotest* diff --git a/auto/init b/auto/init new file mode 100644 --- /dev/null +++ b/auto/init @@ -0,0 +1,9 @@ + +MAKEFILE=$OBJS/Makefile + +NGX_AUTO_CONFIG_H=$OBJS/ngx_auto_config.h +NGX_MODULES_C=$OBJS/ngx_modules.c + + +NGX_UNISTD_H="#include " +NGX_INTTYPES_H="#include " diff --git a/auto/lib/lib b/auto/lib/lib new file mode 100644 --- /dev/null +++ b/auto/lib/lib @@ -0,0 +1,48 @@ + +if [ $PCRE != NO ]; then + + CORE_INCS="$CORE_INCS -I $PCRE" + + if [ "$PLATFORM" = "win32" ]; then + CFLAGS="$CFLAGS -D PCRE_STATIC" + CORE_LIBS="$CORE_LIBS pcre.lib" + CORE_LINK="$CORE_LINK -libpath:$PCRE" + else + CORE_DEPS="$CORE_DEPS $PCRE/.libs/libpcre.a" + CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre" + fi +fi + + +if [ $MD5 != NO ]; then + + CFLAGS="$CFLAGS -D HAVE_OPENSSL_MD5" + CORE_INCS="$CORE_INCS -I $MD5" + + if [ "$PLATFORM" = "win32" ]; then + CORE_LIBS="$CORE_LIBS md5.lib" + CORE_LINK="$CORE_LINK -libpath:$MD5" + else + LINK_DEPS="$LINK_DEPS $MD5/libmd5.a" + CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5" + fi + +elif [ $MD5_LIB != NO ]; then + CORE_LIBS="$CORE_LIBS $MD5_LIB" +fi + + +if [ $ZLIB != NO ]; then + CORE_INCS="$CORE_INCS -I $ZLIB" + + if [ "$PLATFORM" = "win32" ]; then + CORE_LIBS="$CORE_LIBS zlib.lib" + CORE_LINK="$CORE_LINK -libpath:$ZLIB" + else + LINK_DEPS="$LINK_DEPS $ZLIB/libz.a" + CORE_LIBS="$CORE_LIBS -L $ZLIB -lz" + fi + +elif [ $ZLIB_LIB != NO ]; then + CORE_LIBS="$CORE_LIBS $ZLIB_LIB" +fi diff --git a/auto/lib/make b/auto/lib/make new file mode 100644 --- /dev/null +++ b/auto/lib/make @@ -0,0 +1,26 @@ + +if [ "$PLATFORM" != "win32" ]; then + + if [ $PCRE != NO ]; then + echo "$PCRE/.libs/libpcre.a:" >> $MAKEFILE + echo " cd $PCRE \\" >> $MAKEFILE + echo " && ./configure --disable-shared \\" >> $MAKEFILE + echo " && \$(MAKE)" >> $MAKEFILE + echo >> $MAKEFILE + fi + + + if [ $MD5 != NO ]; then + echo "$MD5/libmd5.a:" >> $MAKEFILE + echo " cd $MD5 && \$(MAKE) x86-elf" >> $MAKEFILE + echo >> $MAKEFILE + fi + + + if [ $ZLIB != NO ]; then + echo "$ZLIB/libz.a:" >> $MAKEFILE + echo " cd $ZLIB && ./configure && \$(MAKE)" >> $MAKEFILE + echo >> $MAKEFILE + fi + +fi diff --git a/auto/lib/md5/makefile.msvc b/auto/lib/md5/makefile.msvc new file mode 100644 --- /dev/null +++ b/auto/lib/md5/makefile.msvc @@ -0,0 +1,4 @@ + +all: + cl -nologo -c -MT -O2 -D MD5_ASM -D L_ENDIAN md5_dgst.c md5_one.c + link -lib -out:md5.lib md5_dgst.obj md5_one.obj asm/m-win32.obj diff --git a/auto/lib/pcre/makefile.msvc b/auto/lib/pcre/makefile.msvc new file mode 100644 --- /dev/null +++ b/auto/lib/pcre/makefile.msvc @@ -0,0 +1,18 @@ + +CC = cl +CFLAGS = -O2 -Ob1 -Oi -Gs -MT +LINK = link + +PCREFLAGS = -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 + + +all: + $(CC) -Fedftables dftables.c + + dftables > chartables.c + + $(CC) -nologo -c $(CFLAGS) $(PCREFLAGS) \ + maketables.c get.c study.c pcre.c + + $(LINK) -lib -out:pcre.lib -verbose:lib \ + maketables.obj get.obj study.obj pcre.obj diff --git a/auto/lib/zlib/patch.zlib b/auto/lib/zlib/patch.zlib new file mode 100644 --- /dev/null +++ b/auto/lib/zlib/patch.zlib @@ -0,0 +1,19 @@ +--- msdos/Makefile.w32 Sat Nov 15 13:01:29 2003 ++++ msdos/Makefile.w32 Sat Nov 15 13:02:06 2003 +@@ -10,7 +10,7 @@ + + # ------------- Microsoft Visual C++ 4.0 and later ------------- + MODEL= +-CFLAGS=-Ox -GA3s -nologo -W3 ++CFLAGS=-nologo -O2 -Ob1 -Oi -Gs -MT + CC=cl + LD=link + LDFLAGS= +@@ -79,7 +79,6 @@ + $(CC) -c $(CFLAGS) $*.c + + zlib.lib: $(OBJ1) $(OBJ2) +- if exist zlib.lib del zlib.lib + lib /OUT:zlib.lib $(OBJ1) $(OBJ2) + + example.exe: example.obj zlib.lib diff --git a/auto/make b/auto/make new file mode 100644 --- /dev/null +++ b/auto/make @@ -0,0 +1,146 @@ + +mkdir -p $OBJS/src/core $OBJS/src/event $OBJS/src/event/modules \ + $OBJS/src/os/unix $OBJS/src/os/win32 \ + $OBJS/src/http $OBJS/src/http/modules $OBJS/src/http/modules/proxy + + +HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES \ + $HTTP_CHUNKED_FILTER_MODULE \ + $HTTP_RANGE_FILTER_MODULE \ + $HTTP_CHARSET_FILTER_MODULE" + +HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE" + +if [ $HTTP_GZIP = YES ]; then + HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE" + HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS" +fi + +if [ $HTTP_PROXY = YES ]; then + HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE" + HTTP_INCS="$HTTP_INCS $HTTP_PROXY_INCS" + HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS" + HTTP_SRCS="$HTTP_SRCS $HTTP_PROXY_SRCS" +fi + +modules="$CORE_MODULES $EVENT_MODULES $HTTP_MODULES \ + $HTTP_FILTER_MODULES $HTTP_NOT_MODIFIED_FILTER_MODULE" + + +echo "#include " > $NGX_MODULES_C +echo "#include " >> $NGX_MODULES_C +echo >> $NGX_MODULES_C + +for mod in $modules +do + echo "extern ngx_module_t $mod;" >> $NGX_MODULES_C +done + +echo >> $NGX_MODULES_C +echo 'ngx_module_t *ngx_modules[] = {' >> $NGX_MODULES_C + +for mod in $modules +do + echo " &$mod," >> $NGX_MODULES_C +done + +echo " NULL" >> $NGX_MODULES_C +echo "};" >> $NGX_MODULES_C + + +echo "CC = $CC" > $MAKEFILE +echo "CFLAGS = $CFLAGS" >> $MAKEFILE +echo >> $MAKEFILE + +echo "CORE_DEPS = \\" >> $MAKEFILE +for dep in $CORE_DEPS +do + echo " $dep \\" >> $MAKEFILE +done +echo >> $MAKEFILE + +echo "CORE_INCS = $CORE_INCS -I $OBJS" >> $MAKEFILE +echo >> $MAKEFILE + +echo "HTTP_DEPS = \\" >> $MAKEFILE +for inc in $HTTP_DEPS +do + echo " $inc \\" >> $MAKEFILE +done +echo >> $MAKEFILE + +echo "HTTP_INCS = $HTTP_INCS" >> $MAKEFILE +echo >> $MAKEFILE + + + +echo "nginx: \\" >> $MAKEFILE + +for src in $CORE_SRCS $HTTP_SRCS +do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + echo " $OBJS/$obj \\" >> $MAKEFILE +done + +for src in $NGX_MODULES_C $LINK_DEPS +do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + echo " $obj \\" >> $MAKEFILE +done + +echo >> $MAKEFILE +echo " \$(CC) ${BINOUT}nginx \\" >> $MAKEFILE + +for src in $CORE_SRCS $HTTP_SRCS +do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + echo " $OBJS/$obj \\" >> $MAKEFILE +done + +obj=`echo $NGX_MODULES_C | sed -e "s/\.c\$/.$OBJEXT/"` +echo " $obj \\" >> $MAKEFILE +echo " $CORE_LIBS \\" >> $MAKEFILE +echo " $CORE_LINK" >> $MAKEFILE +echo >> $MAKEFILE + + +deps="\$(CORE_DEPS)" +args="\$(CFLAGS) \$(CORE_INCS)" + +echo "$obj: \\" >> $MAKEFILE +echo " $NGX_MODULES_C $deps" >> $MAKEFILE +echo " \$(CC) -c $args \\" >> $MAKEFILE +echo " $OBJOUT$obj \\" >> $MAKEFILE +echo " $NGX_MODULES_C" >> $MAKEFILE +echo >> $MAKEFILE + + + + +for src in $CORE_SRCS +do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + + echo "$OBJS/$obj: \\" >> $MAKEFILE + echo " $src $deps" >> $MAKEFILE + echo " \$(CC) -c $args \\" >> $MAKEFILE + echo " $OBJOUT$OBJS/$obj \\" >> $MAKEFILE + echo " $src" >> $MAKEFILE + echo >> $MAKEFILE +done + + +deps="\$(CORE_DEPS) \$(HTTP_DEPS)" +args="\$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)" + +for src in $HTTP_SRCS +do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + + echo "$OBJS/$obj: \\" >> $MAKEFILE + echo " $src $deps" >> $MAKEFILE + echo " \$(CC) -c $args \\" >> $MAKEFILE + echo " $OBJOUT$OBJS/$obj \\" >> $MAKEFILE + echo " $src" >> $MAKEFILE + echo >> $MAKEFILE +done diff --git a/auto/options b/auto/options new file mode 100644 --- /dev/null +++ b/auto/options @@ -0,0 +1,68 @@ + +HELP=NO + +CC=gcc +OBJS=objs + +TEST_BUILD_DEVPOLL=NO + +HTTP_GZIP=YES +HTTP_PROXY=YES + +PCRE=NO + +MD5=NO +MD5_LIB=NO + +ZLIB=NO +ZLIB_LIB=NO + + +for option +do + case "$option" in + -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) value="" ;; + esac + + case "$option" in + --help) HELP=YES ;; + + --crossbuild=*) PLATFORM="$value" ;; + + --builddir=*) OBJS="$value" ;; + + --without-http_gzip_module) HTTP_GZIP=NO ;; + --without-http_proxy_module) HTTP_PROXY=NO ;; + + --with-cc=*) CC="$value" ;; + + --with-pcre=*) PCRE="$value" ;; + --with-md5=*) MD5="$value" ;; + --with-zlib=*) ZLIB="$value" ;; + + --test-build-devpoll) TEST_BUILD_DEVPOLL=YES ;; + + *) + echo "$0: error: invalid option \"$option\"" + exit 1 + ;; + esac +done + + +if [ $HELP = YES ]; then + echo " --help this message" + + echo " --without-http_gzip_module disable http_gzip_module" + echo " --without-http_proxy_module disable http_proxy_module" + + echo " --with-cc=NAME name of or path to C compiler" + echo + + echo " --with-pcre=DIR path to PCRE library" + echo " --with-md5=DIR path to md5 library" + echo " --with-zlib=DIR path to zlib library" + + exit 1 +fi diff --git a/auto/os/conf b/auto/os/conf new file mode 100644 --- /dev/null +++ b/auto/os/conf @@ -0,0 +1,47 @@ + +if [ ".$PLATFORM" = "." ]; then + echo "checking for OS" + + SYSTEM=`uname -s 2>/dev/null` + RELEASE=`uname -r 2>/dev/null` + MACHINE=`uname -m 2>/dev/null` + + echo " + $SYSTEM $RELEASE $MACHINE" + + PLATFORM="$SYSTEM:$RELEASE:$MACHINE"; +else + echo "building for $PLATFORM" +fi + +case $PLATFORM in + + FreeBSD:*) + . auto/os/freebsd + ;; + + Solaris:*) + CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64" + CORE_LIBS="$CORE_LIBS -lsocket -lnsl" + ;; + + Linux:*) + CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" + ;; + + win32) + CORE_INCS="$WIN32_INCS" + CORE_DEPS="$WIN32_DEPS" + CORE_SRCS="$WIN32_SRCS $SELECT_SRCS $IOCP_SRCS" + EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $IOCP_MODULE" + + CFLAGS="$CFLAGS -D HAVE_AIO=1 -D HAVE_IOCP=1" + CORE_LIBS="$CORE_LIBS ws2_32.lib" + ;; + +esac + + +if [ $TEST_BUILD_DEVPOLL = YES ]; then + EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE" + EVENT_SRCS="$EVENT_SRCS $DEVPOLL_SRCS" +fi diff --git a/auto/os/freebsd b/auto/os/freebsd new file mode 100644 --- /dev/null +++ b/auto/os/freebsd @@ -0,0 +1,40 @@ + + +CORE_INCS="$UNIX_INCS" +CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS" +CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS $SELECT_SRCS $POLL_SRCS" +EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $POLL_MODULE" + +MD5_LIB="-lmd" +ZLIB_LIB="-lz" + +version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \ + | sed -e 's/^.* \(.*\)$/\1/'` + + +# sendfile + +if [ $version -gt 300007 ]; then + CFLAGS="$CFLAGS -D HAVE_SENDFILE=1" + CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS" +fi + + +# kqueue + +if [ \( $version -lt 500000 -a $version -ge 410000 \) \ + -o $version -ge 500011 ] +then + CFLAGS="$CFLAGS -D HAVE_KQUEUE=1" + CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS" + EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE" +fi + + +# kqueue's NOTE_LAWAT + +if [ \( $version -lt 500000 -a $version -ge 430000 \) \ + -o $version -ge 500018 ] +then + CFLAGS="$CFLAGS -D HAVE_LOWAT_EVENT=1" +fi diff --git a/auto/sources b/auto/sources new file mode 100644 --- /dev/null +++ b/auto/sources @@ -0,0 +1,194 @@ + +CORE_MODULES="ngx_core_module ngx_errlog_module" + +CORE_INCS="-I src/core" + +CORE_DEPS="src/core/nginx.h \ + src/core/ngx_config.h \ + src/core/ngx_log.h \ + src/core/ngx_alloc.h \ + src/core/ngx_array.h \ + src/core/ngx_table.h \ + src/core/ngx_hunk.h \ + src/core/ngx_string.h \ + src/core/ngx_parse.h \ + src/core/ngx_inet.h \ + src/core/ngx_file.h \ + src/core/ngx_regex.h \ + src/core/ngx_times.h \ + src/core/ngx_connection.h \ + src/core/ngx_conf_file.h \ + src/core/ngx_garbage_collector.h" + +CORE_SRCS="src/core/nginx.c \ + src/core/ngx_log.c \ + src/core/ngx_alloc.c \ + src/core/ngx_array.c \ + src/core/ngx_hunk.c \ + src/core/ngx_output_chain.c \ + src/core/ngx_string.c \ + src/core/ngx_parse.c \ + src/core/ngx_inet.c \ + src/core/ngx_file.c \ + src/core/ngx_regex.c \ + src/core/ngx_times.c \ + src/core/ngx_conf_file.c \ + src/core/ngx_garbage_collector.c" + + +EVENT_MODULES="ngx_events_module ngx_event_core_module" + +EVENT_INCS="-I src/event -I src/event/modules" + +EVENT_DEPS="src/event/ngx_event.h \ + src/event/ngx_event_timer.h \ + src/event/ngx_event_connect.h \ + src/event/ngx_event_pipe.h" + +EVENT_SRCS="src/event/ngx_event.c \ + src/event/ngx_event_timer.c \ + src/event/ngx_event_close.c \ + src/event/ngx_event_accept.c \ + src/event/ngx_event_connect.c \ + src/event/ngx_event_pipe.c" + + +SELECT_MODULE="ngx_select_module" +SELECT_SRCS=src/event/modules/ngx_select_module.c + +POLL_MODULE="ngx_poll_module" +POLL_SRCS=src/event/modules/ngx_poll_module.c + +KQUEUE_MODULE="ngx_kqueue_module" +KQUEUE_SRCS=src/event/modules/ngx_kqueue_module.c + +DEVPOLL_MODULE="ngx_devpoll_module" +DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c + +IOCP_MODULE="ngx_iocp_module" +IOCP_SRCS=src/event/modules/ngx_iocp_module.c + +AIO_MODULE="ngx_aio_module" +AIO_SRCS=src/event/modules/ngx_aio_module.c + + +UNIX_INCS="$CORE_INCS $EVENT_INCS -I src/os/unix" + +UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \ + src/os/unix/ngx_time.h \ + src/os/unix/ngx_types.h \ + src/os/unix/ngx_errno.h \ + src/os/unix/ngx_files.h \ + src/os/unix/ngx_process.h \ + src/os/unix/ngx_socket.h \ + src/os/unix/ngx_os.h" + +UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ + src/os/unix/ngx_time.c \ + src/os/unix/ngx_sendv.c \ + src/os/unix/ngx_files.c \ + src/os/unix/ngx_socket.c \ + src/os/unix/ngx_recv.c \ + src/os/unix/ngx_readv_chain.c \ + src/os/unix/ngx_writev_chain.c \ + src/os/unix/ngx_posix_init.c \ + src/os/unix/ngx_process.c \ + src/os/unix/ngx_daemon.c" + + +LINUX_SENDFILE_SRCS=src/os/unix/ngx_linux_sendfile_chain.c + +FREEBSD_DEPS=src/os/unix/ngx_freebsd_config.h +FREEBSD_SRCS=src/os/unix/ngx_freebsd_init.c +FREEBSD_SENDFILE_SRCS=src/os/unix/ngx_freebsd_sendfile_chain.c + + +WIN32_INCS="$CORE_INCS $EVENT_INCS -I src/os/win32" + +WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \ + src/os/win32/ngx_win32_config.h \ + src/os/win32/ngx_time.h \ + src/os/win32/ngx_types.h \ + src/os/win32/ngx_errno.h \ + src/os/win32/ngx_files.h \ + src/os/win32/ngx_process.h \ + src/os/win32/ngx_socket.h \ + src/os/win32/ngx_os.h" + +WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ + src/os/win32/ngx_errno.c \ + src/os/win32/ngx_files.c \ + src/os/win32/ngx_time.c \ + src/os/win32/ngx_socket.c \ + src/os/win32/ngx_wsarecv.c \ + src/os/win32/ngx_wsarecv_chain.c \ + src/os/win32/ngx_wsasend_chain.c \ + src/os/win32/ngx_sendv.c \ + src/os/win32/ngx_win32_init.c \ + src/event/ngx_event_acceptex.c" + + +HTTP_MODULES="ngx_http_module \ + ngx_http_core_module \ + ngx_http_log_module \ + ngx_http_cache_module" + +HTTP_FILTER_MODULES="ngx_http_write_filter_module \ + ngx_http_output_filter_module \ + ngx_http_header_filter_module" + +HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module +HTTP_RANGE_FILTER_MODULE=ngx_http_range_filter_module +HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module +HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module + +HTTP_STATIC_MODULE=ngx_http_static_module +HTTP_INDEX_MODULE=ngx_http_index_module + +HTTP_INCS="-I src/http -I src/http/modules" + +HTTP_DEPS="src/http/ngx_http.h \ + src/http/ngx_http_request.h \ + src/http/ngx_http_filter.h \ + src/http/ngx_http_config.h \ + src/http/ngx_http_core_module.h \ + src/http/ngx_http_cache.h \ + src/http/ngx_http_busy_lock.h \ + src/http/ngx_http_log_handler.h" + +HTTP_SRCS="src/http/ngx_http.c \ + src/http/ngx_http_core_module.c \ + src/http/ngx_http_special_response.c \ + src/http/ngx_http_request.c \ + src/http/ngx_http_cache.c \ + src/http/ngx_http_busy_lock.c \ + src/http/ngx_http_parse.c \ + src/http/ngx_http_headers.c \ + src/http/ngx_http_header_filter.c \ + src/http/ngx_http_write_filter.c \ + src/http/ngx_http_output_filter.c \ + src/http/ngx_http_log_handler.c \ + src/http/ngx_http_request_body.c \ + src/http/ngx_http_parse_time.c \ + src/http/modules/ngx_http_static_handler.c \ + src/http/modules/ngx_http_index_handler.c \ + src/http/modules/ngx_http_chunked_filter.c \ + src/http/modules/ngx_http_range_filter.c \ + src/http/modules/ngx_http_charset_filter.c \ + src/http/modules/ngx_http_not_modified_filter.c" + + +HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module +HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter.c +HTTP_GZIP_UNIX_LIBS=-lz +HTTP_GZIP_WIN_LIBS=zlib.lib + + +HTTP_PROXY_MODULE=ngx_http_proxy_module +HTTP_PROXY_INCS="-I src/http/modules/proxy" +HTTP_PROXY_DEPS=src/http/modules/proxy/ngx_http_proxy_handler.h +HTTP_PROXY_SRCS="src/http/modules/proxy/ngx_http_proxy_handler.c \ + src/http/modules/proxy/ngx_http_proxy_upstream.c \ + src/http/modules/proxy/ngx_http_proxy_cache.c \ + src/http/modules/proxy/ngx_http_proxy_parse.c \ + src/http/modules/proxy/ngx_http_proxy_header.c" diff --git a/auto/types/longlong b/auto/types/longlong deleted file mode 100644 --- a/auto/types/longlong +++ /dev/null @@ -1,31 +0,0 @@ - -echo "Checking for long long size" - -BYTES= - -echo "int main() {" > autotest.c -echo "printf(\"%d\", sizeof(long long));" >> autotest.c -echo "return 0; }" >> autotest.c - -eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - -if [ -x ./autotest ]; then - BYTES=`./autotest` - echo " + long long is $BYTES bytes" -fi - -rm autotest* - -case $BYTES in - 4) - NGX_MAX_LONG_LONG=4294967295 - ;; - - 8) - NGX_MAX_LONG_LONG=18446744073709551615 - ;; - - *) - echo "$0: error: can not detect long long size" - exit 1 -esac diff --git a/auto/types/sizeof b/auto/types/sizeof --- a/auto/types/sizeof +++ b/auto/types/sizeof @@ -1,29 +1,37 @@ -echo "Checking for $NGX_TYPE size" +echo "checking for $NGX_TYPE size" -BYTES= +NGX_BYTES= echo "#include " > autotest.c echo "int main() {" >> autotest.c echo "printf(\"%d\", sizeof($NGX_TYPE));" >> autotest.c echo "return 0; }" >> autotest.c -eval "${CC} -o autotest autotest.c > /dev/null 2>&1" +eval "$CC $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1" if [ -x ./autotest ]; then - BYTES=`./autotest` - echo " + $NGX_TYPE is $BYTES bytes" + NGX_BYTES=`./autotest` + echo " + $NGX_TYPE is $NGX_BYTES bytes" fi rm autotest* -case $BYTES in +case $NGX_BYTES in 4) - NGX_MAX_SIZE=2147483647 + if [ "$NGX_TYPE"="long" ]; then + NGX_MAX_SIZE=2147483647L + else + NGX_MAX_SIZE=2147483647 + fi ;; 8) - NGX_MAX_SIZE=9223372036854775807 + if [ "$NGX_TYPE"="long long" ]; then + NGX_MAX_SIZE=9223372036854775807LL + else + NGX_MAX_SIZE=9223372036854775807L + fi ;; *) diff --git a/auto/types/socklen_t b/auto/types/socklen_t deleted file mode 100644 --- a/auto/types/socklen_t +++ /dev/null @@ -1,28 +0,0 @@ - -found=0 - -echo 'Checking for socklen_t' - -echo '#include ' > autotest.c -echo '#include ' >> autotest.c -echo 'int main() { socklen_t i = 0; return 0; }' >> autotest.c - -eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - -if [ -x autotest ]; then - echo ' + socklen_t found' - found=1 -else - echo ' + socklen_t not found' - echo ' + uint32_t used' - type='typedef uint32_t socklen_t;' - found=2 -fi - -rm autotest* - - -if [ $found = 2 ]; then - echo $type >> ngx_auto_config.h - echo >> ngx_auto_config.h -fi diff --git a/auto/types/time_t b/auto/types/time_t deleted file mode 100644 --- a/auto/types/time_t +++ /dev/null @@ -1,30 +0,0 @@ - -echo "Checking for printf() time_t format" - -echo '#include ' > autotest.c -type=`${CPP} autotest.c | awk '/^typedef.*time_t/ {print \$2}'` -rm autotest.c - -case $type in - long) - echo ' + long: "%ld" used' - fmt='"%ld"' - ;; - - int) - echo ' + int: "%d" used' - fmt='"%d"' - ;; - - *) - echo "$0: error: unknown time_t definition: \"$type\"" - exit 1 - ;; - -esac - - -echo "#ifndef TIME_FMT" >> ngx_auto_config.h -echo "#define TIME_FMT $fmt" >> ngx_auto_config.h -echo "#endif" >> ngx_auto_config.h -echo >> ngx_auto_config.h diff --git a/auto/types/typedef b/auto/types/typedef --- a/auto/types/typedef +++ b/auto/types/typedef @@ -1,32 +1,42 @@ - -echo "Checking for $NGX_TYPE definition" -echo "#include " > autotest.c -TYPE=`${CPP} autotest.c | \ - awk "/^typedef.*$NGX_TYPE/ { for (i = 1; i< NF; i++) print $i}"` -#rm autotest.c +echo "checking for $NGX_TYPE" + +FOUND=NO -echo $TYPE +for TYPE in $NGX_TYPE $NGX_TYPES +do + echo "#include " > autotest.c + echo "#include " >> autotest.c + echo "$NGX_INTTYPES_H" >> autotest.c + echo "int main() { $TYPE i = 0; return 0; }" >> autotest.c -case $TYPE in - "long long") - echo ' + defined as long long' - NGX_FMT=$NGX_LONG_LONG_FMT - ;; + eval "$CC -o autotest autotest.c > /dev/null 2>&1" - long) - echo ' + defined as long' - NGX_FMT=$NGX_LONG_FMT - ;; + if [ -x autotest ]; then + if [ $TYPE = $NGX_TYPE ]; then + echo " + $NGX_TYPE found" + FOUND=YES + else + echo " + $TYPE used" + FOUND=$TYPE + fi + fi + + rm autotest* - int) - echo ' + defined as int' - NGX_FMT=$NGX_INT_FMT - ;; + if [ $FOUND = NO ]; then + echo " + $TYPE not found" + else + break + fi +done - *) - echo "$0: error: unknown $NGX_TYPE definition: \"$TYPE\"" - exit 1 - ;; +if [ $FOUND = NO ]; then + echo "$0: error: can not define $NGX_TYPE" + exit 1 +fi -esac +if [ $FOUND != YES ]; then + echo "typedef $FOUND $NGX_TYPE;" >> $NGX_AUTO_CONFIG_H + echo >> $NGX_AUTO_CONFIG_H +fi diff --git a/auto/types/uint64_t b/auto/types/uint64_t deleted file mode 100644 --- a/auto/types/uint64_t +++ /dev/null @@ -1,50 +0,0 @@ - -found=0 - -echo 'Checking for uint64_t' - - echo '#include ' > autotest.c - echo 'int main() { uint64_t i = 0; return 0; }' >> autotest.c - - eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - - if [ -x autotest ]; then - echo ' + uint64_t found' - found=1 - else - echo ' + uint64_t not found' - fi - - rm autotest* - - -if [ $found = 0 ]; then - - echo '#include ' > autotest.c - echo 'int main() { u_int64_t i = 0; return 0; }' >> autotest.c - - eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - - if [ -x autotest ]; then - echo ' + u_int64_t used' - type='typedef u_int64_t uint64_t;' - found=2 - else - echo ' + u_int64_t not found' - fi - - rm autotest* - -fi - - -if [ $found = 0 ]; then - echo "$0: error: uint64_t not found" - exit 1 -fi - - -if [ $found = 2 ]; then - echo $type >> ngx_auto_config.h - echo >> ngx_auto_config.h -fi diff --git a/auto/types/uintptr_t b/auto/types/uintptr_t --- a/auto/types/uintptr_t +++ b/auto/types/uintptr_t @@ -1,47 +1,26 @@ -found=0 +echo 'checking for uintptr_t' -echo 'Checking for uintptr_t' +FOUND=NO - echo '#include ' > autotest.c - echo 'int main() { uintptr_t i = 0; return i; }' >> autotest.c +echo "#include " > autotest.c +echo "int main() { uintptr_t i = 0; return 0; }" >> autotest.c - eval "${CC} -o autotest autotest.c > /dev/null 2>&1" +eval "$CC -o autotest autotest.c > /dev/null 2>&1" - if [ -x autotest ]; then - echo ' + uintptr_t found' - found=1 - else - echo ' + uintptr_t not found' - fi +if [ -x autotest ]; then + echo " + uintptr_t found" + FOUND=YES +else + echo " + uintptr_t not found" +fi - rm autotest* +rm autotest* -if [ $found = 0 ]; then - echo 'int main() { printf("%d", 8 * sizeof(void *)); return 0; }' \ - > autotest.c - eval "${CC} -o autotest autotest.c > /dev/null 2>&1" - - if [ -x autotest ]; then - type="uint`./autotest`_t" - echo " + $type used" - type="typedef $type uintptr_t;" - found=2 - fi - - rm autotest* +if [ $FOUND = NO ]; then + FOUND="uint`expr 8 \* $NGX_PTR_BYTES`_t" + echo " + $FOUND used" + echo "typedef $FOUND uintptr_t;" >> $NGX_AUTO_CONFIG_H + echo >> $NGX_AUTO_CONFIG_H fi - - -if [ $found = 0 ]; then - echo "$0: error: uintptr_t not found" - exit 1 -fi - - -if [ $found = 2 ]; then - echo $type >> ngx_auto_config.h - echo >> ngx_auto_config.h -fi - diff --git a/auto/unix b/auto/unix new file mode 100755 --- /dev/null +++ b/auto/unix @@ -0,0 +1,70 @@ + +CC_WARN=$CC +NGX_FMT_COLLECT=YES + +NGX_TYPE="int"; . auto/types/sizeof; +NGX_FORMATS="%d"; . auto/fmt/fmt + +NGX_TYPE="long"; . auto/types/sizeof; +NGX_FORMATS="%ld"; . auto/fmt/fmt + +NGX_TYPE="long long"; . auto/types/sizeof; +NGX_FORMATS="%lld %qd"; . auto/fmt/fmt + +NGX_TYPE="void *"; . auto/types/sizeof; NGX_PTR_BYTES=$NGX_BYTES + + +CC_WARN=$CC_STRONG +NGX_FMT_COLLECT=NO + +NGX_FMT_NAME=OFF_T_FMT +NGX_TYPE="off_t"; . auto/types/sizeof +eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt + +NGX_FMT_NAME=TIME_T_FMT +NGX_TYPE="time_t"; . auto/types/sizeof +eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt + +NGX_FMT_NAME=SIZE_T_FMT +NGX_TYPE="size_t"; . auto/types/sizeof +eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt + +NGX_FMT_NAME=SIZE_T_X_FMT; . auto/fmt/xfmt + +NGX_FMT_NAME=PID_T_FMT +NGX_TYPE="pid_t"; . auto/types/sizeof +eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt + +NGX_FMT_NAME=RLIM_T_FMT +NGX_TYPE="rlim_t"; . auto/types/sizeof +eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt + + +CC_WARN=$CC + +NGX_TYPE="uint64_t" +NGX_TYPES="u_int64_t"; . auto/types/typedef + +NGX_TYPE="socklen_t" +NGX_TYPES="u_int32_t"; . auto/types/typedef + +. auto/types/uintptr_t + + +NGX_FUNC_INC= +NGX_FUNC_TEST="int fd = 0; char buf[1]; size_t size = 1; + ssize_t n; off_t offset = 0; + n = pread(fd, buf, size, offset)" +NGX_HAVE=HAVE_PREAD; NGX_FUNC="pread()"; . auto/func + + +NGX_FUNC_INC= +NGX_FUNC_TEST="int fd = 1; char buf[1]; size_t size = 1; + ssize_t n; off_t offset = 0; + n = pwrite(fd, buf, size, offset)" +NGX_HAVE=HAVE_PWRITE; NGX_FUNC="pwrite()"; . auto/func + + +NGX_FUNC_INC="#include " +NGX_FUNC_TEST="struct tm t; time_t c=0; localtime_r(&c, &t)" +NGX_HAVE=HAVE_LOCALTIME_R; NGX_FUNC="localtime_r()"; . auto/func diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -59,6 +59,7 @@ ngx_array_t ngx_old_cycles; static ngx_pool_t *ngx_temp_pool; static ngx_event_t ngx_cleaner_event; + /* STUB NAME */ static ngx_connection_t dumb; @@ -91,7 +92,8 @@ int main(int argc, char *const *argv) /* TODO */ ngx_max_sockets = -1; - ngx_init_time(); + ngx_time_init(); + ngx_regex_init(); log = ngx_log_init_errlog(); diff --git a/src/core/ngx_alloc.h b/src/core/ngx_alloc.h --- a/src/core/ngx_alloc.h +++ b/src/core/ngx_alloc.h @@ -7,9 +7,9 @@ /* - * NGX_MAX_ALLOC_FROM_POOL should be (PAGE_SIZE - 1), i.e. 4095 on x86. + * NGX_MAX_ALLOC_FROM_POOL should be (NGX_PAGE_SIZE - 1), i.e. 4095 on x86. * On FreeBSD 5.x it allows to use zero copy send. - * On Windows NT it decreases number of locked pages in kernel. + * On Windows NT it decreases a number of locked pages in a kernel. */ #define NGX_MAX_ALLOC_FROM_POOL 4095 diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -3,9 +3,6 @@ #include - -#define MAX_CONF_ERRSTR 256 - /* Ten fixed arguments */ static int argument_number[] = { @@ -471,7 +468,29 @@ ngx_log_debug(cf->log, "%d:%d:%d:%d:%d ' len++) { if (*src == '\\') { - src++; + switch (src[1]) { + case '"': + case '\'': + case '\\': + src++; + break; + + case 't': + *dst++ = '\t'; + src += 2; + continue; + + case 'r': + *dst++ = '\r'; + src += 2; + continue; + + case 'n': + *dst++ = '\n'; + src += 2; + continue; + } + } *dst++ = *src++; } @@ -525,7 +544,7 @@ void ngx_conf_log_error(int level, ngx_c char *fmt, ...) { int len; - char errstr[MAX_CONF_ERRSTR]; + char errstr[NGX_MAX_CONF_ERRSTR]; va_list args; va_start(args, fmt); diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -56,6 +56,9 @@ #define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */ +#define NGX_MAX_CONF_ERRSTR 256 + + struct ngx_command_s { ngx_str_t name; int type; diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -2,9 +2,6 @@ #define _NGX_CONFIG_H_INCLUDED_ -#include - - #if defined __FreeBSD__ #include @@ -32,6 +29,13 @@ #endif +/* STUB: autoconf */ +typedef int ngx_int_t; +typedef u_int ngx_uint_t; + +#include + + #ifndef NGX_SERVER_ROOT #define NGX_SERVER_ROOT "./" #if 0 diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -28,6 +28,7 @@ typedef struct ngx_connection_s ngx_con #include #include #include +#include #include #include #include diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -70,7 +70,10 @@ int ngx_create_temp_file(ngx_file_t *fil #endif #endif +#if 0 file->fd = ngx_open_tempfile(file->name.data, persistent); +#endif + file->fd = ngx_open_tempfile(file->name.data, 1); ngx_log_debug(file->log, "temp fd: %d" _ file->fd); @@ -225,14 +228,15 @@ char *ngx_conf_set_path_slot(ngx_conf_t return "invalid value"; } - path->len += path->level[i] + level + 1; + path->level[i] = level; + path->len += level + 1; } while (i < 3) { path->level[i++] = 0; } - path->gc_handler = cmd->post; + path->gc_handler = (ngx_gc_handler_pt) cmd->post; return NGX_CONF_OK; } diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -89,7 +89,7 @@ void ngx_log_error_core(int level, ngx_l /* pid#tid */ len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, - PID_FMT "#%d: ", ngx_getpid(), 0); + PID_T_FMT "#%d: ", ngx_getpid(), 0); if (log->data) { len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, diff --git a/src/core/ngx_modules.c b/src/core/ngx_modules.c --- a/src/core/ngx_modules.c +++ b/src/core/ngx_modules.c @@ -28,6 +28,7 @@ extern ngx_module_t ngx_aio_module; extern ngx_module_t ngx_http_module; extern ngx_module_t ngx_http_core_module; extern ngx_module_t ngx_http_log_module; +extern ngx_module_t ngx_http_cache_module; extern ngx_module_t ngx_http_write_filter_module; extern ngx_module_t ngx_http_output_filter_module; @@ -78,6 +79,8 @@ ngx_module_t *ngx_modules[] = { &ngx_http_core_module, &ngx_http_log_module, + &ngx_http_cache_module, + &ngx_http_write_filter_module, &ngx_http_output_filter_module, &ngx_http_header_filter_module, diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c new file mode 100644 --- /dev/null +++ b/src/core/ngx_regex.c @@ -0,0 +1,71 @@ + +#include +#include + + +static void *ngx_regex_malloc(size_t size); +static void ngx_regex_free(void *p); + + +/* THREADS: this pool should be private for each thread */ +static ngx_pool_t *ngx_pcre_pool; + + +void ngx_regex_init() +{ + pcre_malloc = ngx_regex_malloc; + pcre_free = ngx_regex_free; +} + + +ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, + ngx_pool_t *pool, ngx_str_t *err) +{ + int erroff; + const char *errstr; + ngx_regex_t *re; + + ngx_pcre_pool = pool; + + re = pcre_compile(pattern->data, (int) options, &errstr, &erroff, NULL); + + if (re == NULL) { + if ((size_t) erroff == pattern->len) { + ngx_snprintf(err->data, err->len - 1, + "pcre_compile() failed: %s in \"%s\"", + errstr, pattern->data); + } else { + ngx_snprintf(err->data, err->len - 1, + "pcre_compile() failed: %s in \"%s\" at \"%s\"", + errstr, pattern->data, pattern->data + erroff); + } + } + + return re; +} + + +ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s) +{ + int rc; + + rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, NULL, 0); + + if (rc == -1) { + return NGX_DECLINED; + } + + return rc; +} + + +static void *ngx_regex_malloc(size_t size) +{ + return ngx_palloc(ngx_pcre_pool, size); +} + + +static void ngx_regex_free(void *p) +{ + return; +} diff --git a/src/core/ngx_regex.h b/src/core/ngx_regex.h new file mode 100644 --- /dev/null +++ b/src/core/ngx_regex.h @@ -0,0 +1,23 @@ +#ifndef _NGX_REGEX_H_INCLUDED_ +#define _NGX_REGEX_H_INCLUDED_ + + +#include +#include + +#include + + +#define NGX_REGEX_CASELESS PCRE_CASELESS + +typedef pcre ngx_regex_t; + +void ngx_regex_init(); +ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, + ngx_pool_t *pool, ngx_str_t *err); +ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s); + +#define ngx_regex_exec_n "pcre_exec()" + + +#endif /* _NGX_REGEX_H_INCLUDED_ */ diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -22,7 +22,7 @@ static char *months[] = { "Jan", "Feb", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -void ngx_init_time() +void ngx_time_init() { struct timeval tv; diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h --- a/src/core/ngx_times.h +++ b/src/core/ngx_times.h @@ -6,7 +6,7 @@ #include -void ngx_init_time(); +void ngx_time_init(); void ngx_time_update(); size_t ngx_http_time(char *buf, time_t t); void ngx_gmtime(time_t t, ngx_tm_t *tp); diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -190,6 +190,7 @@ static void ngx_kqueue_done(ngx_cycle_t static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) { + ngx_event_t *e; ngx_connection_t *c; ev->active = 1; @@ -200,6 +201,28 @@ static int ngx_kqueue_add_event(ngx_even && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1) == (uintptr_t) ev) { + if (change_list[ev->index].flags == EV_DISABLE) { + +#if (NGX_DEBUG_EVENT) + ngx_connection_t *c = (ngx_connection_t *) ev->data; + ngx_log_debug(ev->log, "kqueue event activated: %d: ft:%d" _ + c->fd _ event); +#endif + + /* + * if the EV_DISABLE is still not passed to a kernel + * we will not pass it + */ + + if (ev->index < (u_int) --nchanges) { + e = (ngx_event_t *) change_list[nchanges].udata; + change_list[ev->index] = change_list[nchanges]; + e->index = ev->index; + } + + return NGX_OK; + } + c = ev->data; ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "previous event on #%d were not passed in kernel", c->fd); @@ -207,7 +230,7 @@ static int ngx_kqueue_add_event(ngx_even return NGX_ERROR; } - return ngx_kqueue_set_event(ev, event, EV_ADD|flags); + return ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags); } @@ -286,24 +309,27 @@ static int ngx_kqueue_set_event(ngx_even change_list[nchanges].flags = flags; change_list[nchanges].udata = (void *) ((uintptr_t) ev | ev->instance); -#if (HAVE_LOWAT_EVENT) - - if (flags & NGX_LOWAT_EVENT) { - change_list[nchanges].fflags = NOTE_LOWAT; - change_list[nchanges].data = ev->available; + if (filter == EVFILT_VNODE) { + change_list[nchanges].fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND + |NOTE_ATTRIB|NOTE_RENAME|NOTE_REVOKE; + change_list[nchanges].data = 0; } else { +#if (HAVE_LOWAT_EVENT) + if (flags & NGX_LOWAT_EVENT) { + change_list[nchanges].fflags = NOTE_LOWAT; + change_list[nchanges].data = ev->available; + + } else { + change_list[nchanges].fflags = 0; + change_list[nchanges].data = 0; + } +#else change_list[nchanges].fflags = 0; change_list[nchanges].data = 0; +#endif } -#else - - change_list[nchanges].fflags = 0; - change_list[nchanges].data = 0; - -#endif - ev->index = nchanges; nchanges++; @@ -365,12 +391,16 @@ static int ngx_kqueue_process_events(ngx ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta); #endif +#if 0 /* * The expired timers must be handled before a processing of the events * because the new timers can be added during a processing */ ngx_event_expire_timers((ngx_msec_t) delta); +#endif + + ngx_event_set_timer_delta((ngx_msec_t) delta); } else { if (events == 0) { @@ -452,6 +482,13 @@ static int ngx_kqueue_process_events(ngx break; + case EVFILT_VNODE: + ev->kq_vnode = 1; + + ev->event_handler(ev); + + break; + case EVFILT_AIO: ev->complete = 1; ev->ready = 1; @@ -463,10 +500,15 @@ static int ngx_kqueue_process_events(ngx default: ngx_log_error(NGX_LOG_ALERT, log, 0, - "unexpected kevent filter %d" _ event_list[i].filter); + "unexpected kevent() filter %d", + event_list[i].filter); } } + if (timer) { + ngx_event_expire_timers((ngx_msec_t) delta); + } + return NGX_OK; } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -107,6 +107,8 @@ struct ngx_event_s { #endif #if (HAVE_KQUEUE) + unsigned kq_vnode:1; + /* the pending errno reported by kqueue */ int kq_errno; #endif @@ -212,7 +214,7 @@ extern ngx_event_actions_t ngx_event_a /* * Need to add socket or handle only once - i/o completion port. - * It also requires HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT to be set. + * It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set. */ #define NGX_USE_IOCP_EVENT 0x00000100 @@ -233,6 +235,7 @@ extern ngx_event_actions_t ngx_event_a /* these flags have a meaning only for kqueue */ #define NGX_LOWAT_EVENT 0 #define NGX_DISABLE_EVENT 0 +#define NGX_VNODE_EVENT 0 #if (HAVE_KQUEUE) @@ -240,6 +243,9 @@ extern ngx_event_actions_t ngx_event_a #define NGX_READ_EVENT EVFILT_READ #define NGX_WRITE_EVENT EVFILT_WRITE +#undef NGX_VNODE_EVENT +#define NGX_VNODE_EVENT EVFILT_VNODE + /* * NGX_CLOSE_EVENT and NGX_LOWAT_EVENT are the module flags and they would * not go into a kernel so we need to choose the value that would not interfere @@ -289,7 +295,7 @@ extern ngx_event_actions_t ngx_event_a #endif /* HAVE_KQUEUE */ -#if (HAVE_IOCP_EVENT) +#if (HAVE_IOCP) #define NGX_IOCP_ACCEPT 0 #define NGX_IOCP_IO 1 #define NGX_IOCP_CONNECT 2 @@ -444,7 +450,8 @@ ngx_inline static int ngx_handle_write_e if (!wev->active && !wev->ready) { if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags) - == NGX_ERROR) { + == NGX_ERROR) + { return NGX_ERROR; } } @@ -457,7 +464,8 @@ ngx_inline static int ngx_handle_write_e if (!wev->active && !wev->ready) { if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) - == NGX_ERROR) { + == NGX_ERROR) + { return NGX_ERROR; } @@ -484,7 +492,8 @@ ngx_inline static int ngx_handle_level_w if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { if (!wev->active && !wev->ready) { if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) - == NGX_ERROR) { + == NGX_ERROR) + { return NGX_ERROR; } diff --git a/src/event/ngx_event_connect.h b/src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h +++ b/src/event/ngx_event_connect.h @@ -11,7 +11,7 @@ typedef struct { - u_int32_t addr; + in_addr_t addr; ngx_str_t host; int port; ngx_str_t addr_port_text; diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -8,15 +8,21 @@ protected by the single mutex */ +#if 0 static ngx_event_t *ngx_timer_queue, ngx_temp_timer_queue; +static int ngx_expire_timers; +#endif + +static ngx_event_t *ngx_timer_queue; +static ngx_msec_t *ngx_timer_delta; static int ngx_timer_cur_queue; static int ngx_timer_queue_num; -static int ngx_expire_timers; int ngx_event_timer_init(ngx_cycle_t *cycle) { - int i; + ngx_int_t i; + ngx_msec_t *new_delta; ngx_event_t *new_queue; ngx_event_conf_t *ecf; @@ -38,6 +44,21 @@ int ngx_event_timer_init(ngx_cycle_t *cy ngx_timer_queue = new_queue; + ngx_test_null(new_delta, + ngx_calloc(ecf->timer_queues * sizeof(ngx_msec_t), + cycle->log), + NGX_ERROR); + + for (i = 0; i < ngx_timer_queue_num; i++) { + new_delta[i] = ngx_timer_delta[i]; + } + + if (ngx_timer_delta) { + ngx_free(ngx_timer_delta); + } + + ngx_timer_delta = new_delta; + ngx_timer_queue_num = ecf->timer_queues; ngx_timer_cur_queue = 0; @@ -52,8 +73,10 @@ int ngx_event_timer_init(ngx_cycle_t *cy exit(1); } +#if 0 ngx_temp_timer_queue.timer_prev = &ngx_temp_timer_queue; ngx_temp_timer_queue.timer_next = &ngx_temp_timer_queue; +#endif return NGX_OK;; } @@ -63,6 +86,10 @@ void ngx_event_timer_done(ngx_cycle_t *c { ngx_free(ngx_timer_queue); ngx_timer_queue = NULL; + + ngx_free(ngx_timer_delta); + ngx_timer_delta = NULL; + ngx_timer_queue_num = 0; } @@ -89,6 +116,15 @@ void ngx_event_add_timer(ngx_event_t *ev return; } + queue = &ngx_timer_queue[ngx_timer_cur_queue]; + timer += ngx_timer_delta[ngx_timer_cur_queue++]; + + if (ngx_timer_cur_queue >= ngx_timer_queue_num) { + ngx_timer_cur_queue = 0; + } + + +#if 0 if (ngx_expire_timers) { queue = &ngx_temp_timer_queue; @@ -99,6 +135,7 @@ void ngx_event_add_timer(ngx_event_t *ev ngx_timer_cur_queue = 0; } } +#endif for (e = queue->timer_next; e != queue && timer > e->timer_delta; @@ -123,7 +160,7 @@ void ngx_event_add_timer(ngx_event_t *ev int ngx_event_find_timer(void) { - int i; + ngx_int_t i; ngx_msec_t timer; timer = NGX_MAX_MSEC; @@ -146,17 +183,34 @@ int ngx_event_find_timer(void) } +void ngx_event_set_timer_delta(ngx_msec_t timer) +{ + ngx_int_t i; + + for (i = 0; i < ngx_timer_queue_num; i++) { + ngx_timer_delta[i] = timer; + } +} + + +/* void ngx_event_expire_timers() */ void ngx_event_expire_timers(ngx_msec_t timer) { - int i; + ngx_int_t i; +#if 0 ngx_msec_t delta; +#endif ngx_event_t *ev; +#if 0 ngx_expire_timers = 1; +#endif for (i = 0; i < ngx_timer_queue_num; i++) { +#if 0 delta = timer; +#endif for ( ;; ) { ev = ngx_timer_queue[i].timer_next; @@ -165,12 +219,21 @@ void ngx_event_expire_timers(ngx_msec_t break; } + if (ev->timer_delta > ngx_timer_delta[i]) { + ev->timer_delta -= ngx_timer_delta[i]; + break; + } + + ngx_timer_delta[i] -= ev->timer_delta; + +#if 0 if (ev->timer_delta > delta) { ev->timer_delta -= delta; break; } delta -= ev->timer_delta; +#endif ngx_del_timer(ev); @@ -186,8 +249,11 @@ void ngx_event_expire_timers(ngx_msec_t ev->event_handler(ev); } + + ngx_timer_delta[i] = 0; } +#if 0 ngx_expire_timers = 0; if (ngx_temp_timer_queue.timer_next == &ngx_temp_timer_queue) { @@ -207,4 +273,5 @@ void ngx_event_expire_timers(ngx_msec_t ngx_del_timer(ev); ngx_add_timer(ev, timer); } +#endif } diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -11,6 +11,7 @@ int ngx_event_timer_init(ngx_cycle_t *c void ngx_event_timer_done(ngx_cycle_t *cycle); void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer); int ngx_event_find_timer(void); +void ngx_event_set_timer_delta(ngx_msec_t timer); void ngx_event_expire_timers(ngx_msec_t timer); diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c deleted file mode 100644 --- a/src/event/ngx_event_write.c +++ /dev/null @@ -1,203 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in, off_t flush) -{ - int rc, i, last; - u_int flags; - char *prev; - off_t sent; - ngx_iovec_t *iov; - ngx_array_t *header, *trailer; - ngx_hunk_t *file; - ngx_chain_t *ch; - - ch = in; - file = NULL; - last = 0; - - ngx_test_null(header, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)), - (ngx_chain_t *) -1); - - ngx_test_null(trailer, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)), - (ngx_chain_t *) -1); - - do { - header->nelts = 0; - trailer->nelts = 0; - - if (ch->hunk->type & NGX_HUNK_IN_MEMORY) { - prev = NULL; - iov = NULL; - - while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY)) - { - if (prev == ch->hunk->pos.mem) { - iov->ngx_iov_len += ch->hunk->last.mem - ch->hunk->pos.mem; - - } else { - ngx_test_null(iov, ngx_push_array(header), - (ngx_chain_t *) -1); - iov->ngx_iov_base = ch->hunk->pos.mem; - iov->ngx_iov_len = ch->hunk->last.mem - ch->hunk->pos.mem; - prev = ch->hunk->last.mem; - } - - if (ch->hunk->type & NGX_HUNK_LAST) { - last = 1; - } - - ch = ch->next; - } - } - - if (ch && (ch->hunk->type & NGX_HUNK_FILE)) { - file = ch->hunk; - ch = ch->next; - - if (ch->hunk->type & NGX_HUNK_LAST) { - last = 1; - } - } - -#if (HAVE_MAX_SENDFILE_IOVEC) - if (file && header->nelts > HAVE_MAX_SENDFILE_IOVEC) { - rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, header->nelts, - &sent); - } else { -#endif - if (ch && ch->hunk->type & NGX_HUNK_IN_MEMORY) { - prev = NULL; - iov = NULL; - - while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY)) { - - if (prev == ch->hunk->pos.mem) { - iov->ngx_iov_len += - ch->hunk->last.mem - ch->hunk->pos.mem; - - } else { - ngx_test_null(iov, ngx_push_array(trailer), - (ngx_chain_t *) -1); - iov->ngx_iov_base = ch->hunk->pos.mem; - iov->ngx_iov_len = - ch->hunk->last.mem - ch->hunk->pos.mem; - prev = ch->hunk->last.mem; - } - - if (ch->hunk->type & NGX_HUNK_LAST) { - last = 1; - } - - ch = ch->next; - } - } - - if (file) { - flags = ngx_sendfile_flags; -#if (HAVE_SENDFILE_DISCONNECT) - if (last && c->close) { - flags |= HAVE_SENDFILE_DISCONNECT; - } -#endif - rc = ngx_sendfile(c, - (ngx_iovec_t *) header->elts, header->nelts, - file->file->fd, file->pos.file, - (size_t) (file->last.file - file->pos.file), - (ngx_iovec_t *) trailer->elts, trailer->nelts, - &sent, flags); - -#if (HAVE_AIO_EVENT) && !(HAVE_IOCP_EVENT) - } else if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { - - sent = 0; - rc = NGX_AGAIN; - iov = (ngx_iovec_t *) header->elts; - for (i = 0; i < header->nelts; i++) { - rc = ngx_event_aio_write(c, iov[i].ngx_iov_base, - iov[i].ngx_iov_len); - - if (rc > 0) { - sent += rc; - } else { - break; - } - - if (rc < (int) iov->ngx_iov_len) { - break; - } - } -#endif - } else { - rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts); - - sent = rc > 0 ? rc: 0; - -#if (NGX_DEBUG_EVENT_WRITE) - ngx_log_debug(c->log, "sendv: " OFF_FMT _ sent); -#endif - } -#if (HAVE_MAX_SENDFILE_IOVEC) - } -#endif - if (rc == NGX_ERROR) - return (ngx_chain_t *) NGX_ERROR; - - c->sent += sent; - flush -= sent; - - for (ch = in; ch; ch = ch->next) { - -#if (NGX_DEBUG_EVENT_WRITE) - ngx_log_debug(c->log, "event write: %x " QX_FMT " " OFF_FMT _ - ch->hunk->type _ - ch->hunk->pos.file _ - ch->hunk->last.file - ch->hunk->pos.file); -#endif - - if (sent >= ch->hunk->last.file - ch->hunk->pos.file) { - sent -= ch->hunk->last.file - ch->hunk->pos.file; - ch->hunk->pos.file = ch->hunk->last.file; - -#if (NGX_DEBUG_EVENT_WRITE) - ngx_log_debug(c->log, "event write: " QX_FMT " 0 " OFF_FMT _ - ch->hunk->pos.file _ sent); -#endif - -/* - if (ch->hunk->type & NGX_HUNK_LAST) - break; -*/ - - continue; - } - - ch->hunk->pos.file += sent; - -#if (NGX_DEBUG_EVENT_WRITE) - ngx_log_debug(c->log, "event write: " QX_FMT " " OFF_FMT _ - ch->hunk->pos.file _ - ch->hunk->last.file - ch->hunk->pos.file); -#endif - - break; - } - - /* flush hunks if threaded state */ - } while (c->write->context && flush > 0); - - ngx_destroy_array(trailer); - ngx_destroy_array(header); - - return ch; -} diff --git a/src/event/ngx_event_write.h b/src/event/ngx_event_write.h deleted file mode 100644 --- a/src/event/ngx_event_write.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _NGX_EVENT_WRITE_H_INCLUDED_ -#define _NGX_EVENT_WRITE_H_INCLUDED_ - - -#include -#include -#include - -ngx_chain_t *ngx_event_write(ngx_connection_t *cn, ngx_chain_t *in, - off_t flush); - - -#endif /* _NGX_EVENT_WRITE_H_INCLUDED_ */ diff --git a/src/event/ngx_event_wsarecv.c b/src/event/ngx_event_wsarecv.c --- a/src/event/ngx_event_wsarecv.c +++ b/src/event/ngx_event_wsarecv.c @@ -32,7 +32,7 @@ ssize_t ngx_event_wsarecv(ngx_connection if (ev->ready) { ev->ready = 0; -#if (HAVE_IOCP_EVENT) /* iocp */ +#if (HAVE_IOCP) /* iocp */ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { if (ev->ovlp.error) { @@ -85,7 +85,7 @@ ssize_t ngx_event_wsarecv(ngx_connection } } -#if (HAVE_IOCP_EVENT) /* iocp */ +#if (HAVE_IOCP) /* iocp */ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { return NGX_AGAIN; diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c --- a/src/http/modules/ngx_http_chunked_filter.c +++ b/src/http/modules/ngx_http_chunked_filter.c @@ -87,7 +87,7 @@ static int ngx_http_chunked_body_filter( } ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR); - len = ngx_snprintf(chunk, 11, SIZEX_FMT CRLF, size); + len = ngx_snprintf(chunk, 11, SIZE_T_X_FMT CRLF, size); ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; diff --git a/src/http/modules/ngx_http_not_modified_filter.c b/src/http/modules/ngx_http_not_modified_filter.c --- a/src/http/modules/ngx_http_not_modified_filter.c +++ b/src/http/modules/ngx_http_not_modified_filter.c @@ -58,11 +58,13 @@ static int ngx_http_not_modified_header_ if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) { r->headers_out.status = NGX_HTTP_NOT_MODIFIED; + r->headers_out.content_type->key.len = 0; + r->headers_out.content_type = NULL; r->headers_out.content_length_n = -1; r->headers_out.content_length = NULL; - r->headers_out.content_type->key.len = 0; - r->headers_out.content_type = NULL; +#if 0 r->headers_out.accept_ranges->key.len = 0; +#endif } return ngx_http_next_header_filter(r); diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c --- a/src/http/modules/ngx_http_range_filter.c +++ b/src/http/modules/ngx_http_range_filter.c @@ -215,7 +215,7 @@ static int ngx_http_range_header_filter( r->headers_out.content_range->value.len = ngx_snprintf(r->headers_out.content_range->value.data, - 8 + 20 + 1, "bytes */" OFF_FMT, + 8 + 20 + 1, "bytes */" OFF_T_FMT, r->headers_out.content_length_n); r->headers_out.content_length_n = -1; @@ -247,11 +247,11 @@ static int ngx_http_range_header_filter( /* "Content-Range: bytes SSSS-EEEE/TTTT" header */ r->headers_out.content_range->value.len = - ngx_snprintf(r->headers_out.content_range->value.data, - 6 + 20 + 1 + 20 + 1 + 20 + 1, - "bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT, - range->start, range->end - 1, - r->headers_out.content_length_n); + ngx_snprintf(r->headers_out.content_range->value.data, + 6 + 20 + 1 + 20 + 1 + 20 + 1, + "bytes " OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT, + range->start, range->end - 1, + r->headers_out.content_length_n); r->headers_out.content_length_n = range->end - range->start; @@ -336,11 +336,11 @@ static int ngx_http_range_header_filter( /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */ range[i].content_range.len = - ngx_snprintf(range[i].content_range.data, - 20 + 1 + 20 + 1 + 20 + 5, - OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF, - range[i].start, range[i].end - 1, - r->headers_out.content_length_n); + ngx_snprintf(range[i].content_range.data, + 20 + 1 + 20 + 1 + 20 + 5, + OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT CRLF CRLF, + range[i].start, range[i].end - 1, + r->headers_out.content_length_n); len += ctx->boundary_header.len + range[i].content_range.len + (size_t) (range[i].end - range[i].start); diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -44,6 +44,8 @@ int ngx_http_static_translate_handler(ng int rc, level; char *location, *last; ngx_err_t err; + ngx_http_cache_ctx_t ctx; + ngx_http_cache_conf_t *ccf; ngx_http_core_loc_conf_t *clcf; if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { @@ -73,7 +75,7 @@ int ngx_http_static_translate_handler(ng return NGX_HTTP_FORBIDDEN; } - /* "+ 2" is for trailing '/' in redirect and '\0' */ + /* "+ 2" is for trailing '/' in possible redirect and '\0' */ ngx_test_null(r->file.name.data, ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2), NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -85,6 +87,38 @@ int ngx_http_static_translate_handler(ng ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data); + + /* STUB */ + ccf = NULL; + ctx.key.len = 0; + +#if 0 + ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module); + + if (ccf->open_files) { + ctx->hash = ccf->open_files; + ctx->key = r->file.name; + + cache = ngx_http_cache_get_data(r, ctx); + + if (cache + && ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) + || ccf->hash->life_time >= ngx_time() - cache->updated)) + { + cache->refs++; + r->file.fd = cache->fd; + r->file.name = cache->key; + r->content_handler = ngx_http_static_handler; + + return NGX_OK; + } + + } else { + cache = NULL; + } + +#endif + #if (WIN9X) if (ngx_win32_version < NGX_WIN_NT) { diff --git a/src/http/modules/proxy/ngx_http_proxy_cache.c b/src/http/modules/proxy/ngx_http_proxy_cache.c --- a/src/http/modules/proxy/ngx_http_proxy_cache.c +++ b/src/http/modules/proxy/ngx_http_proxy_cache.c @@ -86,6 +86,7 @@ static int ngx_http_proxy_process_cached } if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) { + p->state->expired = ngx_time() - p->cache->ctx.expires; p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { @@ -487,6 +488,8 @@ int ngx_http_proxy_send_cached_response( out[i].hunk->type |= NGX_HUNK_LAST; } + r->file.fd = p->cache->ctx.file.fd; + return ngx_http_output_filter(r, out); } @@ -600,7 +603,7 @@ int ngx_http_proxy_update_cache(ngx_http ep = p->upstream->event_pipe; -ngx_log_debug(p->request->connection->log, "LEN: " OFF_FMT ", " OFF_FMT _ +ngx_log_debug(p->request->connection->log, "LEN: " OFF_T_FMT ", " OFF_T_FMT _ p->cache->ctx.length _ ep->read_length); if (p->cache->ctx.length == -1) { diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -485,6 +485,10 @@ ngx_log_debug(r->connection->log, "CACHE r->file.fd = p->cache->ctx.file.fd; } + if (rc == 0 && r->main == NULL) { + rc = ngx_http_send_last(r); + } + ngx_http_finalize_request(r, rc); } @@ -586,15 +590,25 @@ static char *ngx_http_proxy_log_proxy_st *buf++ = '/'; - *buf++ = '_'; + if (p->state->expired == 0) { + *buf++ = '-'; + + } else { + buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expired); + } *buf++ = '/'; - *buf++ = '_'; + if (p->state->bl_time == 0) { + *buf++ = '-'; + + } else { + buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->bl_time); + } *buf++ = '/'; - *buf++ = '_'; + *buf++ = '*'; *buf++ = ' '; @@ -617,15 +631,15 @@ static char *ngx_http_proxy_log_proxy_st *buf++ = '/'; - if (p->state->reason >= NGX_HTTP_PROXY_CACHE_XAE) { + if (p->state->reason < NGX_HTTP_PROXY_CACHE_XAE) { *buf++ = '-'; } else { - buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_FMT, p->state->expires); + buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expires); } *buf++ = ' '; - *buf++ = '_'; + *buf++ = '*'; return buf; } @@ -833,9 +847,9 @@ static char *ngx_http_proxy_set_pass(ngx int i, len; char *err, *host; + in_addr_t addr; ngx_str_t *value; struct hostent *h; - u_int32_t addr; ngx_http_conf_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; @@ -869,6 +883,8 @@ static char *ngx_http_proxy_set_pass(ngx NGX_CONF_ERROR); ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1); + /* AF_INET only */ + addr = inet_addr(host); if (addr == INADDR_NONE) { @@ -894,7 +910,7 @@ static char *ngx_http_proxy_set_pass(ngx for (i = 0; h->h_addr_list[i] != NULL; i++) { lcf->peers->peers[i].host.data = host; lcf->peers->peers[i].host.len = lcf->upstream->host.len; - lcf->peers->peers[i].addr = *(u_int32_t *)(h->h_addr_list[i]); + lcf->peers->peers[i].addr = *(in_addr_t *)(h->h_addr_list[i]); lcf->peers->peers[i].port = lcf->upstream->port; len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1; diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -1017,8 +1017,7 @@ static void ngx_http_proxy_send_response ep->hunk_to_file->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; if (ngx_event_flags & NGX_USE_AIO_EVENT) { - - /* the posted aio operation can currupt shadow buf */ + /* the posted aio operation can currupt a shadow buffer */ ep->single_buf = 1; } @@ -1126,26 +1125,38 @@ static void ngx_http_proxy_process_body( } if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { + ngx_log_debug(ev->log, "http proxy upstream exit"); ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock); - ngx_http_proxy_close_connection(p); + ngx_http_proxy_finalize_request(p, 0); + return; } } + if (ep->downstream_error) { + ngx_log_debug(ev->log, "http proxy downstream error"); + if (!p->cachable && p->upstream->peer.connection) { + ngx_http_proxy_finalize_request(p, 0); + } + } + +#if 0 if (ep->downstream_done) { ngx_log_debug(ev->log, "http proxy downstream done"); - ngx_http_proxy_finalize_request(p, r->main ? 0 : ngx_http_send_last(r)); + ngx_http_proxy_finalize_request(p, 0); return; } if (ep->downstream_error) { + ngx_log_debug(ev->log, "http proxy downstream error"); if (!p->cachable && p->upstream->peer.connection) { ngx_http_proxy_close_connection(p); } if (p->upstream->peer.connection == NULL) { - ngx_http_close_connection(r->connection); + ngx_http_close_request(r); } } +#endif } diff --git a/src/http/ngx_http_busy_lock.c b/src/http/ngx_http_busy_lock.c --- a/src/http/ngx_http_busy_lock.c +++ b/src/http/ngx_http_busy_lock.c @@ -205,7 +205,7 @@ char *ngx_http_set_busy_lock_slot(ngx_co dup = 0; invalid = 0; - value = (ngx_str_t *) cf->args->elts; + value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c --- a/src/http/ngx_http_cache.c +++ b/src/http/ngx_http_cache.c @@ -13,11 +13,45 @@ #endif +static int ngx_crc(char *data, size_t len); + +static void *ngx_http_cache_create_conf(ngx_conf_t *cf); +static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child); + + +static ngx_http_module_t ngx_http_cache_module_ctx = { + NULL, /* pre conf */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_cache_create_conf, /* create location configuration */ + ngx_http_core_merge_loc_conf /* merge location configuration */ +}; + + +ngx_module_t ngx_http_cache_module = { + NGX_MODULE, + &ngx_http_cache_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init module */ + NULL /* init child */ +}; + + + int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) { MD5_CTX md5; - ctx->header_size = sizeof(ngx_http_cache_header_t) + ctx->key.len + 1; + /* we use offsetof() because sizeof() pads struct size to int size */ + ctx->header_size = offsetof(ngx_http_cache_header_t, key) + + ctx->key.len + 1; ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32; if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) { @@ -46,7 +80,83 @@ ngx_log_debug(r->connection->log, "FILE: } -/* TODO: Win32 inode analogy */ +int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) +{ + ngx_uint_t n, i; + + ctx->crc = ngx_crc(ctx->key.data, ctx->key.len); + + n = ctx->crc % ctx->hash->hash; + for (i = 0; i < ctx->hash->nelts; i++) { + if (ctx->hash->cache[n][i].crc == ctx->crc + && ctx->hash->cache[n][i].key.len == ctx->key.len + && ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data, + ctx->key.len) == 0) + { + ctx->cache = ctx->hash->cache[n][i].data; + ctx->hash->cache[n][i].refs++; + return NGX_OK; + } + } + + return NGX_DECLINED; +} + + +ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r, + ngx_http_cache_ctx_t *ctx) +{ + time_t old; + ngx_uint_t n, i; + ngx_http_cache_entry_t *ce; + + old = ngx_time() + 1; + ce = NULL; + + n = ctx->crc % ctx->hash->hash; + for (i = 0; i < ctx->hash->nelts; i++) { + if (ctx->hash->cache[n][i].key.data == NULL) { + + /* a free entry is found */ + + ce = &ctx->hash->cache[n][i]; + break; + } + + if (ctx->hash->cache[n][i].refs == 0 + && old > ctx->hash->cache[n][i].accessed) + { + /* looking for the oldest cache entry that is not used right now */ + + old = ctx->hash->cache[n][i].accessed; + ce = &ctx->hash->cache[n][i]; + } + } + + if (ce) { + if (ce->key.data) { + if (ctx->key.len > ce->key.len) { + ngx_free(ce->key.data); + ce->key.data = NULL; + } + } + + if (ce->key.data) { + ce->key.data = ngx_alloc(ctx->key.len, r->connection->log); + if (ce->key.data == NULL) { + return NULL; + } + } + + ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len); + + ce->key.len = ctx->key.len; + ce->crc = ctx->crc; + } + + return ce; +} + int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) { @@ -138,6 +248,48 @@ ngx_log_debug(ctx->log, "EXPIRED"); } +int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, + ngx_str_t *temp_file) +{ + int retry; + ngx_err_t err; + + retry = 0; + + for ( ;; ) { + if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) { + return NGX_OK; + } + + err = ngx_errno; + +#if (WIN32) + if (err == NGX_EEXIST) { + if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool) + == NGX_ERROR) + { + return NGX_ERROR; + } + } +#endif + + if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, + ngx_rename_file_n "(\"%s\", \"%s\") failed", + temp_file->data, ctx->file.name.data); + + return NGX_ERROR; + } + + if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) { + return NGX_ERROR; + } + + retry = 1; + } +} + + int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, ngx_dir_t *dir) { @@ -182,45 +334,69 @@ int ngx_garbage_collector_http_cache_han } -int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, - ngx_str_t *temp_file) +/* 32-bit crc16 */ + +static int ngx_crc(char *data, size_t len) { - int retry; - ngx_err_t err; + uint32_t sum; + + for (sum = 0; len; len--) { + /* + * gcc 2.95.2 x86 and icc 7.1.006 compile that operator + * into the single rol opcode. + * msvc 6.0sp2 compiles it into four opcodes. + */ + sum = sum >> 1 | sum << 31; - retry = 0; + sum += *data++; + } + + return sum; +} + + +static void *ngx_http_cache_create_conf(ngx_conf_t *cf) +{ + ngx_http_cache_conf_t *conf; + + if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_conf_t)))) { + return NGX_CONF_ERROR; + } - for ( ;; ) { - if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) { - return NGX_OK; - } + return conf; +} + - err = ngx_errno; +static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child) +{ + ngx_http_cache_conf_t *prev = parent; + ngx_http_cache_conf_t *conf = child; + + if (conf->hash == NULL) { + if (prev->hash) { + conf->hash = prev->hash; -#if (WIN32) - if (err == NGX_EEXIST) { - if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool) - == NGX_ERROR) - { - return NGX_ERROR; + } else { + conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t)); + if (conf->hash == NULL) { + return NGX_CONF_ERROR; + } + + conf->hash->hash = NGX_HTTP_CACHE_HASH; + conf->hash->nelts = NGX_HTTP_CACHE_NELTS; + + conf->hash->cache = ngx_pcalloc(cf->pool, + NGX_HTTP_CACHE_HASH + * NGX_HTTP_CACHE_NELTS + * sizeof(ngx_http_cache_entry_t)); + if (conf->hash->cache == NULL) { + return NGX_CONF_ERROR; } } -#endif - - if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) { - ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_rename_file_n "(\"%s\", \"%s\") failed", - temp_file->data, ctx->file.name.data); + } - return NGX_ERROR; - } - - if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) { - return NGX_ERROR; - } - - retry = 1; - } + return NGX_CONF_OK; } @@ -261,7 +437,7 @@ typedef struct { typedef struct { - u_int32_t crc; + uint32_t crc; ngx_str_t uri; ngx_http_cache_t *cache; } ngx_http_cache_hash_entry_t; @@ -269,7 +445,7 @@ typedef struct { typedef struct { ngx_http_cache_t *cache; - u_int32_t crc; + uint32_t crc; int n; } ngx_http_cache_handle_t; @@ -305,7 +481,7 @@ int ngx_http_cache_get(ngx_http_cache_ha int ngx_crc(char *data, size_t len) { - u_int32_t sum; + uint32_t sum; for (sum = 0; len; len--) { /* diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -18,32 +18,52 @@ typedef struct { typedef struct { - u_int32_t crc; + uint32_t crc; ngx_str_t key; ngx_fd_t fd; off_t size; void *data; /* mmap, memory */ time_t accessed; time_t last_modified; - time_t updated; /* no needed with kqueue */ + time_t updated; /* no needed with kqueue */ int refs; int flags; } ngx_http_cache_entry_t; +#define NGX_HTTP_CACHE_HASH 1021 +#define NGX_HTTP_CACHE_NELTS 4 + +typedef struct { + ngx_http_cache_entry_t **cache; + size_t hash; + size_t nelts; + time_t life_time; + time_t check_time; + ngx_pool_t *pool; +} ngx_http_cache_hash_t; + typedef struct { - ngx_file_t file; - ngx_str_t key; - u_char md5[16]; - ngx_path_t *path; - ngx_hunk_t *buf; - time_t expires; - time_t last_modified; - time_t date; - off_t length; - ssize_t header_size; - size_t file_start; - ngx_log_t *log; + ngx_http_cache_hash_t *hash; +} ngx_http_cache_conf_t; + + +typedef struct { + ngx_http_cache_hash_t *hash; + ngx_http_cache_entry_t *cache; + ngx_file_t file; + ngx_str_t key; + uint32_t crc; + u_char md5[16]; + ngx_path_t *path; + ngx_hunk_t *buf; + time_t expires; + time_t last_modified; + time_t date; + off_t length; + ssize_t header_size; + size_t file_start; + ngx_log_t *log; } ngx_http_cache_ctx_t; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -88,7 +88,7 @@ static ngx_command_t ngx_http_core_comm NULL}, {ngx_string("location"), - NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_location_block, NGX_HTTP_SRV_CONF_OFFSET, 0, @@ -368,19 +368,27 @@ static void ngx_http_run_phases(ngx_http int ngx_http_find_location_config(ngx_http_request_t *r) { - int i, rc; + ngx_int_t i, rc, exact; ngx_str_t *auto_redirect; ngx_http_core_loc_conf_t *clcf, **clcfp; ngx_http_core_srv_conf_t *cscf; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); auto_redirect = NULL; + exact = 0; clcfp = cscf->locations.elts; for (i = 0; i < cscf->locations.nelts; i++) { -#if 0 -ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); + +#if 1 +ngx_log_debug(r->connection->log, "trans: %s: %d" _ + clcfp[i]->name.data _ clcfp[i]->exact_match); #endif + + if (clcfp[i]->regex) { + break; + } + if (clcfp[i]->auto_redirect && r->uri.len == clcfp[i]->name.len - 1 && ngx_strncmp(r->uri.data, clcfp[i]->name.data, @@ -406,6 +414,50 @@ ngx_log_debug(r->connection->log, "trans clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); r->connection->log->file = clcf->err_log->file; r->connection->log->log_level = clcf->err_log->log_level; + + if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { + exact = 1; + break; + } + } + } + + if (!exact && !auto_redirect) { + /* regex matches */ + + for (/* void */; i < cscf->locations.nelts; i++) { + +#if 1 +ngx_log_debug(r->connection->log, "trans: %s: %d" _ + clcfp[i]->name.data _ clcfp[i]->exact_match); +#endif + + if (!clcfp[i]->regex) { + continue; + } + + rc = ngx_regex_exec(clcfp[i]->regex, &r->uri); + + if (rc == NGX_DECLINED) { + continue; + } + + if (rc < 0) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_regex_exec_n + " failed: %d on \"%s\" using \"%s\"", + rc, r->uri.data, clcfp[i]->name.data); + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + /* match */ + + r->loc_conf = clcfp[i]->loc_conf; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + r->connection->log->file = clcf->err_log->file; + r->connection->log->log_level = clcf->err_log->log_level; + + break; } } @@ -669,37 +721,58 @@ static char *ngx_server_block(ngx_conf_t } -static int ngx_cmp_locations(const void *first, const void *second) +static int ngx_cmp_locations(const void *one, const void *two) { - ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first; - ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second; + ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one; + ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two; + + ngx_int_t rc; + + if (first->regex && !second->regex) { + /* shift regex matches to the end */ + return 1; + } - return ngx_strcmp(one->name.data, two->name.data); + if (first->regex || second->regex) { + /* do not sort regex matches */ + return 0; + } + + rc = ngx_strcmp(first->name.data, second->name.data); + + if (rc == 0 && second->exact_match) { + /* an exact match must be before the same inclusive one */ + return 1; + } + + return rc; } static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { - int m; char *rv; - ngx_str_t *location; + ngx_int_t m; + ngx_str_t *value, err; ngx_http_module_t *module; ngx_conf_t pvcf; ngx_http_conf_ctx_t *ctx, *pvctx; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf, **clcfp; + char errstr[NGX_MAX_CONF_ERRSTR]; - ngx_test_null(ctx, - ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), - NGX_CONF_ERROR); + if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { + return NGX_CONF_ERROR; + } pvctx = (ngx_http_conf_ctx_t *) cf->ctx; ctx->main_conf = pvctx->main_conf; ctx->srv_conf = pvctx->srv_conf; - ngx_test_null(ctx->loc_conf, - ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), - NGX_CONF_ERROR); + ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); + if (ctx->loc_conf == NULL) { + return NGX_CONF_ERROR; + } for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { @@ -709,20 +782,61 @@ static char *ngx_location_block(ngx_conf module = ngx_modules[m]->ctx; if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], - module->create_loc_conf(cf), - NGX_CONF_ERROR); + ctx->loc_conf[ngx_modules[m]->ctx_index] = + module->create_loc_conf(cf); + if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) { + return NGX_CONF_ERROR; + } } } clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; - location = (ngx_str_t *) cf->args->elts; - clcf->name.len = location[1].len; - clcf->name.data = location[1].data; clcf->loc_conf = ctx->loc_conf; + value = (ngx_str_t *) cf->args->elts; + + if (cf->args->nelts == 3) { + if (value[1].len == 1 && value[1].data[0] == '=') { + clcf->name.len = value[2].len; + clcf->name.data = value[2].data; + clcf->exact_match = 1; + + } else if ((value[1].len == 1 && value[1].data[0] == '~') + || (value[1].len == 2 + && value[1].data[0] == '~' + && value[1].data[1] == '*')) + { + err.len = NGX_MAX_CONF_ERRSTR; + err.data = errstr; + + clcf->regex = ngx_regex_compile(&value[2], + value[1].len == 2 ? NGX_REGEX_CASELESS: 0, + cf->pool, &err); + + if (clcf->regex == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); + return NGX_CONF_ERROR; + } + + clcf->name.len = value[2].len; + clcf->name.data = value[2].data; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid location modifier \"%s\"", + value[1].data); + return NGX_CONF_ERROR; + } + + } else { + clcf->name.len = value[1].len; + clcf->name.data = value[1].data; + } + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; - ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR); + if (!(clcfp = ngx_push_array(&cscf->locations))) { + return NGX_CONF_ERROR; + } *clcfp = clcf; pvcf = *cf; @@ -911,6 +1025,10 @@ static void *ngx_http_core_create_loc_co lcf->err_log = NULL; lcf->error_pages = NULL; + lcf->regex = NULL; + lcf->exact_match = 0; + lcf->auto_redirect = 0; + */ lcf->client_body_timeout = NGX_CONF_UNSET; @@ -1079,7 +1197,7 @@ static char *ngx_set_listen(ngx_conf_t * return NGX_CONF_ERROR; } - ls->addr = *(u_int32_t *)(h->h_addr_list[0]); + ls->addr = *(in_addr_t *)(h->h_addr_list[0]); } return NGX_CONF_OK; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -8,7 +8,7 @@ typedef struct { - u_int32_t addr; + in_addr_t addr; int port; int family; int flags; /* 'default' */ @@ -65,7 +65,7 @@ typedef struct { typedef struct { - u_int32_t addr; + in_addr_t addr; ngx_array_t names; /* array of ngx_http_server_name_t */ ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf for this address:port */ @@ -128,6 +128,10 @@ typedef struct { int msie_padding; /* msie_padding */ ngx_array_t *error_pages; /* error_page */ + ngx_regex_t *regex; + + unsigned exact_match:1; + unsigned auto_redirect:1; ngx_log_t *err_log; diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -266,7 +266,7 @@ static int ngx_http_header_filter(ngx_ht #endif h->last += ngx_snprintf(h->last, /* 2^64 */ sizeof("Content-Length: 18446744073709551616" CRLF), - "Content-Length: " OFF_FMT CRLF, + "Content-Length: " OFF_T_FMT CRLF, r->headers_out.content_length_n); #if (NGX_HTTP_LOG_ALL_HEADERS_OUT) diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -250,7 +250,7 @@ static char *ngx_http_log_status(ngx_htt static char *ngx_http_log_length(ngx_http_request_t *r, char *buf, uintptr_t data) { - return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_FMT, + return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_T_FMT, r->connection->sent); } diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -82,7 +82,7 @@ int ngx_open_dir(ngx_str_t *name, ngx_di #define ngx_read_dir_n "readdir()" -#define ngx_create_dir(name) mkdir(name, (mode_t) 0700) +#define ngx_create_dir(name) mkdir(name, 0700) #define ngx_create_dir_n "mkdir()" diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -3,7 +3,7 @@ #include -#include /* offsetof */ +#include /* offsetof() */ #include #include #include @@ -27,35 +27,6 @@ #include - -/* TODO: autoconf */ -#if (i386) - -#if 0 -#define OFF_FMT "%lld" -#endif - -#define SIZE_FMT "%d" -#define SIZEX_FMT "%x" - -#else /* amd64, alpha, sparc64, ia64 */ - -#if 0 -#define OFF_FMT "%ld" -#endif - -#define SIZE_FMT "%ld" -#define SIZEX_FMT "%lx" - -#endif - -#if 0 -#define TIME_FMT "%ld" -#endif -#define PID_FMT "%d" -#define RLIM_FMT "%lld" - - #ifndef HAVE_SELECT #define HAVE_SELECT 1 #endif @@ -89,58 +60,11 @@ #endif -/* STUB */ -#define HAVE_PREAD 1 -#define HAVE_PWRITE 1 -#define HAVE_LOCALTIME_R 1 - - - /* FreeBSD sendfile */ - -#if __FreeBSD_version >= 300007 - -#ifndef HAVE_FREEBSD_SENDFILE -#define HAVE_FREEBSD_SENDFILE 1 -#endif - -#endif - - -#if (HAVE_FREEBSD_SENDFILE) -#define HAVE_SENDFILE 1 -#endif - - - /* FreeBSD kqueue */ - -#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \ - || __FreeBSD_version >= 500011 - -#ifndef HAVE_KQUEUE -#define HAVE_KQUEUE 1 -#endif - -#endif - #if (HAVE_KQUEUE) #include #endif - /* kqueue's NOTE_LOWAT */ - -#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \ - || __FreeBSD_version >= 500018 - -#ifndef HAVE_LOWAT_EVENT -#define HAVE_LOWAT_EVENT 1 -#endif - -#endif - - - - #ifndef HAVE_INHERITED_NONBLOCK #define HAVE_INHERITED_NONBLOCK 1 #endif diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -20,12 +20,12 @@ ngx_os_io_t ngx_os_io = { ngx_unix_recv, ngx_readv_chain, NULL, -#if (HAVE_FREEBSD_SENDFILE) +#if (HAVE_SENDFILE) ngx_freebsd_sendfile_chain, - NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY + NGX_HAVE_SENDFILE #else ngx_writev_chain, - NULL + 0 #endif }; @@ -97,7 +97,7 @@ int ngx_os_init(ngx_log_t *log) version, __FreeBSD_version); -#if (HAVE_FREEBSD_SENDFILE) +#if (HAVE_SENDFILE) /* * The determination of the sendfile() nbytes bug is complex enough. @@ -127,7 +127,7 @@ int ngx_os_init(ngx_log_t *log) #endif -#endif /* HAVE_FREEBSD_SENDFILE */ +#endif /* HAVE_SENDFILE */ if ((version < 500000 && version >= 440003) || version >= 500017) { diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -22,16 +22,17 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) { - int rc, eintr, eagain; + int rc; char *prev; off_t sent, fprev; size_t hsize, fsize, size; + ngx_int_t eintr, eagain; struct iovec *iov; struct sf_hdtr hdtr; ngx_err_t err; + ngx_hunk_t *file; ngx_array_t header, trailer; ngx_event_t *wev; - ngx_hunk_t *file; ngx_chain_t *cl, *tail; wev = c->write; @@ -53,7 +54,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( #endif do { - cl = in; file = NULL; fsize = 0; hsize = 0; @@ -156,7 +156,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( ngx_log_debug(c->log, "NOPUSH"); if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { - ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, ngx_tcp_nopush_n " failed"); return NGX_CHAIN_ERROR; } diff --git a/src/os/unix/ngx_linux.h b/src/os/unix/ngx_linux.h new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_linux.h @@ -0,0 +1,8 @@ +#ifndef _NGX_LINUX_H_INCLUDED_ +#define _NGX_LINUX_H_INCLUDED_ + + +ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) + + +#endif /* _NGX_LINUX_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -2,14 +2,14 @@ #define _NGX_LINUX_CONFIG_H_INCLUDED_ -#define _GNU_SOURCE /* pread, pwrite, gethostname, bzero */ +#define _GNU_SOURCE /* pread(), pwrite(), gethostname() */ #define _FILE_OFFSET_BITS 64 #define _LARGEFILE_SOURCE #include -#include /* offsetof */ +#include /* offsetof() */ #include #include #include @@ -27,16 +27,17 @@ #include #include #include +#include #include -#define OFF_FMT "%lld" +#if 0 #define SIZE_FMT "%d" #define SIZEX_FMT "%x" -#define TIME_FMT "%ld" #define PID_FMT "%d" #define RLIM_FMT "%lu" +#endif diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -1,183 +1,214 @@ #include #include -#include +#include ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) { - int rc, on, off; + int rc; char *prev; - size_t hsize, size; - ssize_t sent; + off_t fprev; + size_t size, fsize, sent; + ngx_int_t use_cork, eintr; struct iovec *iov; - struct sf_hdtr hdtr; ngx_err_t err; - ngx_array_t header, trailer; ngx_hunk_t *file; - ngx_chain_t *ce; + ngx_array_t header; + ngx_event_t *wev; + ngx_chain_t *cl; + + wev = c->write; - ce = in; - file = NULL; - hsize = 0; + if (!wev->ready) { + return in; + } + + cork = 0; - on = 1; - off = 0; + do { + file = NULL; + fsize = 0; + eintr = 0; - ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); - ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); + ngx_init_array(header, c->pool, 10, sizeof(struct iovec), + NGX_CHAIN_ERROR); - /* create the header iovec */ - if (ngx_hunk_in_memory_only(ce->hunk)) { prev = NULL; iov = NULL; - /* create the iovec and coalesce the neighbouring chain entries */ - while (ce && ngx_hunk_in_memory_only(ce->hunk)) { + /* create the iovec and coalesce the neighbouring hunks */ + + for (cl = in; cl; cl = cl->next) { + if (ngx_hunk_special(cl->hunk)) { + continue; + } - if (prev == ce->hunk->pos) { - iov->iov_len += ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; + if (!ngx_hunk_in_memory_only(cl->hunk)) { + break; + } + + if (prev == cl->hunk->pos) { + iov->iov_len += cl->hunk->last - cl->hunk->pos; } else { ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR); - iov->iov_base = ce->hunk->pos; - iov->iov_len = ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; - } - - if (ngx_freebsd_sendfile_nbytes_bug) { - hsize += ce->hunk->last - ce->hunk->pos; + iov->iov_base = cl->hunk->pos; + iov->iov_len = cl->hunk->last - cl->hunk->pos; } - ce = ce->next; - } - } - - /* TODO: coalesce the neighbouring file hunks */ - if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { - file = ce->hunk; - ce = ce->next; - } - - /* create the trailer iovec */ - if (ce && ngx_hunk_in_memory_only(ce->hunk)) { - prev = NULL; - iov = NULL; - - /* create the iovec and coalesce the neighbouring chain entries */ - while (ce && ngx_hunk_in_memory_only(ce->hunk)) { - - if (prev == ce->hunk->pos) { - iov->iov_len += ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; - - } else { - ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR); - iov->iov_base = ce->hunk->pos; - iov->iov_len = ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; - } - - ce = ce->next; - } - } - - if (file) { - if (setsockopt(c->fd, IPPROTO_TCP, TCP_CORK, - (const void *) &on, sizeof(int)) == -1) { - ngx_log_error(NGX_LOG_CRIT, c->log, err, - "setsockopt(TCP_CORK, 1) failed"); - return NGX_CHAIN_ERROR; + prev = cl->hunk->last; } - - rc = sendfile(c->fd, file->file->fd, file->file_pos, - (size_t) (file->file_last - file->file_pos)); + /* set TCP_CORK if there is a header before a file */ - if (rc == -1) { - err = ngx_errno; - if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EAGAIN"); + if (!c->tcp_nopush + && header.nelts != 0 + && cl + && cl->hunk->type & NGX_HUNK_FILE) + { + c->tcp_nopush = 1; - } else if (err == NGX_EINTR) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EINTR"); +ngx_log_debug(c->log, "CORK"); - } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfile() failed"); + if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, + ngx_tcp_nopush_n " failed"); return NGX_CHAIN_ERROR; } } - sent = rc > 0 ? rc : 0; + if (header.nelts == 0 && cl && cl->hunk->type & NGX_HUNK_FILE) { + + /* get the file hunk */ -#if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "sendfile: %d, @%qd %d:%d" _ - rc _ file->file_pos _ sent _ - (size_t) (file->file_last - file->file_pos)); -#endif + file = cl->hunk; + fsize = (size_t) (file->file_last - file->file_pos); + fprev = file->file_last; + cl = cl->next; - } else { - rc = writev(c->fd, (struct iovec *) header.elts, header.nelts); + /* coalesce the neighbouring file hunks */ - if (rc == -1) { - err = ngx_errno; - if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); + while (cl && (cl->hunk->type & NGX_HUNK_FILE)) { + if (file->file->fd != cl->hunk->file->fd + || fprev != cl->hunk->file_pos) + { + break; + } - } else if (err == NGX_EINTR) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); - - } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); - return NGX_CHAIN_ERROR; + fsize += (size_t) (cl->hunk->file_last - cl->hunk->file_pos); + fprev = cl->hunk->file_last; + cl = cl->next; } } - sent = rc > 0 ? rc : 0; + /* + * the tail is the rest of the chain that exceeded + * a single sendfile() capability + */ + + tail = cl; + + if (fsize) { + rc = sendfile(c->fd, file->file->fd, file->file_pos, fsize); + + if (rc == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, + "sendfile() EAGAIN"); + + } else if (err == NGX_EINTR) { + eintr = 1; + ngx_log_error(NGX_LOG_INFO, c->log, err, + "sendfile() EINTR"); + + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, + "sendfile() failed"); + return NGX_CHAIN_ERROR; + } + } + + sent = rc > 0 ? rc : 0; #if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "writev: %d" _ sent); + ngx_log_debug(c->log, "sendfile: %d, @" OFF_T_FMT " %d:%d" _ + rc _ file->file_pos _ sent _ fsize); #endif - } - - c->sent += sent; - - for (ce = in; ce && sent > 0; ce = ce->next) { + } else { + rc = writev(c->fd, header.elts, header.nelts); - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - size = ce->hunk->last - ce->hunk->pos; - } else { - size = ce->hunk->file_last - ce->hunk->file_pos; - } + if (rc == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); - if (sent >= size) { - sent -= size; + } else if (err == NGX_EINTR) { + eintr = 1; + ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - ce->hunk->pos = ce->hunk->last; + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); + return NGX_CHAIN_ERROR; + } } - if (ce->hunk->type & NGX_HUNK_FILE) { - ce->hunk->file_pos = ce->hunk->file_last; - } + sent = rc > 0 ? rc : 0; - continue; - } - - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - ce->hunk->pos += sent; +#if (NGX_DEBUG_WRITE_CHAIN) + ngx_log_debug(c->log, "writev: %d" _ sent); +#endif } - if (ce->hunk->type & NGX_HUNK_FILE) { - ce->hunk->file_pos += sent; + c->sent += sent; + + for (cl = in; cl; cl = cl->next) { + + if (ngx_hunk_special(cl->hunk)) { + continue; + } + + if (sent == 0) { + break; + } + + size = ngx_hunk_size(cl->hunk); + + if (sent >= size) { + sent -= size; + + if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { + cl->hunk->pos = cl->hunk->last; + } + + if (cl->hunk->type & NGX_HUNK_FILE) { + cl->hunk->file_pos = cl->hunk->file_last; + } + + continue; + } + + if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { + cl->hunk->pos += sent; + } + + if (cl->hunk->type & NGX_HUNK_FILE) { + cl->hunk->file_pos += sent; + } + + break; } - break; + in = cl; + + /* "tail == in" means that a single sendfile() is complete */ + + } while ((tail && tail == in) || eintr); + + if (in) { + wev->ready = 0; } - ngx_destroy_array(&trailer); - ngx_destroy_array(&header); - - return ce; + return in; } diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -56,7 +56,7 @@ int ngx_posix_init(ngx_log_t *log) } ngx_log_error(NGX_LOG_INFO, log, 0, - "getrlimit(RLIMIT_NOFILE): " RLIM_FMT ":" RLIM_FMT, + "getrlimit(RLIMIT_NOFILE): " RLIM_T_FMT ":" RLIM_T_FMT, rlmt.rlim_cur, rlmt.rlim_max); ngx_max_sockets = rlmt.rlim_cur; diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -41,9 +41,10 @@ int ngx_spawn_process(ngx_log_t *log) break; default: + break; } -ngx_log_debug(log, "parent process, child: " PID_FMT _ pid); +ngx_log_debug(log, "parent process, child: " PID_T_FMT _ pid); /* book keeping */ @@ -97,7 +98,7 @@ void ngx_sigchld_handler(int signo) one = 1; ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, - "process " PID_FMT " exited with code %d", pid, status); + "process " PID_T_FMT " exited with code %d", pid, status); /* TODO: restart handler */ diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c --- a/src/os/unix/ngx_socket.c +++ b/src/os/unix/ngx_socket.c @@ -55,6 +55,28 @@ int ngx_tcp_push(ngx_socket_t s) (const void *) &tcp_nopush, sizeof(int)); } +#elif __linux__ + +int ngx_tcp_nopush(ngx_socket_t s) +{ + int cork; + + cork = 1; + + return setsockopt(s, IPPROTO_TCP, TCP_CORK, + (const void *) &cork, sizeof(int)); +} + +int ngx_tcp_push(ngx_socket_t s) +{ + int cork; + + cork = 0; + + return setsockopt(s, IPPROTO_TCP, TCP_CORK, + (const void *) &cork, sizeof(int)); +} + #else int ngx_tcp_nopush(ngx_socket_t s) diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -29,11 +29,19 @@ int ngx_blocking(ngx_socket_t s); #endif int ngx_tcp_nopush(ngx_socket_t s); -#define ngx_tcp_nopush_n "setsockopt(TCP_NOPUSH)" +int ngx_tcp_push(ngx_socket_t s); + +#ifdef __linux__ -int ngx_tcp_push(ngx_socket_t s); +#define ngx_tcp_nopush_n "setsockopt(TCP_CORK)" +#define ngx_tcp_push_n "setsockopt(!TCP_CORK)" + +#else + +#define ngx_tcp_nopush_n "setsockopt(TCP_NOPUSH)" #define ngx_tcp_push_n "setsockopt(!TCP_NOPUSH)" +#endif #define ngx_shutdown_socket shutdown diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -10,7 +10,7 @@ #include #include -#include /* offsetof */ +#include /* offsetof() */ #include #include #include @@ -28,14 +28,14 @@ #include -typedef uint32_t u_int32_t; - +#if 0 #define OFF_FMT "%lld" #define SIZE_FMT "%d" #define SIZEX_FMT "%x" #define TIME_FMT "%ld" #define PID_FMT "%ld" #define RLIM_FMT "%lu" +#endif #ifndef HAVE_SELECT diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c --- a/src/os/unix/ngx_writev_chain.c +++ b/src/os/unix/ngx_writev_chain.c @@ -58,7 +58,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connec sent = n > 0 ? n : 0; #if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "writev: " OFF_FMT _ sent); + ngx_log_debug(c->log, "writev: " OFF_T_FMT _ sent); #endif c->sent += sent; diff --git a/src/os/win32/ngx_sendfile.c b/src/os/win32/ngx_sendfile.c --- a/src/os/win32/ngx_sendfile.c +++ b/src/os/win32/ngx_sendfile.c @@ -42,7 +42,7 @@ int ngx_sendfile(ngx_connection_t *c, if (ev->ready) { ev->ready = 0; -#if (HAVE_IOCP_EVENT) /* iocp */ +#if (HAVE_IOCP) /* iocp */ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { if (ev->ovlp.error) { diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -21,7 +21,7 @@ #include #include -#include /* offsetof */ +#include /* offsetof() */ #include #include #include @@ -41,6 +41,7 @@ #if 0 +/* owc have not __int32 */ typedef unsigned __int32 uint32_t; #else typedef unsigned int uint32_t; @@ -52,18 +53,16 @@ typedef u_int uintptr_t; typedef int ssize_t; typedef long time_t; typedef __int64 off_t; +typedef uint32_t in_addr_t; -#define OFF_FMT "%I64d" -#define SIZE_FMT "%d" -#define SIZEX_FMT "%x" -#define PID_FMT "%d" -#define TIME_FMT "%lu" +#define OFF_T_FMT "%I64d" +#define SIZE_T_FMT "%d" +#define SIZE_T_X_FMT "%x" +#define PID_T_FMT "%d" +#define TIME_T_FMT "%lu" -/* STUB */ -typedef uint32_t u_int32_t; - #ifndef HAVE_INHERITED_NONBLOCK #define HAVE_INHERITED_NONBLOCK 1