Dengine: change .gitignore file for submit lib dir(very stupid mistake)

This commit is contained in:
leon.li 2016-08-24 16:43:11 +08:00
parent f97919e1da
commit c924212e47
55 changed files with 9447 additions and 1 deletions

1
.gitignore vendored
View file

@ -31,7 +31,6 @@ timer_gdb.sh
# others
TestNoSubmit.java
lib
dump
dumpdata
dump.tar

View file

@ -0,0 +1,95 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
. auto/lib/pcre/conf
else
if [ $USE_PCRE = DISABLED -a $HTTP_REWRITE = YES ]; then
cat << END
$0: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option or you have to enable the PCRE support.
END
exit 1
fi
fi
if [ $USE_OPENSSL = YES ]; then
. auto/lib/openssl/conf
fi
if [ $USE_MD5 = YES ]; then
if [ $USE_OPENSSL = YES ]; then
have=NGX_HAVE_OPENSSL_MD5_H . auto/have
have=NGX_OPENSSL_MD5 . auto/have
have=NGX_HAVE_MD5 . auto/have
MD5=YES
MD5_LIB=OpenSSL
else
. auto/lib/md5/conf
fi
fi
if [ $USE_SHA1 = YES ]; then
if [ $USE_OPENSSL = YES ]; then
have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
have=NGX_HAVE_SHA1 . auto/have
SHA1=YES
SHA1_LIB=OpenSSL
else
. auto/lib/sha1/conf
fi
fi
if [ $USE_ZLIB = YES ]; then
. auto/lib/zlib/conf
fi
if [ $USE_LIBXSLT = YES ]; then
. auto/lib/libxslt/conf
fi
if [ $USE_LIBGD = YES ]; then
. auto/lib/libgd/conf
fi
if [ $USE_PERL = YES ]; then
. auto/lib/perl/conf
fi
if [ $HTTP_LUA = YES ] || [ $HTTP_LUA_SHARED = YES ]; then
. auto/lib/lua/conf
fi
if [ $HTTP_TFS = YES ] || [ $HTTP_TFS_SHARED = YES ]; then
. auto/lib/libyajl/conf
fi
if [ $HTTP_GEOIP = YES ] || [ $HTTP_GEOIP_SHARED = YES ]; then
. auto/lib/geoip/conf
fi
if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
. auto/lib/google-perftools/conf
fi
if [ $NGX_LIBATOMIC != NO ]; then
. auto/lib/libatomic/conf
fi
if [ $JEMALLOC != NO ]; then
. auto/lib/jemalloc/conf
fi

View file

@ -0,0 +1,97 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
ngx_feature="GeoIP library"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs="#include <GeoIP.h>"
ngx_feature_path=
ngx_feature_libs="-lGeoIP"
ngx_feature_test="GeoIP_open(NULL, 0)"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="GeoIP library in /usr/local/"
ngx_feature_path="/usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
else
ngx_feature_libs="-L/usr/local/lib -lGeoIP"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD port
ngx_feature="GeoIP library in /usr/pkg/"
ngx_feature_path="/usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
else
ngx_feature_libs="-L/usr/pkg/lib -lGeoIP"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="GeoIP library in /opt/local/"
ngx_feature_path="/opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lGeoIP"
else
ngx_feature_libs="-L/opt/local/lib -lGeoIP"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
if [ $HTTP_GEOIP_SHARED = YES ]; then
DSO_LIBS="$DSO_LIBS|$HTTP_GEOIP_MODULE:$ngx_feature_libs"
else
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
fi
if [ $NGX_IPV6 = YES ]; then
ngx_feature="GeoIP IPv6 support"
ngx_feature_name="NGX_HAVE_GEOIP_V6"
ngx_feature_run=no
ngx_feature_incs="#include <stdio.h>
#include <GeoIP.h>"
#ngx_feature_path=
#ngx_feature_libs=
ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
. auto/feature
fi
else
cat << END
$0: error: the GeoIP module requires the GeoIP library.
You can either do not enable the module or install the library.
END
exit 1
fi

View file

@ -0,0 +1,61 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
ngx_feature="Google perftools"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs="-lprofiler"
ngx_feature_test="ProfilerStop()"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="Google perftools in /usr/local/"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lprofiler"
else
ngx_feature_libs="-L/usr/local/lib -lprofiler"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="Google perftools in /opt/local/"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lprofiler"
else
ngx_feature_libs="-L/opt/local/lib -lprofiler"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: the Google perftool module requires the Google perftools
library. You can either do not enable the module or install the library.
END
exit 1
fi

View file

@ -0,0 +1,56 @@
# Copyright (C) 2010-2014 Alibaba Group Holding Limited
if [ $JEMALLOC != NONE ]; then
case "$NGX_CC_NAME" in
*)
have=NGX_JEMALLOC . auto/have
LINK_DEPS="$LINK_DEPS $JEMALLOC/lib/libjemalloc.a"
CORE_LIBS="$CORE_LIBS $JEMALLOC/lib/libjemalloc.a -lpthread"
CFLAGS="$CFLAGS -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"
;;
esac
elif [ $USE_JEMALLOC = YES ]; then
if [ "$NGX_PLATFORM" != win32 ]; then
JEMALLOC=NO
# FreeBSD, Mac OS X, Linux
ngx_feature="jemalloc library"
ngx_feature_name="NGX_JEMALLOC"
ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs="-ljemalloc"
ngx_feature_test=
. auto/feature
if [ $ngx_found = yes ]; then
if [ $CC = gcc ]; then
CFLAGS="$CFLAGS -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"
fi
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
JEMALLOC=YES
fi
fi
if [ $JEMALLOC != YES ]; then
cat << END
$0: error: the --with-jemalloc requires the jemalloc library.
You can either do not enable this feature, or install the jemalloc
library into the system, or build the jemalloc library statically from
the source with nginx by using --with-jemalloc=<path> option.
END
exit 1
fi
fi

View file

@ -0,0 +1,27 @@
# Copyright (C) 2010-2014 Alibaba Group Holding Limited
done=NO
case "$NGX_PLATFORM" in
*)
cat << END >> $NGX_MAKEFILE
$JEMALLOC/Makefile: $NGX_MAKEFILE
cd $JEMALLOC \\
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
&& CC="\$(CC)" \\
./configure
$JEMALLOC/lib/libjemalloc.a: $JEMALLOC/Makefile
cd $JEMALLOC \\
&& \$(MAKE)
END
;;
esac

View file

@ -0,0 +1,43 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $NGX_LIBATOMIC != YES ]; then
have=NGX_HAVE_LIBATOMIC . auto/have
CORE_INCS="$CORE_INCS $NGX_LIBATOMIC/src"
LINK_DEPS="$LINK_DEPS $NGX_LIBATOMIC/src/libatomic_ops.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBATOMIC/src/libatomic_ops.a"
else
ngx_feature="atomic_ops library"
ngx_feature_name=NGX_HAVE_LIBATOMIC
ngx_feature_run=yes
ngx_feature_incs="#define AO_REQUIRE_CAS
#include <atomic_ops.h>"
ngx_feature_path=
ngx_feature_libs="-latomic_ops"
ngx_feature_test="long n = 0;
if (!AO_compare_and_swap(&n, 0, 1))
return 1;
if (AO_fetch_and_add(&n, 1) != 1)
return 1;
if (n != 2)
return 1;
AO_nop();"
. auto/feature
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: libatomic_ops library was not found.
END
exit 1
fi
fi

View file

@ -0,0 +1,14 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
cat << END >> $NGX_MAKEFILE
$NGX_LIBATOMIC/src/libatomic_ops.a: $NGX_LIBATOMIC/Makefile
cd $NGX_LIBATOMIC && \$(MAKE)
$NGX_LIBATOMIC/Makefile: $NGX_MAKEFILE
cd $NGX_LIBATOMIC && ./configure
END

View file

@ -0,0 +1,83 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
ngx_feature="GD library"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs="#include <gd.h>"
ngx_feature_path=
ngx_feature_libs="-lgd"
ngx_feature_test="gdImagePtr img = gdImageCreateFromGifPtr(1, NULL);"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="GD library in /usr/local/"
ngx_feature_path="/usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lgd"
else
ngx_feature_libs="-L/usr/local/lib -lgd"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD port
ngx_feature="GD library in /usr/pkg/"
ngx_feature_path="/usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd"
else
ngx_feature_libs="-L/usr/pkg/lib -lgd"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="GD library in /opt/local/"
ngx_feature_path="/opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lgd"
else
ngx_feature_libs="-L/opt/local/lib -lgd"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: the HTTP image filter module requires the GD library.
You can either do not enable the module or install the libraries.
END
exit 1
fi

View file

@ -0,0 +1,156 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
ngx_feature="libxslt"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs="#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>"
ngx_feature_path="/usr/include/libxml2"
ngx_feature_libs="-lxml2 -lxslt"
ngx_feature_test="xmlParserCtxtPtr ctxt = NULL;
xsltStylesheetPtr sheet = NULL;
xmlDocPtr doc;
doc = xmlParseChunk(ctxt, NULL, 0, 0);
xsltApplyStylesheet(sheet, doc, NULL);"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="libxslt in /usr/local/"
ngx_feature_path="/usr/local/include/libxml2 /usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lxml2 -lxslt"
else
ngx_feature_libs="-L/usr/local/lib -lxml2 -lxslt"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD port
ngx_feature="libxslt in /usr/pkg/"
ngx_feature_path="/usr/pkg/include/libxml2 /usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lxml2 -lxslt"
else
ngx_feature_libs="-L/usr/pkg/lib -lxml2 -lxslt"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="libxslt in /opt/local/"
ngx_feature_path="/opt/local/include/libxml2 /opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lxml2 -lxslt"
else
ngx_feature_libs="-L/opt/local/lib -lxml2 -lxslt"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: the HTTP XSLT module requires the libxml2/libxslt
libraries. You can either do not enable the module or install the libraries.
END
exit 1
fi
ngx_feature="libexslt"
ngx_feature_name=NGX_HAVE_EXSLT
ngx_feature_run=no
ngx_feature_incs="#include <libexslt/exslt.h>"
ngx_feature_path="/usr/include/libxml2"
ngx_feature_libs="-lexslt"
ngx_feature_test="exsltRegisterAll();"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="libexslt in /usr/local/"
ngx_feature_path="/usr/local/include/libxml2 /usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lexslt"
else
ngx_feature_libs="-L/usr/local/lib -lexslt"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD port
ngx_feature="libexslt in /usr/pkg/"
ngx_feature_path="/usr/pkg/include/libxml2 /usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lexslt"
else
ngx_feature_libs="-L/usr/pkg/lib -lexslt"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="libexslt in /opt/local/"
ngx_feature_path="/opt/local/include/libxml2 /opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lexslt"
else
ngx_feature_libs="-L/opt/local/lib -lexslt"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS -lexslt"
fi

View file

@ -0,0 +1,72 @@
# Copyright (C) 2010-2014 Alibaba Group Holding Limited
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs="#include <yajl/yajl_parse.h> \
#include <yajl/yajl_gen.h>"
ngx_feature_test="yajl_version();"
if [ -n "$LIBYAJL_INC" -o -n "$LIBYAJL_LIB" ]; then
# explicit set libdyajl lib path
ngx_feature="libdyajl library in directories specified by LIBYAJL_INC ($LIBYAJL_INC) and LIBYAJL_LIB ($LIBYAJL_LIB)"
ngx_feature_path="$LIBYAJL_INC"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R$LIBYAJL_LIB -L$LIBYAJL_LIB -lyajl"
else
ngx_feature_libs="-L$LIBYAJL_LIB -lyajl"
fi
. auto/feature
else
# auto-discovery
ngx_feature="libyajl library"
ngx_feature_path=
ngx_feature_libs="-lyajl"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD, OpenBSD, linux
ngx_feature="libyajl library in /usr/local/"
ngx_feature_path="/usr/local/include/yajl /usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lyajl"
else
ngx_feature_libs="-L/usr/local/lib -lyajl"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD
ngx_feature="libyajl library in /usr/pkg/"
ngx_feature_path="/usr/pkg/include/yajl /usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lyajl"
else
ngx_feature_libs="-L/usr/pkg/lib -lyajl"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="libyajl library in /opt/local/"
ngx_feature_path="/opt/local/include/yajl /opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lyajl"
else
ngx_feature_libs="-L/opt/local/lib -lyajl"
fi
. auto/feature
fi
fi
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: the ngx_tfs addon requires the libyajl library.
END
exit 1
fi

View file

@ -0,0 +1,219 @@
ngx_feature="Lua library"
ngx_feature_libs="-llua -lm"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs="#include <lauxlib.h>"
ngx_feature_path=
ngx_feature_test="(void) luaL_newstate();"
if [ -n "$LUAJIT_INC" -o -n "$LUAJIT_LIB" ]; then
# explicitly set Lua lib path
ngx_feature="LuaJIT library in $LUAJIT_LIB and $LUAJIT_INC (specified by the LUAJIT_LIB and LUAJIT_INC env)"
ngx_feature_path="$LUAJIT_INC"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R$LUAJIT_LIB -L$LUAJIT_LIB -lluajit-5.1 -lm"
else
ngx_feature_libs="-L$LUAJIT_LIB -lluajit-5.1 -lm"
fi
. auto/feature
if [ $ngx_found = no ]; then
cat << END
$0: error: ngx_http_lua_module requires the Lua or LuaJIT library and LUAJIT_LIB is defined as $LUAJIT_LIB and LUAJIT_INC (path for lua.h) $LUAJIT_INC, but we cannot find LuaJIT there.
END
exit 1
fi
case "$NGX_PLATFORM" in
Darwin:*)
case "$NGX_MACHINE" in
amd64 | x86_64 | i386)
echo "adding extra linking options needed by LuaJIT"
if [ $HTTP_LUA_SHARED = YES ]; then
NGX_EXTEND_LD_OPT="$NGX_EXTEND_LD_OPT -pagezero_size 10000 -image_base 100000000"
else
ngx_feature_libs="$ngx_feature_libs -pagezero_size 10000 -image_base 100000000"
fi
;;
*)
;;
esac
;;
*)
;;
esac
else
if [ -n "$LUA_INC" -o -n "$LUA_LIB" ]; then
# explicitly set Lua lib path
ngx_feature="Lua library in $LUA_LIB and $LUA_INC (specified by the LUA_LIB and LUA_INC env)"
ngx_feature_path="$LUA_INC"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R$LUA_LIB -L$LUA_LIB -llua -lm"
else
ngx_feature_libs="-L$LUA_LIB -llua -lm"
fi
. auto/feature
if [ $ngx_found = no ]; then
cat << END
$0: error: ngx_http_lua_module requires the Lua or LuaJIT library and LUA_LIB is defined as $LUA_LIB and LUA_INC (path for lua.h) is $LUA_INC, but we cannot find standard Lua there.
END
exit 1
fi
else
# auto-discovery
ngx_feature="Lua library"
ngx_feature_libs="-llua -lm"
. auto/feature
if [ $ngx_found = no ]; then
# OpenBSD-5.2
ngx_feature="Lua library in /usr/local/"
ngx_feature_path="/usr/local/include/lua-5.1"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -llua -lm"
else
ngx_feature_libs="-L/usr/local/lib -llua5.1 -lm"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# OpenBSD < 5.2
ngx_feature="Lua library in /usr/local/"
ngx_feature_path="/usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -llua -lm"
else
ngx_feature_libs="-L/usr/local/lib -llua -lm"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD
ngx_feature="Lua library in /usr/pkg/"
ngx_feature_path="/usr/pkg/include/"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lm -llua"
else
ngx_feature_libs="-L/usr/pkg/lib -lm -llua"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="Lua library in /opt/local/"
ngx_feature_path="/opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lm -llua"
else
ngx_feature_libs="-L/opt/local/lib -lm -llua"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# FreeBSD
ngx_feature="Lua library in /usr/local/*/lua51/"
ngx_feature_path="/usr/local/include/lua51"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib/lua51 -L/usr/local/lib/lua51 -llua -lm"
else
ngx_feature_libs="-L/usr/local/lib/lua51 -llua -lm"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# Debian
ngx_feature="Lua library in /usr/"
ngx_feature_path="/usr/include/lua5.1"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/lib -L/usr/lib -lm -llua5.1"
else
ngx_feature_libs="-L/usr/lib -lm -llua5.1"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# FreeBSD with luajit-2.0 from ports collection
ngx_feature="LuaJIT library in /usr/local/"
ngx_feature_path="/usr/local/include/luajit-2.0"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lluajit-5.1 -lm"
else
ngx_feature_libs="-L/usr/local/lib -lluajit-5.1 -lm"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# Gentoo with LuaJIT-2.0
ngx_feature="LuaJIT library in /usr/"
ngx_feature_path="/usr/include/luajit-2.0"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/lib -L/usr/lib -lm -lluajit-5.1"
else
ngx_feature_libs="-L/usr/lib -lm -lluajit-5.1"
fi
. auto/feature
fi
fi
fi
if [ $ngx_found = yes ]; then
if [ $HTTP_LUA_SHARED = YES ]; then
DSO_INCS="$DSO_INCS|$NGX_HTTP_LUA_MODULE:$ngx_feature_path"
DSO_LIBS="$DSO_LIBS|$NGX_HTTP_LUA_MODULE:$ngx_feature_libs"
else
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
fi
else
cat << END
$0: error: ngx_http_lua_module requires the Lua library.
END
exit 1
fi
CFLAGS="$CFLAGS -DNDK_SET_VAR"
ngx_feature="export symbols by default"
ngx_feature_libs="-Wl,-E"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs="#include <stdio.h>"
ngx_feature_path=
ngx_feature_test='printf("hello");'
. auto/feature
if [ $ngx_found = yes ]; then
if [ $HTTP_LUA_SHARED = YES ]; then
DSO_LIBS="$DSO_LIBS $ngx_feature_libs"
else
CORE_LIBS="-Wl,-E $CORE_LIBS"
fi
fi
#NGX_DTRACE_PROVIDERS="$NGX_DTRACE_PROVIDERS $ngx_addon_dir/dtrace/ngx_lua_provider.d"
#NGX_TAPSET_SRCS="$NGX_TAPSET_SRCS $ngx_addon_dir/tapset/ngx_lua.stp"
ngx_feature="SO_PASSCRED"
ngx_feature_libs=
ngx_feature_name="NGX_HTTP_LUA_HAVE_SO_PASSCRED"
ngx_feature_run=no
ngx_feature_incs="#include <sys/types.h>
#include <sys/socket.h>"
ngx_feature_path=
ngx_feature_test='setsockopt(1, SOL_SOCKET, SO_PASSCRED, NULL, 0);'
. auto/feature

View file

@ -0,0 +1,36 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $PCRE != NONE -a $PCRE != NO -a $PCRE != YES ]; then
. auto/lib/pcre/make
fi
if [ $MD5 != NONE -a $MD5 != NO -a $MD5 != YES ]; then
. auto/lib/md5/make
fi
if [ $SHA1 != NONE -a $SHA1 != NO -a $SHA1 != YES ]; then
. auto/lib/sha1/make
fi
if [ $OPENSSL != NONE -a $OPENSSL != NO -a $OPENSSL != YES ]; then
. auto/lib/openssl/make
fi
if [ $ZLIB != NONE -a $ZLIB != NO -a $ZLIB != YES ]; then
. auto/lib/zlib/make
fi
if [ $NGX_LIBATOMIC != NO -a $NGX_LIBATOMIC != YES ]; then
. auto/lib/libatomic/make
fi
if [ $USE_PERL = YES ]; then
. auto/lib/perl/make
fi
if [ $JEMALLOC != NONE ]; then
. auto/lib/jemalloc/make
fi

View file

@ -0,0 +1,103 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $MD5 != NONE ]; then
if grep MD5_Init $MD5/md5.h 2>&1 >/dev/null; then
# OpenSSL md5
OPENSSL_MD5=YES
have=NGX_HAVE_OPENSSL_MD5 . auto/have
have=NGX_OPENSSL_MD5 . auto/have
else
# rsaref md5
OPENSSL_MD5=NO
fi
have=NGX_HAVE_MD5 . auto/have
CORE_INCS="$CORE_INCS $MD5"
case "$NGX_CC_NAME" in
msvc* | owc* | bcc)
LINK_DEPS="$LINK_DEPS $MD5/md5.lib"
CORE_LIBS="$CORE_LIBS $MD5/md5.lib"
;;
icc*)
LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
# to allow -ipo optimization we link with the *.o but not library
CORE_LIBS="$CORE_LIBS $MD5/md5_dgst.o"
if [ $MD5_ASM = YES ]; then
CORE_LIBS="$CORE_LIBS $MD5/asm/mx86-elf.o"
fi
;;
*)
LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
CORE_LIBS="$CORE_LIBS $MD5/libmd5.a"
#CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
;;
esac
else
if [ "$NGX_PLATFORM" != win32 ]; then
MD5=NO
# FreeBSD, Solaris 10
ngx_feature="md5 in system md library"
ngx_feature_name=NGX_HAVE_MD5
ngx_feature_run=no
ngx_feature_incs="#include <md5.h>"
ngx_feature_path=
ngx_feature_libs="-lmd"
ngx_feature_test="MD5_CTX md5; MD5Init(&md5)"
. auto/feature
ngx_md5_lib="system md"
if [ $ngx_found = no ]; then
# Solaris 8/9
ngx_feature="md5 in system md5 library"
ngx_feature_libs="-lmd5"
. auto/feature
ngx_md5_lib="system md5"
fi
if [ $ngx_found = no ]; then
# OpenSSL crypto library
ngx_feature="md5 in system OpenSSL crypto library"
ngx_feature_name="NGX_OPENSSL_MD5"
ngx_feature_incs="#include <openssl/md5.h>"
ngx_feature_libs="-lcrypto"
ngx_feature_test="MD5_CTX md5; MD5_Init(&md5)"
. auto/feature
ngx_md5_lib="system crypto"
if [ $ngx_found = yes ]; then
have=NGX_HAVE_OPENSSL_MD5_H . auto/have
have=NGX_HAVE_MD5 . auto/have
fi
fi
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
MD5=YES
MD5_LIB=$ngx_md5_lib
fi
fi
fi

View file

@ -0,0 +1,96 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
case "$NGX_CC_NAME" in
msvc*)
ngx_makefile=makefile.msvc
ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC MD5_ASM=$MD5_ASM"
ngx_md5="MD5=\"$MD5\""
;;
owc*)
ngx_makefile=makefile.owc
ngx_opt="CPU_OPT=\"$CPU_OPT\""
ngx_md5=`echo MD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
bcc)
ngx_makefile=makefile.bcc
ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DMD5_ASM=$MD5_ASM"
ngx_md5=`echo \-DMD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
esac
done=NO
case "$NGX_PLATFORM" in
win32)
cat << END >> $NGX_MAKEFILE
`echo "$MD5/md5.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/md5/$ngx_makefile $ngx_opt $ngx_md5
END
done=YES
;;
SunOS:*:i86pc)
if [ $MD5_ASM = YES ]; then
cat << END >> $NGX_MAKEFILE
$MD5/libmd5.a: $NGX_MAKEFILE
cd $MD5 \\
&& \$(MAKE) CFLAGS="$MD5_OPT -DSOL -DMD5_ASM -DL_ENDIAN" \\
CC="\$(CC)" CPP="\$(CPP)" \\
MD5_ASM_OBJ=asm/mx86-sol.o clean libmd5.a
END
done=YES
fi
;;
# FreeBSD: i386
# Linux: i686
*:i386 | *:i686)
if [ $MD5_ASM = YES ]; then
cat << END >> $NGX_MAKEFILE
$MD5/libmd5.a: $NGX_MAKEFILE
cd $MD5 \\
&& \$(MAKE) CFLAGS="$MD5_OPT -DELF -DMD5_ASM -DL_ENDIAN" \\
CC="\$(CC)" CPP="\$(CPP)" \\
MD5_ASM_OBJ=asm/mx86-elf.o clean libmd5.a
END
done=YES
fi
;;
esac
if [ $done = NO ]; then
cat << END >> $NGX_MAKEFILE
$MD5/libmd5.a: $NGX_MAKEFILE
cd $MD5 \\
&& \$(MAKE) CFLAGS="$MD5_OPT" \\
CC="\$(CC)" MD5_ASM_OBJ= clean libmd5.a
END
fi

View file

@ -0,0 +1,22 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN
!if "$(MD5_ASM)" == "YES"
md5.lib:
cd $(MD5)
bcc32 -c $(CFLAGS) -DMD5_ASM md5_dgst.c
tlib md5.lib +md5_dgst.obj +"asm\m-win32.obj"
!else
md5.lib:
cd $(MD5)
bcc32 -c $(CFLAGS) md5_dgst.c
tlib md5.lib +md5_dgst.obj
!endif

View file

@ -0,0 +1,22 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN
!IF "$(MD5_ASM)" == "YES"
md5.lib:
cd $(MD5)
cl -c $(CFLAGS) -D MD5_ASM md5_dgst.c
link -lib -out:md5.lib md5_dgst.obj asm/m-win32.obj
!ELSE
md5.lib:
cd $(MD5)
cl -c $(CFLAGS) md5_dgst.c
link -lib -out:md5.lib md5_dgst.obj
!ENDIF

View file

@ -0,0 +1,11 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT)
md5.lib:
cd $(MD5)
wcl386 -c $(CFLAGS) -dL_ENDIAN md5_dgst.c
wlib -n md5.lib md5_dgst.obj

View file

@ -0,0 +1,74 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $OPENSSL != NONE ]; then
case "$CC" in
cl | bcc32)
have=NGX_OPENSSL . auto/have
have=NGX_SSL . auto/have
CFLAGS="$CFLAGS -DNO_SYS_TYPES_H"
CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/ssleay32.lib"
CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libeay32.lib"
# libeay32.lib requires gdi32.lib
CORE_LIBS="$CORE_LIBS gdi32.lib"
# OpenSSL 1.0.0 requires crypt32.lib
CORE_LIBS="$CORE_LIBS crypt32.lib"
;;
*)
have=NGX_OPENSSL . auto/have
have=NGX_SSL . auto/have
CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
;;
esac
else
if [ "$NGX_PLATFORM" != win32 ]; then
OPENSSL=NO
ngx_feature="OpenSSL library"
ngx_feature_name="NGX_OPENSSL"
ngx_feature_run=no
ngx_feature_incs="#include <openssl/ssl.h>"
ngx_feature_path=
ngx_feature_libs="-lssl -lcrypto"
ngx_feature_test="SSL_library_init()"
. auto/feature
if [ $ngx_found = yes ]; then
have=NGX_SSL . auto/have
CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL"
OPENSSL=YES
fi
fi
if [ $OPENSSL != YES ]; then
cat << END
$0: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
END
exit 1
fi
fi

View file

@ -0,0 +1,67 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
case "$CC" in
cl)
cat << END >> $NGX_MAKEFILE
$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE
\$(MAKE) -f auto/lib/openssl/makefile.msvc \
OPENSSL="$OPENSSL" OPENSSL_OPT="$OPENSSL_OPT"
END
;;
bcc32)
ngx_opt=`echo "-DOPENSSL=\"$OPENSSL\" -DOPENSSL_OPT=\"$OPENSSL_OPT\"" \
| sed -e "s/\//$ngx_regex_dirsep/g"`
cat << END >> $NGX_MAKEFILE
`echo "$OPENSSL\\openssl\\lib\\libeay32.lib: \
$OPENSSL\\openssl\\include\\openssl\\ssl.h" \
| sed -e "s/\//$ngx_regex_dirsep/g"`
`echo "$OPENSSL\\openssl\\lib\\ssleay32.lib: \
$OPENSSL\\openssl\\include\\openssl\\ssl.h" \
| sed -e "s/\//$ngx_regex_dirsep/g"`
`echo "$OPENSSL\\openssl\\include\\openssl\\ssl.h: $NGX_MAKEFILE" \
| sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/openssl/makefile.bcc $ngx_opt
END
;;
*)
case $USE_THREADS in
NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;;
*) OPENSSL_OPT="$OPENSSL_OPT threads" ;;
esac
case $OPENSSL in
/*) ngx_prefix="$OPENSSL/.openssl" ;;
*) ngx_prefix="$PWD/$OPENSSL/.openssl" ;;
esac
cat << END >> $NGX_MAKEFILE
$OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
cd $OPENSSL \\
&& \$(MAKE) clean \\
&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
&& \$(MAKE) \\
&& \$(MAKE) install LIBDIR=lib
END
;;
esac

View file

@ -0,0 +1,18 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
all:
cd $(OPENSSL)
perl Configure BC-32 no-shared --prefix=openssl $(OPENSSL_OPT)
ms\do_nasm
$(MAKE) -f ms\bcb.mak
$(MAKE) -f ms\bcb.mak install
# Borland's make does not expand "[ch]" in
# copy "inc32\openssl\*.[ch]" "openssl\include\openssl"
copy inc32\openssl\*.h openssl\include\openssl

View file

@ -0,0 +1,14 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
all:
cd $(OPENSSL)
perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT)
ms\do_ms
$(MAKE) -f ms\nt.mak
$(MAKE) -f ms\nt.mak install

View file

@ -0,0 +1,198 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $PCRE != NONE ]; then
CORE_INCS="$CORE_INCS $PCRE"
case "$NGX_CC_NAME" in
msvc* | owc* | bcc)
have=NGX_PCRE . auto/have
have=PCRE_STATIC . auto/have
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
;;
icc* )
have=NGX_PCRE . auto/have
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
echo $ngx_n "checking for PCRE library ...$ngx_c"
if [ -f $PCRE/pcre.h ]; then
ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
| sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
else if [ -f $PCRE/configure.in ]; then
ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
| sed -e 's/^.*=\(.*\)$/\1/'`
else
ngx_pcre_ver=`grep pcre_major, $PCRE/configure.ac \
| sed -e 's/^.*pcre_major,.*\[\(.*\)\].*$/\1/'`
fi
fi
echo " $ngx_pcre_ver major version found"
# to allow -ipo optimization we link with the *.o but not library
case "$ngx_pcre_ver" in
4|5)
CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
;;
6)
CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
;;
*)
CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_newline.o"
;;
esac
;;
*)
have=NGX_PCRE . auto/have
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
;;
esac
if [ $PCRE_JIT = YES ]; then
have=NGX_HAVE_PCRE_JIT . auto/have
PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
fi
else
if [ "$NGX_PLATFORM" != win32 ]; then
PCRE=NO
ngx_feature="PCRE library"
ngx_feature_name="NGX_PCRE"
ngx_feature_run=no
ngx_feature_incs="#include <pcre.h>"
ngx_feature_path=
ngx_feature_libs="-lpcre"
ngx_feature_test="pcre *re;
re = pcre_compile(NULL, 0, NULL, 0, NULL);
if (re == NULL) return 1"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="PCRE library in /usr/local/"
ngx_feature_path="/usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lpcre"
else
ngx_feature_libs="-L/usr/local/lib -lpcre"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# RedHat RPM, Solaris package
ngx_feature="PCRE library in /usr/include/pcre/"
ngx_feature_path="/usr/include/pcre"
ngx_feature_libs="-lpcre"
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD port
ngx_feature="PCRE library in /usr/pkg/"
ngx_feature_path="/usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
else
ngx_feature_libs="-L/usr/pkg/lib -lpcre"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="PCRE library in /opt/local/"
ngx_feature_path="/opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
else
ngx_feature_libs="-L/opt/local/lib -lpcre"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
PCRE=YES
fi
if [ $PCRE = YES ]; then
ngx_feature="PCRE JIT support"
ngx_feature_name="NGX_HAVE_PCRE_JIT"
ngx_feature_test="int jit = 0;
pcre_free_study(NULL);
pcre_config(PCRE_CONFIG_JIT, &jit);
if (jit != 1) return 1;"
. auto/feature
if [ $ngx_found = yes ]; then
PCRE_JIT=YES
fi
fi
fi
if [ $PCRE != YES ]; then
cat << END
$0: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
END
exit 1
fi
fi

View file

@ -0,0 +1,64 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
case "$NGX_CC_NAME" in
msvc*)
ngx_makefile=makefile.msvc
ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
ngx_pcre="PCRE=\"$PCRE\""
;;
owc*)
ngx_makefile=makefile.owc
ngx_opt="CPU_OPT=\"$CPU_OPT\""
ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
bcc)
ngx_makefile=makefile.bcc
ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
ngx_pcre=`echo \-DPCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
esac
case "$NGX_PLATFORM" in
win32)
cat << END >> $NGX_MAKEFILE
`echo "$PCRE/pcre.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/pcre/$ngx_makefile $ngx_pcre $ngx_opt
`echo "$PCRE/pcre.h:" | sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/pcre/$ngx_makefile $ngx_pcre pcre.h
END
;;
*)
cat << END >> $NGX_MAKEFILE
$PCRE/pcre.h: $PCRE/Makefile
$PCRE/Makefile: $NGX_MAKEFILE
cd $PCRE \\
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
&& CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
./configure --disable-shared $PCRE_CONF_OPT
$PCRE/.libs/libpcre.a: $PCRE/Makefile
cd $PCRE \\
&& \$(MAKE) libpcre.la
END
;;
esac

View file

@ -0,0 +1,26 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -q -O2 -tWM -w-8004 $(CPU_OPT)
PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
pcre.lib:
cd $(PCRE)
bcc32 -c $(CFLAGS) -I. $(PCREFLAGS) pcre_*.c
> pcre.lst
for %n in (*.obj) do @echo +%n & >> pcre.lst
echo + >> pcre.lst
tlib pcre.lib @pcre.lst
pcre.h:
cd $(PCRE)
copy /y pcre.h.generic pcre.h
copy /y config.h.generic config.h
copy /y pcre_chartables.c.dist pcre_chartables.c

View file

@ -0,0 +1,22 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT)
PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
pcre.lib:
cd $(PCRE)
cl -nologo -c $(CFLAGS) -I . $(PCREFLAGS) pcre_*.c
link -lib -out:pcre.lib -verbose:lib pcre_*.obj
pcre.h:
cd $(PCRE)
copy /y pcre.h.generic pcre.h
copy /y config.h.generic config.h
copy /y pcre_chartables.c.dist pcre_chartables.c

View file

@ -0,0 +1,24 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -c -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT)
PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
pcre.lib:
cd $(PCRE)
wcl386 $(CFLAGS) -i=. $(PCREFLAGS) pcre_*.c
dir /b *.obj > pcre.lst
wlib -n pcre.lib @pcre.lst
pcre.h:
cd $(PCRE)
copy /y pcre.h.generic pcre.h
copy /y config.h.generic config.h
copy /y pcre_chartables.c.dist pcre_chartables.c

View file

@ -0,0 +1,70 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
echo "checking for perl"
NGX_PERL_VER=`$NGX_PERL -v 2>&1 | grep '^This is perl' 2>&1 \
| sed -e 's/^This is perl, \(.*\)/\1/'`
if test -n "$NGX_PERL_VER"; then
echo " + perl version: $NGX_PERL_VER"
if [ "`$NGX_PERL -e 'use 5.006001; print "OK"'`" != "OK" ]; then
echo
echo "$0: error: perl 5.6.1 or higher is required"
echo
exit 1;
fi
if [ "`$NGX_PERL -MExtUtils::Embed -e 'print "OK"'`" != "OK" ]; then
echo
echo "$0: error: perl module ExtUtils::Embed is required"
echo
exit 1;
fi
NGX_PERL_CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`"
NGX_PM_CFLAGS=`$NGX_PERL -MExtUtils::Embed -e ccopts`
# gcc 4.1/4.2 warn about unused values in pTHX_
NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \
| sed -e 's/-Wunused-value/-Wno-unused-value/'`
# icc8 warns 'declaration hides parameter "my_perl"' in ENTER and LEAVE
NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \
| sed -e 's/-wd171/-wd171 -wd1599/'`
ngx_perl_ldopts=`$NGX_PERL -MExtUtils::Embed -e ldopts`
ngx_perl_dlext=`$NGX_PERL -MConfig -e 'print $Config{dlext}'`
if $NGX_PERL -V:usemultiplicity | grep define > /dev/null; then
have=NGX_HAVE_PERL_MULTIPLICITY . auto/have
echo " + perl interpreter multiplicity found"
fi
if $NGX_PERL -V:useithreads | grep undef > /dev/null; then
# FreeBSD port wants to link with -pthread non-threaded perl
ngx_perl_ldopts=`echo $ngx_perl_ldopts | sed 's/ -pthread//'`
fi
CORE_LINK="$CORE_LINK $ngx_perl_ldopts"
LINK_DEPS="$LINK_DEPS $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext"
if test -n "$NGX_PERL_MODULES"; then
have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\""
. auto/define
NGX_PERL_MODULES_MAN=$NGX_PERL_MODULES/man3
fi
else
echo
echo "$0: error: perl 5.6.1 or higher is required"
echo
exit 1;
fi

View file

@ -0,0 +1,40 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
v=`grep 'define NGINX_VERSION' src/core/nginx.h | sed -e 's/^.*"\(.*\)".*/\1/'`
cat << END >> $NGX_MAKEFILE
$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\
\$(CORE_DEPS) \$(HTTP_DEPS) \\
src/http/modules/perl/ngx_http_perl_module.h \\
$NGX_OBJS/src/http/modules/perl/Makefile
cd $NGX_OBJS/src/http/modules/perl && \$(MAKE)
rm -rf $NGX_OBJS/install_perl
$NGX_OBJS/src/http/modules/perl/Makefile: \\
src/core/nginx.h \\
src/http/modules/perl/Makefile.PL \\
src/http/modules/perl/nginx.pm \\
src/http/modules/perl/nginx.xs \\
src/http/modules/perl/typemap
sed "s/%%VERSION%%/$v/" src/http/modules/perl/nginx.pm > \\
$NGX_OBJS/src/http/modules/perl/nginx.pm
cp -p src/http/modules/perl/nginx.xs $NGX_OBJS/src/http/modules/perl/
cp -p src/http/modules/perl/typemap $NGX_OBJS/src/http/modules/perl/
cp -p src/http/modules/perl/Makefile.PL $NGX_OBJS/src/http/modules/perl/
cd $NGX_OBJS/src/http/modules/perl \\
&& NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \\
NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \\
NGX_DEPS="\$(CORE_DEPS) \$(HTTP_DEPS)" \\
$NGX_PERL Makefile.PL \\
LIB=$NGX_PERL_MODULES \\
INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
END

View file

@ -0,0 +1,79 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $SHA1 != NONE ]; then
have=NGX_HAVE_SHA1 . auto/have
CORE_INCS="$CORE_INCS $SHA1"
case "$NGX_CC_NAME" in
msvc* | owc* | bcc)
LINK_DEPS="$LINK_DEPS $SHA1/sha1.lib"
CORE_LIBS="$CORE_LIBS $SHA1/sha1.lib"
;;
icc*)
LINK_DEPS="$LINK_DEPS $SHA1/libsha.a"
# to allow -ipo optimization we link with the *.o but not library
CORE_LIBS="$CORE_LIBS $SHA1/sha1_dgst.o"
if [ $SHA1_ASM = YES ]; then
CORE_LIBS="$CORE_LIBS $SHA1/asm/sx86-elf.o"
fi
;;
*)
LINK_DEPS="$LINK_DEPS $SHA1/libsha.a"
CORE_LIBS="$CORE_LIBS $SHA1/libsha.a"
#CORE_LIBS="$CORE_LIBS -L $SHA1 -lsha"
;;
esac
else
if [ "$NGX_PLATFORM" != win32 ]; then
SHA1=NO
# FreeBSD
ngx_feature="sha1 in system md library"
ngx_feature_name=NGX_HAVE_SHA1
ngx_feature_run=no
ngx_feature_incs="#include <sha.h>"
ngx_feature_path=
ngx_feature_libs="-lmd"
ngx_feature_test="SHA_CTX sha1; SHA1_Init(&sha1)"
. auto/feature
ngx_sha1_lib="system md"
if [ $ngx_found = no ]; then
# OpenSSL crypto library
ngx_feature="sha1 in system OpenSSL crypto library"
ngx_feature_incs="#include <openssl/sha.h>"
ngx_feature_libs="-lcrypto"
. auto/feature
ngx_sha1_lib="system crypto"
if [ $ngx_found = yes ]; then
have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
fi
fi
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
SHA1=YES
SHA1_LIB=$ngx_sha1_lib
fi
fi
fi

View file

@ -0,0 +1,96 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
case "$NGX_CC_NAME" in
msvc*)
ngx_makefile=makefile.msvc
ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC SHA1_ASM=$SHA1_ASM"
ngx_sha1="SHA1=\"$SHA1\""
;;
owc*)
ngx_makefile=makefile.owc
ngx_opt="CPU_OPT=\"$CPU_OPT\""
ngx_sha1=`echo SHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
bcc)
ngx_makefile=makefile.bcc
ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DSHA1_ASM=$SHA1_ASM"
ngx_sha1=`echo \-DSHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
esac
done=NO
case "$NGX_PLATFORM" in
win32)
cat << END >> $NGX_MAKEFILE
`echo "$SHA1/sha1.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/sha1/$ngx_makefile $ngx_opt $ngx_sha1
END
done=YES
;;
SunOS:*:i86pc)
if [ $SHA1_ASM = YES ]; then
cat << END >> $NGX_MAKEFILE
$SHA1/libsha.a: $NGX_MAKEFILE
cd $SHA1 \\
&& \$(MAKE) CFLAGS="$SHA1_OPT -DSOL -DSHA1_ASM -DL_ENDIAN" \\
CC="\$(CC)" CPP="\$(CPP)" \\
SHA_ASM_OBJ=asm/sx86-sol.o clean libsha.a
END
done=YES
fi
;;
# FreeBSD: i386
# Linux: i686
*:i386 | *:i686)
if [ $SHA1_ASM = YES ]; then
cat << END >> $NGX_MAKEFILE
$SHA1/libsha.a: $NGX_MAKEFILE
cd $SHA1 \\
&& \$(MAKE) CFLAGS="$SHA1_OPT -DELF -DSHA1_ASM -DL_ENDIAN" \\
CC="\$(CC)" CPP="\$(CPP)" \\
SHA_ASM_OBJ=asm/sx86-elf.o clean libsha.a
END
done=YES
fi
;;
esac
if [ $done = NO ]; then
cat << END >> $NGX_MAKEFILE
$SHA1/libsha.a: $NGX_MAKEFILE
cd $SHA1 \\
&& \$(MAKE) CFLAGS="$SHA1_OPT" \\
CC="\$(CC)" SHA_ASM_OBJ= clean libsha.a
END
fi

View file

@ -0,0 +1,22 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN
!if "$(SHA1_ASM)" == "YES"
sha1.lib:
cd $(SHA1)
bcc32 -c $(CFLAGS) -DSHA1_ASM sha1dgst.c
tlib sha1.lib +sha1dgst.obj +"asm\s-win32.obj"
!else
sha1.lib:
cd $(SHA1)
bcc32 -c $(CFLAGS) sha1dgst.c
tlib sha1.lib +sha1dgst.obj
!endif

View file

@ -0,0 +1,22 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN
!IF "$(SHA1_ASM)" == "YES"
sha1.lib:
cd $(SHA1)
cl -c $(CFLAGS) -D SHA1_ASM sha1dgst.c
link -lib -out:sha1.lib sha1dgst.obj asm/s-win32.obj
!ELSE
sha1.lib:
cd $(SHA1)
cl -c $(CFLAGS) sha1dgst.c
link -lib -out:sha1.lib sha1dgst.obj
!ENDIF

View file

@ -0,0 +1,11 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT)
sha1.lib:
cd $(SHA1)
wcl386 -c $(CFLAGS) -dL_ENDIAN sha1dgst.c
wlib -n sha1.lib sha1dgst.obj

View file

@ -0,0 +1,40 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
echo $ngx_n "checking for $ngx_lib ...$ngx_c"
cat << END >> $NGX_AUTOCONF_ERR
----------------------------------------
checking for $ngx_lib
END
ngx_found=no
cat << END > $NGX_AUTOTEST.c
$ngx_lib_incs
int main() {
$ngx_lib_test;
return 0;
}
eval "$CC $cc_test_flags $ngx_lib_cflags \
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $ngx_libs \
>> $NGX_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
echo " found"
ngx_found=yes
else
echo " not found"
fi
rm $NGX_AUTOTEST*

View file

@ -0,0 +1,79 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
if [ $ZLIB != NONE ]; then
CORE_INCS="$CORE_INCS $ZLIB"
case "$NGX_CC_NAME" in
msvc* | owc* | bcc)
have=NGX_ZLIB . auto/have
LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib"
CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib"
;;
icc*)
have=NGX_ZLIB . auto/have
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
# to allow -ipo optimization we link with the *.o but not library
CORE_LIBS="$CORE_LIBS $ZLIB/adler32.o"
CORE_LIBS="$CORE_LIBS $ZLIB/crc32.o"
CORE_LIBS="$CORE_LIBS $ZLIB/deflate.o"
CORE_LIBS="$CORE_LIBS $ZLIB/trees.o"
CORE_LIBS="$CORE_LIBS $ZLIB/zutil.o"
CORE_LIBS="$CORE_LIBS $ZLIB/compress.o"
if [ $ZLIB_ASM != NO ]; then
CORE_LIBS="$CORE_LIBS $ZLIB/match.o"
fi
;;
*)
have=NGX_ZLIB . auto/have
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
#CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
;;
esac
else
if [ "$NGX_PLATFORM" != win32 ]; then
ZLIB=NO
# FreeBSD, Solaris, Linux
ngx_feature="zlib library"
ngx_feature_name="NGX_ZLIB"
ngx_feature_run=no
ngx_feature_incs="#include <zlib.h>"
ngx_feature_path=
ngx_feature_libs="-lz"
ngx_feature_test="z_stream z; deflate(&z, Z_NO_FLUSH)"
. auto/feature
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
ZLIB=YES
ngx_found=no
fi
fi
if [ $ZLIB != YES ]; then
cat << END
$0: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.
END
exit 1
fi
fi

View file

@ -0,0 +1,114 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
case "$NGX_CC_NAME" in
msvc*)
ngx_makefile=makefile.msvc
ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
ngx_zlib="ZLIB=\"$ZLIB\""
;;
owc*)
ngx_makefile=makefile.owc
ngx_opt="CPU_OPT=\"$CPU_OPT\""
ngx_zlib=`echo ZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
bcc)
ngx_makefile=makefile.bcc
ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
ngx_zlib=`echo \-DZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
esac
done=NO
case "$NGX_PLATFORM" in
win32)
cat << END >> $NGX_MAKEFILE
`echo "$ZLIB/zlib.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/zlib/$ngx_makefile $ngx_opt $ngx_zlib
END
done=YES
;;
# FreeBSD: i386
# Linux: i686
*:i386 | *:i686)
case $ZLIB_ASM in
pentium)
cat << END >> $NGX_MAKEFILE
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
&& \$(MAKE) distclean \\
&& cp contrib/asm586/match.S . \\
&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
./configure \\
&& \$(MAKE) OBJA=match.o libz.a
END
done=YES
;;
pentiumpro)
cat << END >> $NGX_MAKEFILE
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
&& \$(MAKE) distclean \\
&& cp contrib/asm686/match.S . \\
&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
./configure \\
&& \$(MAKE) OBJA=match.o libz.a
END
done=YES
;;
NO)
;;
*)
echo "$0: error: invalid --with-zlib-asm=$ZLIB_ASM option."
echo "The valid values are \"pentium\" and \"pentiumpro\" only".
echo
exit 1;
;;
esac
;;
esac
if [ $done = NO ]; then
cat << END >> $NGX_MAKEFILE
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
&& \$(MAKE) distclean \\
&& CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
./configure \\
&& \$(MAKE) libz.a
END
fi

View file

@ -0,0 +1,17 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -q -O2 -tWM -w-8004 -w-8012 $(CPU_OPT)
zlib.lib:
cd $(ZLIB)
bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c \
trees.c zutil.c compress.c \
inflate.c inffast.c inftrees.c
tlib zlib.lib +adler32.obj +crc32.obj +deflate.obj \
+trees.obj +zutil.obj +compress.obj \
+inflate.obj +inffast.obj +inftrees.obj

View file

@ -0,0 +1,17 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT)
zlib.lib:
cd $(ZLIB)
cl -c $(CFLAGS) adler32.c crc32.c deflate.c \
trees.c zutil.c compress.c \
inflate.c inffast.c inftrees.c
link -lib -out:zlib.lib adler32.obj crc32.obj deflate.obj \
trees.obj zutil.obj compress.obj \
inflate.obj inffast.obj inftrees.obj

View file

@ -0,0 +1,14 @@
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
CFLAGS = -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT)
zlib.lib:
cd $(ZLIB)
wcl386 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c &
compress.c inflate.c inffast.c inftrees.c
wlib -n zlib.lib adler32.obj crc32.obj deflate.obj trees.obj &
zutil.obj compress.obj inflate.obj inffast.obj inftrees.obj

View file

@ -0,0 +1,10 @@
--- zlib.h Thu Jul 9 20:06:56 1998
+++ zlib-1.1.3/zlib.h Tue Mar 22 13:41:04 2005
@@ -709,7 +709,6 @@
(0 in case of error).
*/
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
/*
Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of

View file

@ -0,0 +1 @@
../nginx-tests/lib

View file

@ -0,0 +1,592 @@
package Test::Nginx;
# (C) Maxim Dounin
# Generic module for nginx tests.
###############################################################################
use warnings;
use strict;
use base qw/ Exporter /;
our @EXPORT = qw/ log_in log_out http http_get http_head /;
our @EXPORT_OK = qw/ http_gzip_request http_gzip_like /;
our %EXPORT_TAGS = (
gzip => [ qw/ http_gzip_request http_gzip_like / ]
);
###############################################################################
use File::Path qw/ rmtree /;
use File::Temp qw/ tempdir /;
use IO::Socket;
use POSIX qw/ waitpid WNOHANG /;
use Socket qw/ CRLF /;
use Test::More qw//;
###############################################################################
our $NGINX = defined $ENV{TEST_NGINX_BINARY} ? $ENV{TEST_NGINX_BINARY}
: '../nginx/objs/nginx';
sub new {
my $self = {};
bless $self;
$self->{_pid} = $$;
$self->{_testdir} = tempdir(
'nginx-test-XXXXXXXXXX',
TMPDIR => 1,
CLEANUP => not $ENV{TEST_NGINX_LEAVE}
)
or die "Can't create temp directory: $!\n";
$self->{_testdir} =~ s!\\!/!g if $^O eq 'MSWin32';
$self->{_dso_module} = ();
mkdir("$self->{_testdir}/logs");
return $self;
}
sub DESTROY {
my ($self) = @_;
return if $self->{_pid} != $$;
$self->stop();
$self->stop_daemons();
if ($ENV{TEST_NGINX_CATLOG}) {
system("cat $self->{_testdir}/error.log");
}
if (not $ENV{TEST_NGINX_LEAVE}) {
eval { rmtree($self->{_testdir}); };
}
}
sub has($;) {
my ($self, @features) = @_;
foreach my $feature (@features) {
Test::More::plan(skip_all => "$feature not compiled in")
unless $self->has_module($feature);
}
return $self;
}
sub set_dso($;) {
my ($self, $module_name, $module_path) = @_;
$self->{_dso_module}{$module_name} = $module_path;
}
sub has_module($) {
my ($self, $feature) = @_;
my %regex = (
sni => 'TLS SNI support enabled',
mail => '--with-mail(?!\S)',
flv => '--with-http_flv_module',
perl => '--with-http_perl_module',
auth_request
=> '--with-http_auth_request_module',
charset => '(?s)^(?!.*--without-http_charset_module)',
gzip => '(?s)^(?!.*--without-http_gzip_module)',
ssi => '(?s)^(?!.*--without-http_ssi_module)',
userid => '(?s)^(?!.*--without-http_userid_module)',
access => '(?s)^(?!.*--without-http_access_module)',
auth_basic
=> '(?s)^(?!.*--without-http_auth_basic_module)',
autoindex
=> '(?s)^(?!.*--without-http_autoindex_module)',
geo => '(?s)^(?!.*--without-http_geo_module)',
map => '(?s)^(?!.*--without-http_map_module)',
referer => '(?s)^(?!.*--without-http_referer_module)',
rewrite => '(?s)^(?!.*--without-http_rewrite_module)',
proxy => '(?s)^(?!.*--without-http_proxy_module)',
fastcgi => '(?s)^(?!.*--without-http_fastcgi_module)',
uwsgi => '(?s)^(?!.*--without-http_uwsgi_module)',
scgi => '(?s)^(?!.*--without-http_scgi_module)',
memcached
=> '(?s)^(?!.*--without-http_memcached_module)',
limit_conn
=> '(?s)^(?!.*--without-http_limit_conn_module)',
limit_req
=> '(?s)^(?!.*--without-http_limit_req_module)',
empty_gif
=> '(?s)^(?!.*--without-http_empty_gif_module)',
browser => '(?s)^(?!.*--without-http_browser_module)',
upstream_ip_hash
=> '(?s)^(?!.*--without-http_upstream_ip_hash_module)',
reqstat
=> '(?s)^(?!.*--without-http_reqstat_module)',
upstream_least_conn
=> '(?s)^(?!.*--without-http_upstream_least_conn_mod)',
upstream_keepalive
=> '(?s)^(?!.*--without-http_upstream_keepalive_modu)',
http => '(?s)^(?!.*--without-http(?!\S))',
cache => '(?s)^(?!.*--without-http-cache)',
pop3 => '(?s)^(?!.*--without-mail_pop3_module)',
imap => '(?s)^(?!.*--without-mail_imap_module)',
smtp => '(?s)^(?!.*--without-mail_smtp_module)',
pcre => '(?s)^(?!.*--without-pcre)',
split_clients
=> '(?s)^(?!.*--without-http_split_clients_module)',
);
my $re = $regex{$feature};
$re = $feature if !defined $re;
$self->{_configure_args} = `$NGINX -V 2>&1`
if !defined $self->{_configure_args};
return ($self->{_configure_args} =~ $re) ? 1 : 0;
}
sub has_version($) {
my ($self, $need) = @_;
$self->{_configure_args} = `$NGINX -V 2>&1`
if !defined $self->{_configure_args};
$self->{_configure_args} =~ m!nginx version: nginx/([0-9.]+)!;
my @v = split(/\./, $1);
my ($n, $v);
for $n (split(/\./, $need)) {
$v = shift @v || 0;
return 0 if $n > $v;
return 1 if $v > $n;
}
return 1;
}
sub has_daemon($) {
my ($self, $daemon) = @_;
if ($^O eq 'MSWin32') {
Test::More::plan(skip_all => "win32");
return $self;
}
if ($^O eq 'solaris') {
Test::More::plan(skip_all => "$daemon not found")
unless `command -v $daemon`;
return $self;
}
Test::More::plan(skip_all => "$daemon not found")
unless `which $daemon`;
return $self;
}
sub plan($) {
my ($self, $plan) = @_;
Test::More::plan(tests => $plan);
return $self;
}
sub run(;$) {
my ($self, $conf) = @_;
my $testdir = $self->{_testdir};
if (defined $conf) {
my $c = `cat $conf`;
$self->write_file_expand('nginx.conf', $c);
}
my $pid = fork();
die "Unable to fork(): $!\n" unless defined $pid;
if ($pid == 0) {
my @globals = $self->{_test_globals} ?
() : ('-g', "pid $testdir/nginx.pid; "
. "error_log $testdir/error.log debug;");
exec($NGINX, '-c', "$testdir/nginx.conf", @globals)
or die "Unable to exec(): $!\n";
}
# wait for nginx to start
$self->waitforfile("$testdir/nginx.pid", $pid)
or die "Can't start nginx";
$self->{_started} = 1;
return $self;
}
sub waitforfile($;$) {
my ($self, $file, $pid) = @_;
my $exited;
# wait for file to appear
# or specified process to exit
for (1 .. 30) {
return 1 if -e $file;
return 0 if $exited;
$exited = waitpid($pid, WNOHANG) != 0 if $pid;
select undef, undef, undef, 0.1;
}
return undef;
}
sub waitforsocket($) {
my ($self, $peer) = @_;
# wait for socket to accept connections
for (1 .. 30) {
my $s = IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => $peer
);
return 1 if defined $s;
select undef, undef, undef, 0.1;
}
return undef;
}
sub reload() {
my ($self) = @_;
return $self unless $self->{_started};
local $/;
open F, '<' . $self->{_testdir} . '/nginx.pid'
or die "Can't open nginx.pid: $!";
my $pid = <F>;
close F;
if ($^O eq 'MSWin32') {
my $testdir = $self->{_testdir};
my @globals = $self->{_test_globals} ?
() : ('-g', "pid $testdir/nginx.pid; "
. "error_log $testdir/error.log debug;");
system($NGINX, '-c', "$testdir/nginx.conf", '-s', 'reload',
@globals) == 0
or die "system() failed: $?\n";
} else {
kill 'HUP', $pid;
}
sleep(1);
return $self;
}
sub stop() {
my ($self) = @_;
return $self unless $self->{_started};
local $/;
open F, '<' . $self->{_testdir} . '/nginx.pid'
or die "Can't open nginx.pid: $!";
my $pid = <F>;
close F;
if ($^O eq 'MSWin32') {
my $testdir = $self->{_testdir};
my @globals = $self->{_test_globals} ?
() : ('-g', "pid $testdir/nginx.pid; "
. "error_log $testdir/error.log debug;");
system($NGINX, '-c', "$testdir/nginx.conf", '-s', 'stop',
@globals) == 0
or die "system() failed: $?\n";
} else {
kill 'QUIT', $pid;
}
waitpid($pid, 0);
$self->{_started} = 0;
return $self;
}
sub stop_daemons() {
my ($self) = @_;
while ($self->{_daemons} && scalar @{$self->{_daemons}}) {
my $p = shift @{$self->{_daemons}};
kill $^O eq 'MSWin32' ? 9 : 'TERM', $p;
waitpid($p, 0);
}
return $self;
}
sub write_file($$) {
my ($self, $name, $content) = @_;
open F, '>' . $self->{_testdir} . '/' . $name
or die "Can't create $name: $!";
print F $content;
close F;
return $self;
}
sub write_file_expand($$) {
my ($self, $name, $content) = @_;
$content =~ s/%%TEST_GLOBALS%%/$self->test_globals()/gmse;
$content =~ s/%%TEST_GLOBALS_DSO%%/$self->test_globals_dso()/gmse;
$content =~ s/%%TEST_GLOBALS_HTTP%%/$self->test_globals_http()/gmse;
$content =~ s/%%TESTDIR%%/$self->{_testdir}/gms;
return $self->write_file($name, $content);
}
sub run_daemon($;@) {
my ($self, $code, @args) = @_;
my $pid = fork();
die "Can't fork daemon: $!\n" unless defined $pid;
if ($pid == 0) {
if (ref($code) eq 'CODE') {
$code->(@args);
exit 0;
} else {
exec($code, @args);
exit 0;
}
}
$self->{_daemons} = [] unless defined $self->{_daemons};
push @{$self->{_daemons}}, $pid;
return $self;
}
sub testdir() {
my ($self) = @_;
return $self->{_testdir};
}
sub test_globals() {
my ($self) = @_;
return $self->{_test_globals}
if defined $self->{_test_globals};
my $s = '';
$s .= "pid $self->{_testdir}/nginx.pid;\n";
$s .= "error_log $self->{_testdir}/error.log debug;\n";
$self->{_test_globals} = $s;
}
sub test_globals_dso() {
my ($self) = @_;
return "" unless defined $ENV{TEST_NGINX_DSO};
return $self->{_test_globals_dso} if defined $self->{_test_globals_dso};
my $s = '';
$s .= "dso {\n";
if (defined $ENV{NGINX_DSO_PATH}) {
$s .= "path $ENV{NGINX_DSO_PATH};\n";
}
while ( my ($key, $value) = each(%{$self->{_dso_module}}) ) {
$s .= "load $key $value;\n";
}
$s .= "}\n";
$self->{_test_globals_dso} = $s;
}
sub test_globals_http() {
my ($self) = @_;
return $self->{_test_globals_http}
if defined $self->{_test_globals_http};
my $s = '';
$s .= "root $self->{_testdir};\n";
$s .= "access_log $self->{_testdir}/access.log;\n";
$s .= "client_body_temp_path $self->{_testdir}/client_body_temp;\n";
$s .= "fastcgi_temp_path $self->{_testdir}/fastcgi_temp;\n"
if $self->has_module('fastcgi');
$s .= "proxy_temp_path $self->{_testdir}/proxy_temp;\n"
if $self->has_module('proxy');
$s .= "uwsgi_temp_path $self->{_testdir}/uwsgi_temp;\n"
if $self->has_module('uwsgi');
$s .= "scgi_temp_path $self->{_testdir}/scgi_temp;\n"
if $self->has_module('scgi');
$self->{_test_globals_http} = $s;
}
###############################################################################
sub log_core {
return unless $ENV{TEST_NGINX_VERBOSE};
my ($prefix, $msg) = @_;
($prefix, $msg) = ('', $prefix) unless defined $msg;
$prefix .= ' ' if length($prefix) > 0;
if (length($msg) > 2048) {
$msg = substr($msg, 0, 2048)
. "(...logged only 2048 of " . length($msg)
. " bytes)";
}
$msg =~ s/^/# $prefix/gm;
$msg =~ s/([^\x20-\x7e])/sprintf('\\x%02x', ord($1)) . (($1 eq "\n") ? "\n" : '')/gmxe;
$msg .= "\n" unless $msg =~ /\n\Z/;
print $msg;
}
sub log_out {
log_core('>>', @_);
}
sub log_in {
log_core('<<', @_);
}
###############################################################################
sub http_get($;%) {
my ($url, %extra) = @_;
return http(<<EOF, %extra);
GET $url HTTP/1.0
Host: localhost
EOF
}
sub http_head($;%) {
my ($url, %extra) = @_;
return http(<<EOF, %extra);
HEAD $url HTTP/1.0
Host: localhost
EOF
}
sub http($;%) {
my ($request, %extra) = @_;
my $reply;
eval {
local $SIG{ALRM} = sub { die "timeout\n" };
local $SIG{PIPE} = sub { die "sigpipe\n" };
alarm(5);
my $s = $extra{socket} || IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => '127.0.0.1:8080'
)
or die "Can't connect to nginx: $!\n";
log_out($request);
$s->print($request);
select undef, undef, undef, $extra{sleep} if $extra{sleep};
return '' if $extra{aborted};
if ($extra{body}) {
log_out($extra{body});
$s->print($extra{body});
}
local $/;
$reply = $s->getline();
alarm(0);
};
alarm(0);
if ($@) {
log_in("died: $@");
return undef;
}
log_in($reply);
return $reply;
}
###############################################################################
sub http_gzip_request {
my ($url) = @_;
my $r = http(<<EOF);
GET $url HTTP/1.1
Host: localhost
Connection: close
Accept-Encoding: gzip
EOF
}
sub http_content {
my ($text) = @_;
return undef if !defined $text;
if ($text !~ /(.*?)\x0d\x0a?\x0d\x0a?(.*)/ms) {
return undef;
}
my ($headers, $body) = ($1, $2);
if ($headers !~ /Transfer-Encoding: chunked/i) {
return $body;
}
my $content = '';
while ($body =~ /\G\x0d?\x0a?([0-9a-f]+)\x0d\x0a?/gcmsi) {
my $len = hex($1);
$content .= substr($body, pos($body), $len);
pos($body) += $len;
}
return $content;
}
sub http_gzip_like {
my ($text, $re, $name) = @_;
SKIP: {
eval { require IO::Uncompress::Gunzip; };
Test::More->builder->skip(
"IO::Uncompress::Gunzip not installed", 1) if $@;
my $in = http_content($text);
my $out;
IO::Uncompress::Gunzip::gunzip(\$in => \$out);
Test::More->builder->like($out, $re, $name);
}
}
###############################################################################
1;
###############################################################################

View file

@ -0,0 +1,110 @@
package Test::Nginx::IMAP;
# (C) Maxim Dounin
# Module for nginx imap tests.
###############################################################################
use warnings;
use strict;
use Test::More qw//;
use IO::Socket;
use Socket qw/ CRLF /;
use Test::Nginx;
use base qw/ IO::Socket::INET /;
sub new {
my $class = shift;
my $self = return $class->SUPER::new(
Proto => "tcp",
PeerAddr => "127.0.0.1:8143",
@_
)
or die "Can't connect to nginx: $!\n";
$self->autoflush(1);
return $self;
}
sub send {
my ($self, $cmd) = @_;
log_out($cmd);
$self->print($cmd . CRLF);
}
sub read {
my ($self) = @_;
eval {
local $SIG{ALRM} = sub { die "timeout\n" };
alarm(3);
while (<$self>) {
log_in($_);
# XXX
next if m/^\d\d\d-/;
last;
}
alarm(0);
};
alarm(0);
if ($@) {
log_in("died: $@");
return undef;
}
return $_;
}
sub check {
my ($self, $regex, $name) = @_;
Test::More->builder->like($self->read(), $regex, $name);
}
sub ok {
my $self = shift;
Test::More->builder->like($self->read(), qr/^\S+ OK/, @_);
}
###############################################################################
sub imap_test_daemon {
my $server = IO::Socket::INET->new(
Proto => 'tcp',
LocalAddr => '127.0.0.1:8144',
Listen => 5,
Reuse => 1
)
or die "Can't create listening socket: $!\n";
while (my $client = $server->accept()) {
$client->autoflush(1);
print $client "* OK fake imap server ready" . CRLF;
while (<$client>) {
my $tag = '';
$tag = $1 if m/^(\S+)/;
s/^(\S+)\s+//;
if (/^logout/i) {
print $client $tag . ' OK logout ok' . CRLF;
} elsif (/^login /i) {
print $client $tag . ' OK login ok' . CRLF;
} else {
print $client $tag . ' ERR unknown command' . CRLF;
}
}
close $client;
}
}
###############################################################################
1;
###############################################################################

View file

@ -0,0 +1,107 @@
package Test::Nginx::POP3;
# (C) Maxim Dounin
# Module for nginx pop3 tests.
###############################################################################
use warnings;
use strict;
use Test::More qw//;
use IO::Socket;
use Socket qw/ CRLF /;
use Test::Nginx;
use base qw/ IO::Socket::INET /;
sub new {
my $class = shift;
my $self = return $class->SUPER::new(
Proto => "tcp",
PeerAddr => "127.0.0.1:8110",
@_
)
or die "Can't connect to nginx: $!\n";
$self->autoflush(1);
return $self;
}
sub send {
my ($self, $cmd) = @_;
log_out($cmd);
$self->print($cmd . CRLF);
}
sub read {
my ($self) = @_;
eval {
local $SIG{ALRM} = sub { die "timeout\n" };
alarm(3);
while (<$self>) {
log_in($_);
# XXX
next if m/^\d\d\d-/;
last;
}
alarm(0);
};
alarm(0);
if ($@) {
log_in("died: $@");
return undef;
}
return $_;
}
sub check {
my ($self, $regex, $name) = @_;
Test::More->builder->like($self->read(), $regex, $name);
}
sub ok {
my $self = shift;
Test::More->builder->like($self->read(), qr/^\+OK/, @_);
}
###############################################################################
sub pop3_test_daemon {
my $server = IO::Socket::INET->new(
Proto => 'tcp',
LocalAddr => '127.0.0.1:8111',
Listen => 5,
Reuse => 1
)
or die "Can't create listening socket: $!\n";
while (my $client = $server->accept()) {
$client->autoflush(1);
print $client "+OK fake pop3 server ready" . CRLF;
while (<$client>) {
if (/^quit/i) {
print $client '+OK quit ok' . CRLF;
} elsif (/^user test\@example.com/i) {
print $client '+OK user ok' . CRLF;
} elsif (/^pass secret/i) {
print $client '+OK pass ok' . CRLF;
} else {
print $client "-ERR unknown command" . CRLF;
}
}
close $client;
}
}
###############################################################################
1;
###############################################################################

View file

@ -0,0 +1,123 @@
package Test::Nginx::SMTP;
# (C) Maxim Dounin
# Module for nginx smtp tests.
###############################################################################
use warnings;
use strict;
use Test::More qw//;
use IO::Socket;
use Socket qw/ CRLF /;
use Test::Nginx;
use base qw/ IO::Socket::INET /;
sub new {
my $class = shift;
my $self = return $class->SUPER::new(
Proto => "tcp",
PeerAddr => "127.0.0.1:8025",
@_
)
or die "Can't connect to nginx: $!\n";
$self->autoflush(1);
return $self;
}
sub send {
my ($self, $cmd) = @_;
log_out($cmd);
$self->print($cmd . CRLF);
}
sub read {
my ($self) = @_;
eval {
local $SIG{ALRM} = sub { die "timeout\n" };
alarm(3);
while (<$self>) {
log_in($_);
next if m/^\d\d\d-/;
last;
}
alarm(0);
};
alarm(0);
if ($@) {
log_in("died: $@");
return undef;
}
return $_;
}
sub check {
my ($self, $regex, $name) = @_;
Test::More->builder->like($self->read(), $regex, $name);
}
sub ok {
my $self = shift;
Test::More->builder->like($self->read(), qr/^2\d\d /, @_);
}
sub authok {
my $self = shift;
Test::More->builder->like($self->read(), qr/^235 /, @_);
}
###############################################################################
sub smtp_test_daemon {
my $server = IO::Socket::INET->new(
Proto => 'tcp',
LocalAddr => '127.0.0.1:8026',
Listen => 5,
Reuse => 1
)
or die "Can't create listening socket: $!\n";
while (my $client = $server->accept()) {
$client->autoflush(1);
print $client "220 fake esmtp server ready" . CRLF;
while (<$client>) {
Test::Nginx::log_core('||', $_);
if (/^quit/i) {
print $client '221 quit ok' . CRLF;
} elsif (/^(ehlo|helo)/i) {
print $client '250 hello ok' . CRLF;
} elsif (/^rset/i) {
print $client '250 rset ok' . CRLF;
} elsif (/^mail from:[^@]+$/i) {
print $client '500 mail from error' . CRLF;
} elsif (/^mail from:/i) {
print $client '250 mail from ok' . CRLF;
} elsif (/^rcpt to:[^@]+$/i) {
print $client '500 rcpt to error' . CRLF;
} elsif (/^rcpt to:/i) {
print $client '250 rcpt to ok' . CRLF;
} elsif (/^xclient/i) {
print $client '220 xclient ok' . CRLF;
} else {
print $client "500 unknown command" . CRLF;
}
}
close $client;
}
}
###############################################################################
1;
###############################################################################

View file

@ -0,0 +1,292 @@
# Date::Parse
#
# Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
# software; you can redistribute it and/or modify it under the same terms
# as Perl itself.
package Time::Parse;
=head1 NAME
Date::Parse - Parse date strings into time values
=head1 SYNOPSIS
use Date::Parse;
$time = str2time($date);
($ss,$mm,$hh,$day,$month,$year,$zone) = strptime($date);
=head1 DESCRIPTION
C<Date::Parse> provides two routines for parsing date strings into time values.
=over 4
=item str2time(DATE [, ZONE])
C<str2time> parses C<DATE> and returns a unix time value, or undef upon failure.
C<ZONE>, if given, specifies the timezone to assume when parsing if the
date string does not specify a timezome.
=item strptime(DATE [, ZONE])
C<strptime> takes the same arguments as str2time but returns an array of
values C<($ss,$mm,$hh,$day,$month,$year,$zone)>. Elements are only defined
if they could be extracted from the date string. The C<$zone> element is
the timezone offset in seconds from GMT. An empty array is returned upon
failure.
=head1 MULTI-LANGUAGE SUPPORT
Date::Parse is capable of parsing dates in several languages, these are
English, French, German and Italian. Changing the language is done via
a static method call, for example
Date::Parse->language('German');
will cause Date::Parse to attempt to parse any subsequent dates in German.
This is only a first pass, I am considering changing this to be
$lang = Date::Language->new('German');
$lang->str2time("25 Jun 1996 21:09:55 +0100");
I am open to suggestions on this.
=head1 AUTHOR
Graham Barr <Graham.Barr@tiuk.ti.com>
=head1 REVISION
$Revision: 2.6 $
=head1 COPYRIGHT
Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
software; you can redistribute it and/or modify it under the same terms
as Perl itself.
=cut
require 5.000;
use strict;
use vars qw($VERSION @ISA @EXPORT);
use Time::Local;
use Carp;
use Time::Zone;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(&strtotime &str2time &strptime);
$VERSION = sprintf("%d.%02d", q$Revision: 2.6 $ =~ m#(\d+)\.(\d+)#);
my %month = (
january => 0,
february => 1,
march => 2,
april => 3,
may => 4,
june => 5,
july => 6,
august => 7,
september => 8,
sept => 8,
october => 9,
november => 10,
december => 11,
);
my %day = (
sunday => 0,
monday => 1,
tuesday => 2,
tues => 2,
wednesday => 3,
wednes => 3,
thursday => 4,
thur => 4,
thurs => 4,
friday => 5,
saturday => 6,
);
my @suf = (qw(th st nd rd th th th th th th)) x 3;
@suf[11,12,13] = qw(th th th);
#Abbreviations
map { $month{substr($_,0,3)} = $month{$_} } keys %month;
map { $day{substr($_,0,3)} = $day{$_} } keys %day;
my $strptime = <<'ESQ';
my %month = map { lc $_ } %$mon_ref;
my $daypat = join("|", map { lc $_ } keys %$day_ref);
my $monpat = join("|", keys %month);
my $sufpat = join("|", map { lc $_ } @$suf_ref);
my %ampm = (
am => 0,
pm => 12
);
# allow map am +. a.m.
map { my($z) = $_; $z =~ s#(\w)#$1\.#g; $ampm{$z} = $ampm{$_} } keys %ampm;
my($AM, $PM) = (0,12);
sub
{
my $dtstr = lc shift;
my $merid = 24;
my($year,$month,$day,$hh,$mm,$ss,$zone) = (undef) x 7;
$zone = tz_offset(shift)
if(@_);
while(1) { last unless($dtstr =~ s#\([^\(\)]*\)# #o) }
$dtstr =~ s#(\A|\n|\Z)# #sog;
# ignore day names
$dtstr =~ s#([\d\w\s])[\.\,]\s#$1 #sog;
$dtstr =~ s#($daypat)\s*(den\s)?# #o;
# Time: 12:00 or 12:00:00 with optional am/pm
if($dtstr =~ s#[:\s](\d\d?):(\d\d)(:(\d\d)(?:\.\d+)?)?\s*([ap]\.?m\.?)?\s# #o)
{
($hh,$mm,$ss) = ($1,$2,$4 || 0);
$merid = $ampm{$5} if($5);
}
# Time: 12 am
elsif($dtstr =~ s#\s(\d\d?)\s*([ap]\.?m\.?)\s# #o)
{
($hh,$mm,$ss) = ($1,0,0);
$merid = $ampm{$2};
}
# Date: 12-June-96 (using - . or /)
if($dtstr =~ s#\s(\d\d?)([\-\./])($monpat)(\2(\d\d+))?\s# #o)
{
($month,$day) = ($month{$3},$1);
$year = $5
if($5);
}
# Date: 12-12-96 (using '-', '.' or '/' )
elsif($dtstr =~ s#\s(\d\d*)([\-\./])(\d\d?)(\2(\d\d+))?\s# #o)
{
($month,$day) = ($1 - 1,$3);
if($5)
{
$year = $5;
# Possible match for 1995-01-24 (short mainframe date format);
($year,$month,$day) = ($1, $3 - 1, $5)
if($month > 12);
}
}
elsif($dtstr =~ s#\s(\d+)\s*($sufpat)?\s*($monpat)# #o)
{
($month,$day) = ($month{$3},$1);
}
elsif($dtstr =~ s#($monpat)\s*(\d+)\s*($sufpat)?\s# #o)
{
($month,$day) = ($month{$1},$2);
}
# Date: 961212
elsif($dtstr =~ s#\s(\d\d)(\d\d)(\d\d)\s# #o)
{
($year,$month,$day) = ($1,$2-1,$3);
}
$year = $1
if(!defined($year) && $dtstr =~ s#\s(\d{2}(\d{2})?)[\s\.,]# #o);
# Zone
if($dtstr =~ s#\s"?(\w{3,})\s# #o)
{
$zone = tz_offset($1);
return ()
unless(defined $zone);
}
elsif($dtstr =~ s#\s(([\-\+])\d\d?)(\d\d)\s# #o)
{
my $m = $2 . $3;
$zone = 60 * ($m + (60 * $1));
}
return ()
if($dtstr =~ /\S/o);
$hh += 12
if(defined $hh && $merid == $PM);
$year -= 1900
if(defined $year && $year > 1900);
return ($ss,$mm,$hh,$day,$month,$year,$zone);
}
ESQ
use vars qw($day_ref $mon_ref $suf_ref $obj);
sub gen_parser
{
local($day_ref,$mon_ref,$suf_ref,$obj) = @_;
if($obj)
{
my $obj_strptime = $strptime;
substr($obj_strptime,index($strptime,"sub")+6,0) = <<'ESQ';
shift; # package
ESQ
return eval "$obj_strptime";
}
eval "$strptime";
}
*strptime = gen_parser(\%day,\%month,\@suf);
sub str2time
{
my @t = strptime(@_);
return undef
unless @t;
my($ss,$mm,$hh,$day,$month,$year,$zone) = @t;
my @lt = localtime(time);
$hh ||= 0;
$mm ||= 0;
$ss ||= 0;
$month = $lt[4]
unless(defined $month);
$day = $lt[3]
unless(defined $day);
$year = ($month > $lt[4]) ? ($lt[5] - 1) : $lt[5]
unless(defined $year);
return defined $zone ? timegm($ss,$mm,$hh,$day,$month,$year) - $zone
: timelocal($ss,$mm,$hh,$day,$month,$year);
}
1;

View file

@ -0,0 +1,270 @@
package Time::Zone;
=head1 NAME
Time::Zone -- miscellaneous timezone manipulations routines
=head1 SYNOPSIS
use Time::Zone;
print tz2zone();
print tz2zone($ENV{'TZ'});
print tz2zone($ENV{'TZ'}, time());
print tz2zone($ENV{'TZ'}, undef, $isdst);
$offset = tz_local_offset();
$offset = tz_offset($TZ);
=head1 DESCRIPTION
This is a collection of miscellaneous timezone manipulation routines.
C<tz2zone()> parses the TZ environment variable and returns a timezone
string suitable for inclusion in L<date>-like output. It opionally takes
a timezone string, a time, and a is-dst flag.
C<tz_local_offset()> determins the offset from GMT time in seconds. It
only does the calculation once.
C<tz_offset()> determines the offset from GMT in seconds of a specified
timezone.
C<tz_name()> determines the name of the timezone based on its offset
=head1 AUTHORS
Graham Barr <bodg@tiuk.ti.com>
David Muir Sharnoff <muir@idiom.com>
Paul Foley <paul@ascent.com>
=cut
require 5.002;
require Exporter;
use Carp;
use strict;
use vars qw(@ISA @EXPORT $VERSION @tz_local);
@ISA = qw(Exporter);
@EXPORT = qw(tz2zone tz_local_offset tz_offset tz_name);
$VERSION = "2.04";
# Parts stolen from code by Paul Foley <paul@ascent.com>
sub tz2zone (;$$$)
{
my($TZ, $time, $isdst) = @_;
use vars qw(%tzn_cache);
$TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : ''
unless $TZ;
# Hack to deal with 'PST8PDT' format of TZ
# Note that this can't deal with all the esoteric forms, but it
# does recognize the most common: [:]STDoff[DST[off][,rule]]
if (! defined $isdst) {
my $j;
$time = time() unless $time;
($j, $j, $j, $j, $j, $j, $j, $j, $isdst) = localtime($time);
}
if (defined $tzn_cache{$TZ}->[$isdst]) {
return $tzn_cache{$TZ}->[$isdst];
}
if ($TZ =~ /^
( [^:\d+\-,] {3,} )
( [+-] ?
\d {1,2}
( : \d {1,2} ) {0,2}
)
( [^\d+\-,] {3,} )?
/x
) {
$TZ = $isdst ? $4 : $1;
$tzn_cache{$TZ} = [ $1, $4 ];
} else {
$tzn_cache{$TZ} = [ $TZ, $TZ ];
}
return $TZ;
}
sub tz_local_offset (;$)
{
my ($time) = @_;
$time = time() unless $time;
my (@l) = localtime($time);
my $isdst = $l[8];
if (defined($tz_local[$isdst])) {
return $tz_local[$isdst];
}
$tz_local[$isdst] = &calc_off($time);
return $tz_local[$isdst];
}
sub calc_off
{
my ($time) = @_;
my (@l) = localtime($time);
my (@g) = gmtime($time);
my $off;
$off = $l[0] - $g[0]
+ ($l[1] - $g[1]) * 60
+ ($l[2] - $g[2]) * 3600;
# subscript 7 is yday.
if ($l[7] == $g[7]) {
# done
} elsif ($l[7] == $g[7] + 1) {
$off += 86400;
} elsif ($l[7] == $g[7] - 1) {
$off -= 86400;
} elsif ($l[7] < $g[7]) {
# crossed over a year boundry!
# localtime is beginning of year, gmt is end
# therefore local is ahead
$off += 86400;
} else {
$off -= 86400;
}
return $off;
}
# constants
CONFIG: {
use vars qw(%dstZone %zoneOff %dstZoneOff %Zone);
%dstZone = (
# "ndt" => -2*3600-1800, # Newfoundland Daylight
"adt" => -3*3600, # Atlantic Daylight
"edt" => -4*3600, # Eastern Daylight
"cdt" => -5*3600, # Central Daylight
"mdt" => -6*3600, # Mountain Daylight
"pdt" => -7*3600, # Pacific Daylight
"ydt" => -8*3600, # Yukon Daylight
"hdt" => -9*3600, # Hawaii Daylight
"bst" => +1*3600, # British Summer
"mest" => +2*3600, # Middle European Summer
"sst" => +2*3600, # Swedish Summer
"fst" => +2*3600, # French Summer
"wadt" => +8*3600, # West Australian Daylight
# "cadt" => +10*3600+1800, # Central Australian Daylight
"eadt" => +11*3600, # Eastern Australian Daylight
"nzdt" => +13*3600, # New Zealand Daylight
);
%Zone = (
"gmt" => 0, # Greenwich Mean
"ut" => 0, # Universal (Coordinated)
"utc" => 0,
"wet" => 0, # Western European
"wat" => -1*3600, # West Africa
"at" => -2*3600, # Azores
# For completeness. BST is also British Summer, and GST is also Guam Standard.
# "bst" => -3*3600, # Brazil Standard
# "gst" => -3*3600, # Greenland Standard
# "nft" => -3*3600-1800,# Newfoundland
# "nst" => -3*3600-1800,# Newfoundland Standard
"ast" => -4*3600, # Atlantic Standard
"est" => -5*3600, # Eastern Standard
"cst" => -6*3600, # Central Standard
"mst" => -7*3600, # Mountain Standard
"pst" => -8*3600, # Pacific Standard
"yst" => -9*3600, # Yukon Standard
"hst" => -10*3600, # Hawaii Standard
"cat" => -10*3600, # Central Alaska
"ahst" => -10*3600, # Alaska-Hawaii Standard
"nt" => -11*3600, # Nome
"idlw" => -12*3600, # International Date Line West
"cet" => +1*3600, # Central European
"met" => +1*3600, # Middle European
"mewt" => +1*3600, # Middle European Winter
"swt" => +1*3600, # Swedish Winter
"fwt" => +1*3600, # French Winter
"eet" => +2*3600, # Eastern Europe, USSR Zone 1
"bt" => +3*3600, # Baghdad, USSR Zone 2
# "it" => +3*3600+1800,# Iran
"zp4" => +4*3600, # USSR Zone 3
"zp5" => +5*3600, # USSR Zone 4
# "ist" => +5*3600+1800,# Indian Standard
"zp6" => +6*3600, # USSR Zone 5
# For completeness. NST is also Newfoundland Stanard, and SST is also Swedish Summer.
# "nst" => +6*3600+1800,# North Sumatra
# "sst" => +7*3600, # South Sumatra, USSR Zone 6
"wast" => +7*3600, # West Australian Standard
# "jt" => +7*3600+1800,# Java (3pm in Cronusland!)
"cct" => +8*3600, # China Coast, USSR Zone 7
"jst" => +9*3600, # Japan Standard, USSR Zone 8
# "cast" => +9*3600+1800,# Central Australian Standard
"east" => +10*3600, # Eastern Australian Standard
"gst" => +10*3600, # Guam Standard, USSR Zone 9
"nzt" => +12*3600, # New Zealand
"nzst" => +12*3600, # New Zealand Standard
"idle" => +12*3600, # International Date Line East
);
%zoneOff = reverse(%Zone);
%dstZoneOff = reverse(%dstZone);
# Preferences
$zoneOff{0} = 'gmt';
$dstZoneOff{3600} = 'bst';
}
sub tz_offset (;$$)
{
my ($zone, $time) = @_;
return &tz_local_offset() unless($zone);
$time = time() unless $time;
my(@l) = localtime($time);
my $dst = $l[8];
$zone = lc $zone;
if($zone =~ /^(([\-\+])\d\d?)(\d\d)$/) {
my $v = $2 . $3;
return $1 * 3600 + $v * 60;
} elsif (exists $dstZone{$zone} && ($dst || !exists $Zone{$zone})) {
return $dstZone{$zone};
} elsif(exists $Zone{$zone}) {
return $Zone{$zone};
}
undef;
}
sub tz_name (;$$)
{
my ($off, $dst) = @_;
$off = tz_offset()
unless(defined $off);
$dst = (localtime(time))[8]
unless(defined $dst);
if (exists $dstZoneOff{$off} && ($dst || !exists $zoneOff{$off})) {
return $dstZoneOff{$off};
} elsif (exists $zoneOff{$off}) {
return $zoneOff{$off};
}
sprintf("%+05d", int($off / 60) * 100 + $off % 60);
}
1;

View file

@ -0,0 +1,173 @@
--Copyright (c) 2007-2008 Neil Richardson (nrich@iinet.net.au)
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
--IN THE SOFTWARE.
module('CRC32', package.seeall)
local max = 2^32 -1
local CRC32 = {
0,79764919,159529838,222504665,319059676,
398814059,445009330,507990021,638119352,
583659535,797628118,726387553,890018660,
835552979,1015980042,944750013,1276238704,
1221641927,1167319070,1095957929,1595256236,
1540665371,1452775106,1381403509,1780037320,
1859660671,1671105958,1733955601,2031960084,
2111593891,1889500026,1952343757,2552477408,
2632100695,2443283854,2506133561,2334638140,
2414271883,2191915858,2254759653,3190512472,
3135915759,3081330742,3009969537,2905550212,
2850959411,2762807018,2691435357,3560074640,
3505614887,3719321342,3648080713,3342211916,
3287746299,3467911202,3396681109,4063920168,
4143685023,4223187782,4286162673,3779000052,
3858754371,3904687514,3967668269,881225847,
809987520,1023691545,969234094,662832811,
591600412,771767749,717299826,311336399,
374308984,453813921,533576470,25881363,
88864420,134795389,214552010,2023205639,
2086057648,1897238633,1976864222,1804852699,
1867694188,1645340341,1724971778,1587496639,
1516133128,1461550545,1406951526,1302016099,
1230646740,1142491917,1087903418,2896545431,
2825181984,2770861561,2716262478,3215044683,
3143675388,3055782693,3001194130,2326604591,
2389456536,2200899649,2280525302,2578013683,
2640855108,2418763421,2498394922,3769900519,
3832873040,3912640137,3992402750,4088425275,
4151408268,4197601365,4277358050,3334271071,
3263032808,3476998961,3422541446,3585640067,
3514407732,3694837229,3640369242,1762451694,
1842216281,1619975040,1682949687,2047383090,
2127137669,1938468188,2001449195,1325665622,
1271206113,1183200824,1111960463,1543535498,
1489069629,1434599652,1363369299,622672798,
568075817,748617968,677256519,907627842,
853037301,1067152940,995781531,51762726,
131386257,177728840,240578815,269590778,
349224269,429104020,491947555,4046411278,
4126034873,4172115296,4234965207,3794477266,
3874110821,3953728444,4016571915,3609705398,
3555108353,3735388376,3664026991,3290680682,
3236090077,3449943556,3378572211,3174993278,
3120533705,3032266256,2961025959,2923101090,
2868635157,2813903052,2742672763,2604032198,
2683796849,2461293480,2524268063,2284983834,
2364738477,2175806836,2238787779,1569362073,
1498123566,1409854455,1355396672,1317987909,
1246755826,1192025387,1137557660,2072149281,
2135122070,1912620623,1992383480,1753615357,
1816598090,1627664531,1707420964,295390185,
358241886,404320391,483945776,43990325,
106832002,186451547,266083308,932423249,
861060070,1041341759,986742920,613929101,
542559546,756411363,701822548,3316196985,
3244833742,3425377559,3370778784,3601682597,
3530312978,3744426955,3689838204,3819031489,
3881883254,3928223919,4007849240,4037393693,
4100235434,4180117107,4259748804,2310601993,
2373574846,2151335527,2231098320,2596047829,
2659030626,2470359227,2550115596,2947551409,
2876312838,2788305887,2733848168,3165939309,
3094707162,3040238851,2985771188,
}
local function xor(a, b)
local calc = 0
for i = 32, 0, -1 do
local val = 2 ^ i
local aa = false
local bb = false
if a == 0 then
calc = calc + b
break
end
if b == 0 then
calc = calc + a
break
end
if a >= val then
aa = true
a = a - val
end
if b >= val then
bb = true
b = b - val
end
if not (aa and bb) and (aa or bb) then
calc = calc + val
end
end
return calc
end
local function lshift(num, left)
local res = num * (2 ^ left)
return res % (2 ^ 32)
end
local function rshift(num, right)
local res = num / (2 ^ right)
return math.floor(res)
end
function Hash(str)
local count = string.len(tostring(str))
local crc = max
local i = 1
while count > 0 do
local byte = string.byte(str, i)
crc = xor(lshift(crc, 8), CRC32[xor(rshift(crc, 24), byte) + 1])
i = i + 1
count = count - 1
end
return crc
end
--
-- CRC32.lua
--
-- A pure Lua implementation of a CRC32 hashing algorithm. Slower than using a C implemtation,
-- but useful having no other dependancies.
--
--
-- Synopsis
--
-- require('CRC32')
--
-- crchash = CRC32.Hash('a string')
--
-- Methods:
--
-- hashval = CRC32.Hash(val)
-- Calculates and returns (as an integer) the CRC32 hash of the parameter 'val'.

View file

@ -0,0 +1,567 @@
--Copyright (c) 2006-2008 Neil Richardson (nrich@iinet.net.au)
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
--IN THE SOFTWARE.
module('Memcached', package.seeall)
require('socket')
require('CRC32')
local SERVER_RETRIES = 10
local STATS_KEYS = {
malloc = true,
sizes = true,
slabs = true,
items = true,
}
local FLAGS = {
'STORABLE',
'COMPRESSED',
'SERIALISED',
}
local function warn(str)
io.stderr:write(string.format('Warning: %s\n', tostring(str)))
end
local function _select_server(cache, key)
local server_count = #cache.servers
local hashfunc = cache.hash or CRC32.Hash
if server_count == 1 then
return cache.servers[1].socket
else
local serverhash = hashfunc(key)
for i = 0, SERVER_RETRIES do
local index = (serverhash % server_count) + 1
local server = cache.servers[index].socket
if not server then
serverhash = hashfunc(serverhash .. i)
else
return server
end
end
end
error('No servers found')
return nil
end
local function _retrieve(cache, key, str)
local server = _select_server(cache, key)
server:send(str .. '\r\n')
local function toboolean(value)
if type(value) == 'string' then
if value == 'true' then
return true
elseif value == 'false' then
return false
end
end
return nil
end
local function extract_flags(str)
local num = tonumber(str)
local flags = {}
for i = table.maxn(FLAGS), 1, -1 do
local bf = 2 ^ (i - 1)
if num >= bf then
flags[FLAGS[i]] = true
num = num - bf
end
end
return flags
end
local returndata = {}
while true do
local line, err = server:receive()
if line == 'END' then
break
elseif string.sub(line, 1, 5) == 'VALUE' then
local key,flagstr,size,cas = string.match(line, 'VALUE (%S+) (%d+) (%d+)')
flags = extract_flags(flagstr)
local data = server:receive(size)
if flags.COMPRESSED and cache.compress_enabled then
data = cache.decompress(data)
end
if flags.SERIALISED then
returndata[key] = cache.decode(data)
else
local ldata = tonumber(data) or toboolean(data)
if ldata == nil then
if data == 'nil' then
returndata[key] = nil
else
returndata[key] = data
end
else
returndata[key] = ldata
end
end
end
end
return returndata
end
local function _send(cache, key, str)
local server = _select_server(cache, key)
server:send(str .. "\r\n")
local line, err = server:receive()
if not err then return line end
end
local function _store(cache, op, key, value, expiry)
local str
local flags = 0
if type(value) == 'table' then
str = cache.encode(value)
-- TODO lookup rather than hard code
flags = flags + 4
else
str = tostring(value)
end
if cache.compress_enabled and string.len(str) > cache.compress_threshold then
local cstr = cache.compress(str)
if string.len(cstr) < (string.len(str) * 0.8) then
str = cstr
-- TODO lookup rather than hard code
flags = flags + 2
end
end
local len = string.len(str)
expiry = expiry or 0
local cmd = op .. ' ' .. key .. ' ' .. flags .. ' ' .. expiry .. ' ' .. len .. '\r\n' .. str
local res = _send(cache, key, cmd)
if res ~= 'STORED' then
return false, res
end
return true
end
local function set(cache, key, value, expiry)
return _store(cache, 'set', key, value, expiry)
end
local function add(cache, key, value, expiry)
return _store(cache, 'add', key, value, expiry)
end
local function replace(cache, key, value, expiry)
return _store(cache, 'replace', key, value, expiry)
end
local function get(cache, key)
local dataset = _retrieve(cache, key, 'get ' .. key)
return dataset[key]
end
local function delete(cache, key)
local res = _send(cache, key, 'delete ' .. key)
if res == 'NOT_FOUND' then
return false
end
if res ~= 'DELETED' then
return false, res
end
return true
end
local function incr(cache, key, val)
val = val or 1
local res = _send(cache, key, 'incr ' .. key .. ' ' .. val)
if res == 'ERROR' or res == 'CLIENT_ERROR' then
return false, res
end
return res
end
local function decr(cache, key, val)
val = val or 1
local res = _send(cache, key, 'decr ' .. key .. ' ' .. val)
if res == 'ERROR' or res == 'CLIENT_ERROR' then
return false, res
end
return res
end
local function stats(cache, key)
local servers = {}
key = key or ''
if string.len(key) > 0 and not STATS_KEYS[key] then
error(string.format("Unknown stats key '%s'", key))
end
for i,server in pairs(cache.servers) do
server.socket:send('stats ' .. key .. '\r\n')
local stats = {}
while true do
local line, err = server.socket:receive()
if line == 'END' or line == 'ERROR' then
break
end
local k,v = string.match(line, 'STAT (%S+) (%S+)')
if k then
stats[k] = v
end
end
servers[server.name] = stats
end
return servers
end
local function get_multi(cache, ...)
local dataset = nil
if table.maxn(cache.servers) > 1 then
dataset = {}
for i,k in ipairs(arg) do
local data = _retrieve(cache, k, 'get ' .. k)
dataset[k] = data[k]
end
else
local keys = table.concat(arg, ' ')
dataset = _retrieve(cache, keys, 'get ' .. keys)
end
return dataset
end
local function flush_all(cache)
local success = true
for i,server in ipairs(cache.servers) do
server.socket:send('flush_all\r\n')
local res = assert(server.socket:receive())
if res ~= 'OK' then
success = false
end
end
return success
end
local function disconnect_all(cache)
while true do
local server = table.remove(cache.servers)
if not server then
break
end
server.socket:close()
end
end
local function set_hash(cache, hashfunc)
cache.hash = hashfunc
end
local function set_encode(cache, func)
cache.encode = func
end
local function set_decode(cache, func)
cache.decode = func
end
local function set_compress(cache, func)
cache.compress = func
end
local function set_decompress(cache, func)
cache.decompress = func
end
function Connect(hostlist, port)
local servers = {}
if type(hostlist) == 'table' then
for i,host in pairs(hostlist) do
local h, p
if type(host) == 'table' then
h = host[1]
p = host[2]
elseif type(host) == 'string' then
h = host
elseif type(host) == 'number' then
p = host
h = nil
end
if not h then
h = '127.0.0.1'
end
if not p then
p = 11211
end
local server = socket.connect(h, p)
if not server then
warn('Could not connect to ' .. h .. ':' .. p)
else
table.insert(servers, {socket = server, name = string.format('%s:%d', h, p)})
end
end
else
local address = hostlist
if type(address) == 'number' then
port = address
address = nil
end
if address == nil then
address = '127.0.0.1'
end
if port == nil then
port = 11211
end
local server = socket.connect(address, port)
if not server then
warn('Could not connect to ' .. address .. ':' .. port)
else
servers = {{socket = server, name = string.format('%s:%d', address, port)}}
end
end
if table.maxn(servers) < 1 then
error('No servers available')
end
local cache = {
servers = servers,
set_hash = set_hash,
set_encode = set_encode,
set_decode = set_decode,
set_decompress = set_decompress,
set_compress = set_compress,
compress_enabled = false,
enable_compression = function(self, on)
self.compress_enabled = on
end,
hash = nil,
encode = function()
error('No encode function set')
end,
decode = function()
error('No decode function set')
end,
compress = function()
error('No compress function set')
end,
decompress = function()
error('No decompress function set')
end,
-- 10K default
compress_threshold = 10240,
set_compress_threshold = function(self, threshold)
if threshold == nil then
self:enable_compression(false)
else
self.compress_threshold = threshold
end
end,
set = set,
add = add,
replace = replace,
get = get,
delete = delete,
incr = incr,
decr = decr,
get_multi = get_multi,
stats = stats,
flush_all = flush_all,
disconnect_all = disconnect_all,
}
return cache
end
function New(hostlist, port)
return Connect(hostlist, port)
end
--
-- Memcached.lua
--
-- A pure Lua implementation of a simple memcached client. 1 or more memcached server(s) are currently supported. Requires the luasocket library.
-- See http://www.danga.com/memcached/ for more information about memcached.
--
--
--
-- Synopsis
--
-- require('Memcached')
--
-- memcache = Memcached.Connect('some.host.com', 11000)
-- OR
-- memcache = Memcached.New('some.host.com', 11000)
--
-- memcache:set('some_key', 1234)
-- memcache:add('new_key', 'add new value')
-- memcache:replace('existing_key', 'replace old value')
--
-- cached_data = memcache:get('some_key')
--
-- memcache:delete('old_key')
--
--
--
-- Methods:
--
-- memcache = Memcached.Connect()
-- Connect to memcached server at localhost on port number 11211.
--
-- memcache = Memcached.Connect(host[, port])
-- Connect to memcached server at 'host' on port number 'port'. If port is not provided, port 11211 is used.
--
---memcache = Memcached.Connect(port)
-- Connect to memcached server at localhost on port number 'port'.
--
-- memcache = Memcached.Connect({{'host', port}, 'host', port})
-- Connect to multiple memcached servers.
--
-- memcache:set(key, value[, expiry])
-- Unconditionally sets a key to a given value in the memcache. The value for 'expiry' is the expiration
-- time (default is 0, never expire).
--
-- memcache:add(key, value[, expiry])
-- Like set, but only stores in memcache if the key doesn't already exist.
--
-- memcache:replace(key, value[, expiry])
-- Like set, but only stores in memcache if the key already exists. The opposite of add.
--
-- value = memcache:get(key)
-- Retrieves a key from the memcache. Returns the value or nil
--
-- values = memcache:get_multi(...)
-- Retrieves multiple keys from the memcache doing just one query. Returns a table of key/value pairs that were available.
--
-- memcache:delete(key)
-- Deletes a key. Returns true on deletion, false if the key was not found.
--
-- value = memcache:incr(key[, value])
-- Sends a command to the server to atomically increment the value for key by value, or by 1 if value is nil.
-- Returns nil if key doesn't exist on server, otherwise it returns the new value after incrementing. Value should be zero or greater.
--
-- value = memcache:decr(key[, value])
-- Like incr, but decrements. Unlike incr, underflow is checked and new values are capped at 0. If server value is 1, a decrement of 2 returns 0, not -1.
--
-- servers = memcache:stats([key])
-- Returns a table of statistical data regarding the memcache server(s). Allowed keys are:
-- '', 'malloc', 'sizes', 'slabs', 'items'
--
-- success = memcache:flush_all()
-- Runs the memcached "flush_all" command on all configured hosts, emptying all their caches.
--
-- memcache:disconnect_all()
-- Closes all cached sockets to all memcached servers.
--
-- memcache:set_hash(hashfunc)
-- Sets a custom hash function for key values. The default is a CRC32 hashing function.
-- 'hashfunc' should be defined receiving a single string parameter and returing a single integer value.
--
-- memcache:set_encode(func)
-- Sets a custom encode function for serialising table values. 'func' should be defined receiving a single
-- table value and returning a single string value.
--
-- memcache:set_decode(func)
-- Sets a custom decode function for deserialising table values. 'func' should be defined receiving a
-- single single and returning a single table value
--
-- memcache:enable_compression(onflag)
-- Turns data compression support on or off.
--
-- memcache:set_compress_threshold(size)
-- Set the compression threshold. If the value to be stored is larger than `size' bytes (and compression
-- is enabled), compress before storing.
--
-- memcache:set_compress(func)
-- Sets a custom data compression function. 'func' should be defined receiving a single string value and
-- returning a single string value.
--
-- memcache:set_decompress(func)
-- Sets a custom data decompression function. 'func' should be defined receiving a single string value and
-- returning a single string value.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,315 @@
package Test::Nginx;
use strict;
use warnings;
our $VERSION = '0.17';
__END__
=encoding utf-8
=head1 NAME
Test::Nginx - Testing modules for Nginx C module development
=head1 DESCRIPTION
This distribution provides two testing modules for Nginx C module development:
=over
=item *
L<Test::Nginx::LWP>
=item *
L<Test::Nginx::Socket>
=back
All of them are based on L<Test::Base>.
Usually, L<Test::Nginx::Socket> is preferred because it works on a much lower
level and not that fault tolerant like L<Test::Nginx::LWP>.
Also, a lot of connection hang issues (like wrong C<< r->main->count >> value in nginx
0.8.x) can only be captured by L<Test::Nginx::Socket> because Perl's L<LWP::UserAgent> client
will close the connection itself which will conceal such issues from
the testers.
Test::Nginx automatically starts an nginx instance (from the C<PATH> env)
rooted at t/servroot/ and the default config template makes this nginx
instance listen on the port C<1984> by default. One can specify a different
port number by setting his port number to the C<TEST_NGINX_PORT> environment,
as in
export TEST_NGINX_PORT=1989
=head2 etcproxy integration
The default settings in etcproxy (https://github.com/chaoslawful/etcproxy)
makes this small TCP proxy split the TCP packets into bytes and introduce 1 ms latency among them.
There's usually various TCP chains that we can put etcproxy into, for example
=head3 Test::Nginx <=> nginx
$ ./etcproxy 1234 1984
Here we tell etcproxy to listen on port 1234 and to delegate all the
TCP traffic to the port 1984, the default port that Test::Nginx makes
nginx listen to.
And then we tell Test::Nginx to test against the port 1234, where
etcproxy listens on, rather than the port 1984 that nginx directly
listens on:
$ TEST_NGINX_CLIENT_PORT=1234 prove -r t/
Then the TCP chain now looks like this:
Test::Nginx <=> etcproxy (1234) <=> nginx (1984)
So etcproxy can effectively emulate extreme network conditions and
exercise "unusual" code paths in your nginx server by your tests.
In practice, *tons* of weird bugs can be captured by this setting.
Even ourselves didn't expect that this simple approach is so
effective.
=head3 nginx <=> memcached
We first start the memcached server daemon on port 11211:
memcached -p 11211 -vv
and then we another etcproxy instance to listen on port 11984 like this
$ ./etcproxy 11984 11211
Then we tell our t/foo.t test script to connect to 11984 rather than 11211:
# foo.t
use Test::Nginx::Socket;
repeat_each(1);
plan tests => 2 * repeat_each() * blocks();
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211; # make this env take a default value
run_tests();
__DATA__
=== TEST 1: sanity
--- config
location /foo {
set $memc_cmd set;
set $memc_key foo;
set $memc_value bar;
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
}
--- request
GET /foo
--- response_body_like: STORED
The Test::Nginx library will automatically expand the special macro
C<$TEST_NGINX_MEMCACHED_PORT> to the environment with the same name.
You can define your own C<$TEST_NGINX_BLAH_BLAH_PORT> macros as long as
its prefix is C<TEST_NGINX_> and all in upper case letters.
And now we can run your test script against the etcproxy port 11984:
TEST_NGINX_MEMCACHED_PORT=11984 prove t/foo.t
Then the TCP chains look like this:
Test::Nginx <=> nginx (1984) <=> etcproxy (11984) <=> memcached (11211)
If C<TEST_NGINX_MEMCACHED_PORT> is not set, then it will take the default
value 11211, which is what we want when there's no etcproxy
configured:
Test::Nginx <=> nginx (1984) <=> memcached (11211)
This approach also works for proxied mysql and postgres traffic.
Please see the live test suite of ngx_drizzle and ngx_postgres for
more details.
Usually we set both C<TEST_NGINX_CLIENT_PORT> and
C<TEST_NGINX_MEMCACHED_PORT> (and etc) at the same time, effectively
yielding the following chain:
Test::Nginx <=> etcproxy (1234) <=> nginx (1984) <=> etcproxy (11984) <=> memcached (11211)
as long as you run two separate etcproxy instances in two separate terminals.
It's easy to verify if the traffic actually goes through your etcproxy
server. Just check if the terminal running etcproxy emits outputs. By
default, etcproxy always dump out the incoming and outgoing data to
stdout/stderr.
=head2 valgrind integration
Test::Nginx has integrated support for valgrind (L<http://valgrind.org>) even though by
default it does not bother running it with the tests because valgrind
will significantly slow down the test sutie.
First ensure that your valgrind executable visible in your PATH env.
And then run your test suite with the C<TEST_NGINX_USE_VALGRIND> env set
to true:
TEST_NGINX_USE_VALGRIND=1 prove -r t
If you see false alarms, you do have a chance to skip them by defining
a ./valgrind.suppress file at the root of your module source tree, as
in
L<https://github.com/chaoslawful/drizzle-nginx-module/blob/master/valgrind.suppress>
This is the suppression file for ngx_drizzle. Test::Nginx will
automatically use it to start nginx with valgrind memcheck if this
file does exist at the expected location.
If you do see a lot of "Connection refused" errors while running the
tests this way, then you probably have a slow machine (or a very busy
one) that the default waiting time is not sufficient for valgrind to
start. You can define the sleep time to a larger value by setting the
C<TEST_NGINX_SLEEP> env:
TEST_NGINX_SLEEP=1 prove -r t
The time unit used here is "second". The default sleep setting just
fits my ThinkPad (C<Core2Duo T9600>).
Applying the no-pool patch to your nginx core is recommended while
running nginx with valgrind:
L<https://github.com/shrimp/no-pool-nginx>
The nginx memory pool can prevent valgrind from spotting lots of
invalid memory reads/writes as well as certain double-free errors. We
did find a lot more memory issues in many of our modules when we first
introduced the no-pool patch in practice ;)
There's also more advanced features in Test::Nginx that have never
documented. I'd like to write more about them in the near future ;)
=head1 Nginx C modules that use Test::Nginx to drive their test suites
=over
=item ngx_echo
L<http://github.com/agentzh/echo-nginx-module>
=item ngx_headers_more
L<http://github.com/agentzh/headers-more-nginx-module>
=item ngx_chunkin
L<http://wiki.nginx.org/NginxHttpChunkinModule>
=item ngx_memc
L<http://wiki.nginx.org/NginxHttpMemcModule>
=item ngx_drizzle
L<http://github.com/chaoslawful/drizzle-nginx-module>
=item ngx_rds_json
L<http://github.com/agentzh/rds-json-nginx-module>
=item ngx_xss
L<http://github.com/agentzh/xss-nginx-module>
=item ngx_srcache
L<http://github.com/agentzh/srcache-nginx-module>
=item ngx_lua
L<http://github.com/chaoslawful/lua-nginx-module>
=item ngx_set_misc
L<http://github.com/agentzh/set-misc-nginx-module>
=item ngx_array_var
L<http://github.com/agentzh/array-var-nginx-module>
=item ngx_form_input
L<http://github.com/calio/form-input-nginx-module>
=item ngx_iconv
L<http://github.com/calio/iconv-nginx-module>
=item ngx_set_cconv
L<http://github.com/liseen/set-cconv-nginx-module>
=item ngx_postgres
L<http://github.com/FRiCKLE/ngx_postgres>
=item ngx_coolkit
L<http://github.com/FRiCKLE/ngx_coolkit>
=back
=head1 SOURCE REPOSITORY
This module has a Git repository on Github, which has access for all.
http://github.com/agentzh/test-nginx
If you want a commit bit, feel free to drop me a line.
=head1 AUTHORS
agentzh (章亦春) C<< <agentzh@gmail.com> >>
Antoine BONAVITA C<< <antoine.bonavita@gmail.com> >>
=head1 COPYRIGHT & LICENSE
Copyright (c) 2009-2011, Taobao Inc., Alibaba Group (L<http://www.taobao.com>).
Copyright (c) 2009-2011, agentzh C<< <agentzh@gmail.com> >>.
Copyright (c) 2011, Antoine Bonavita C<< <antoine.bonavita@gmail.com> >>.
This module is licensed under the terms of the BSD license.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
=over
=item *
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
=item *
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
=item *
Neither the name of the Taobao Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
=back
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=head1 SEE ALSO
L<Test::Nginx::LWP>, L<Test::Nginx::Socket>, L<Test::Base>.

View file

@ -0,0 +1,508 @@
package Test::Nginx::LWP;
use lib 'lib';
use lib 'inc';
use Test::Base -Base;
our $VERSION = '0.17';
our $NoLongString;
use LWP::UserAgent;
use Time::HiRes qw(sleep);
use Test::LongString;
use Test::Nginx::Util qw(
setup_server_root
write_config_file
get_canon_version
get_nginx_version
trim
show_all_chars
parse_headers
run_tests
$ServerPortForClient
$PidFile
$ServRoot
$ConfFile
$ServerPort
$RunTestHelper
$NoNginxManager
$RepeatEach
worker_connections
master_process_enabled
master_on
master_off
config_preamble
repeat_each
no_shuffle
no_root_location
);
our $UserAgent = LWP::UserAgent->new;
$UserAgent->agent(__PACKAGE__);
#$UserAgent->default_headers(HTTP::Headers->new);
#use Smart::Comments::JSON '##';
our @EXPORT = qw( plan run_tests run_test
repeat_each config_preamble worker_connections
master_process_enabled master_on master_off
no_long_string no_shuffle no_root_location);
sub no_long_string () {
$NoLongString = 1;
}
sub run_test_helper ($$);
$RunTestHelper = \&run_test_helper;
sub parse_request ($$) {
my ($name, $rrequest) = @_;
open my $in, '<', $rrequest;
my $first = <$in>;
if (!$first) {
Test::More::BAIL_OUT("$name - Request line should be non-empty");
die;
}
$first =~ s/^\s+|\s+$//g;
my ($meth, $rel_url) = split /\s+/, $first, 2;
my $url = "http://localhost:$ServerPortForClient" . $rel_url;
my $content = do { local $/; <$in> };
if ($content) {
$content =~ s/^\s+|\s+$//s;
}
close $in;
return {
method => $meth,
url => $url,
content => $content,
};
}
sub chunk_it ($$$) {
my ($chunks, $start_delay, $middle_delay) = @_;
my $i = 0;
return sub {
if ($i == 0) {
if ($start_delay) {
sleep($start_delay);
}
} elsif ($middle_delay) {
sleep($middle_delay);
}
return $chunks->[$i++];
}
}
sub run_test_helper ($$) {
my ($block, $dry_run) = @_;
my $request = $block->request;
my $name = $block->name;
#if (defined $TODO) {
#$name .= "# $TODO";
#}
my $req_spec = parse_request($name, \$request);
## $req_spec
my $method = $req_spec->{method};
my $req = HTTP::Request->new($method);
my $content = $req_spec->{content};
if (defined ($block->request_headers)) {
my $headers = parse_headers($block->request_headers);
while (my ($key, $val) = each %$headers) {
$req->header($key => $val);
}
}
#$req->header('Accept', '*/*');
$req->url($req_spec->{url});
if ($content) {
if ($method eq 'GET' or $method eq 'HEAD') {
croak "HTTP 1.0/1.1 $method request should not have content: $content";
}
$req->content($content);
} elsif ($method eq 'POST' or $method eq 'PUT') {
my $chunks = $block->chunked_body;
if (defined $chunks) {
if (!ref $chunks or ref $chunks ne 'ARRAY') {
Test::More::BAIL_OUT("$name - --- chunked_body should takes a Perl array ref as its value");
}
my $start_delay = $block->start_chunk_delay || 0;
my $middle_delay = $block->middle_chunk_delay || 0;
$req->content(chunk_it($chunks, $start_delay, $middle_delay));
if (!defined $req->header('Content-Type')) {
$req->header('Content-Type' => 'text/plain');
}
} else {
if (!defined $req->header('Content-Type')) {
$req->header('Content-Type' => 'text/plain');
}
$req->header('Content-Length' => 0);
}
}
if ($block->more_headers) {
my @headers = split /\n+/, $block->more_headers;
for my $header (@headers) {
next if $header =~ /^\s*\#/;
my ($key, $val) = split /:\s*/, $header, 2;
#warn "[$key, $val]\n";
$req->header($key => $val);
}
}
#warn "req: ", $req->as_string, "\n";
#warn "DONE!!!!!!!!!!!!!!!!!!!!";
my $res = HTTP::Response->new;
unless ($dry_run) {
$res = $UserAgent->request($req);
}
#warn "res returned!!!";
if ($dry_run) {
SKIP: {
Test::More::skip("$name - tests skipped due to the lack of directive $dry_run", 1);
}
} else {
if (defined $block->error_code) {
is($res->code, $block->error_code, "$name - status code ok");
} else {
is($res->code, 200, "$name - status code ok");
}
}
if (defined $block->response_headers) {
my $headers = parse_headers($block->response_headers);
while (my ($key, $val) = each %$headers) {
my $expected_val = $res->header($key);
if (!defined $expected_val) {
$expected_val = '';
}
if ($dry_run) {
SKIP: {
Test::More::skip("$name - tests skipped due to the lack of directive $dry_run", 1);
}
} else {
is $expected_val, $val,
"$name - header $key ok";
}
}
} elsif (defined $block->response_headers_like) {
my $headers = parse_headers($block->response_headers_like);
while (my ($key, $val) = each %$headers) {
my $expected_val = $res->header($key);
if (!defined $expected_val) {
$expected_val = '';
}
if ($dry_run) {
SKIP: {
Test::More::skip("$name - tests skipped due to the lack of directive $dry_run", 1);
}
} else {
like $expected_val, qr/^$val$/,
"$name - header $key like ok";
}
}
}
if (defined $block->response_body) {
my $content = $res->content;
if (defined $content) {
$content =~ s/^TE: deflate,gzip;q=0\.3\r\n//gms;
}
$content =~ s/^Connection: TE, close\r\n//gms;
my $expected = $block->response_body;
$expected =~ s/\$ServerPort\b/$ServerPort/g;
$expected =~ s/\$ServerPortForClient\b/$ServerPortForClient/g;
#warn show_all_chars($content);
if ($dry_run) {
SKIP: {
Test::More::skip("$name - tests skipped due to the lack of directive $dry_run", 1);
}
} else {
if ($NoLongString) {
is($content, $expected, "$name - response_body - response is expected");
} else {
is_string($content, $expected, "$name - response_body - response is expected");
}
#is($content, $expected, "$name - response_body - response is expected");
}
} elsif (defined $block->response_body_like) {
my $content = $res->content;
if (defined $content) {
$content =~ s/^TE: deflate,gzip;q=0\.3\r\n//gms;
}
$content =~ s/^Connection: TE, close\r\n//gms;
my $expected_pat = $block->response_body_like;
$expected_pat =~ s/\$ServerPort\b/$ServerPort/g;
$expected_pat =~ s/\$ServerPortForClient\b/$ServerPortForClient/g;
my $summary = trim($content);
if ($dry_run) {
SKIP: {
Test::More::skip("$name - tests skipped due to the lack of directive $dry_run", 1);
}
} else {
like($content, qr/$expected_pat/s, "$name - response_body_like - response is expected ($summary)");
}
}
}
1;
__END__
=encoding utf-8
=head1 NAME
Test::Nginx::LWP - LWP-backed test scaffold for the Nginx C modules
=head1 SYNOPSIS
use Test::Nginx::LWP;
plan tests => $Test::Nginx::LWP::RepeatEach * 2 * blocks();
run_tests();
__DATA__
=== TEST 1: sanity
--- config
location /echo {
echo_before_body hello;
echo world;
}
--- request
GET /echo
--- response_body
hello
world
--- error_code: 200
=== TEST 2: set Server
--- config
location /foo {
echo hi;
more_set_headers 'Server: Foo';
}
--- request
GET /foo
--- response_headers
Server: Foo
--- response_body
hi
=== TEST 3: clear Server
--- config
location /foo {
echo hi;
more_clear_headers 'Server: ';
}
--- request
GET /foo
--- response_headers_like
Server: nginx.*
--- response_body
hi
=== TEST 4: set request header at client side and rewrite it
--- config
location /foo {
more_set_input_headers 'X-Foo: howdy';
echo $http_x_foo;
}
--- request
GET /foo
--- request_headers
X-Foo: blah
--- response_headers
X-Foo:
--- response_body
howdy
=== TEST 3: rewrite content length
--- config
location /bar {
more_set_input_headers 'Content-Length: 2048';
echo_read_request_body;
echo_request_body;
}
--- request eval
"POST /bar\n" .
"a" x 4096
--- response_body eval
"a" x 2048
=== TEST 4: timer without explicit reset
--- config
location /timer {
echo_sleep 0.03;
echo "elapsed $echo_timer_elapsed sec.";
}
--- request
GET /timer
--- response_body_like
^elapsed 0\.0(2[6-9]|3[0-6]) sec\.$
=== TEST 5: small buf (using 2-byte buf)
--- config
chunkin on;
location /main {
client_body_buffer_size 2;
echo "body:";
echo $echo_request_body;
echo_request_body;
}
--- request
POST /main
--- start_chunk_delay: 0.01
--- middle_chunk_delay: 0.01
--- chunked_body eval
["hello", "world"]
--- error_code: 200
--- response_body eval
"body:
helloworld"
=head1 DESCRIPTION
This module provides a test scaffold based on L<LWP::UserAgent> for automated testing in Nginx C module development.
This class inherits from L<Test::Base>, thus bringing all its
declarative power to the Nginx C module testing practices.
You need to terminate or kill any Nginx processes before running the test suite if you have changed the Nginx server binary. Normally it's as simple as
killall nginx
PATH=/path/to/your/nginx-with-memc-module:$PATH prove -r t
This module will create a temporary server root under t/servroot/ of the current working directory and starts and uses the nginx executable in the PATH environment.
You will often want to look into F<t/servroot/logs/error.log>
when things go wrong ;)
=head1 Sections supported
The following sections are supported:
=over
=item config
=item http_config
=item request
=item request_headers
=item more_headers
=item response_body
=item response_body_like
=item response_headers
=item response_headers_like
=item error_code
=item chunked_body
=item middle_chunk_delay
=item start_chunk_delay
=back
=head1 Samples
You'll find live samples in the following Nginx 3rd-party modules:
=over
=item ngx_echo
L<http://wiki.nginx.org/NginxHttpEchoModule>
=item ngx_headers_more
L<http://wiki.nginx.org/NginxHttpHeadersMoreModule>
=item ngx_chunkin
L<http://wiki.nginx.org/NginxHttpChunkinModule>
=item ngx_memc
L<http://wiki.nginx.org/NginxHttpMemcModule>
=back
=head1 SOURCE REPOSITORY
This module has a Git repository on Github, which has access for all.
http://github.com/agentzh/test-nginx
If you want a commit bit, feel free to drop me a line.
=head1 AUTHOR
agentzh (章亦春) C<< <agentzh@gmail.com> >>
=head1 COPYRIGHT & LICENSE
Copyright (c) 2009-2011, Taobao Inc., Alibaba Group (L<http://www.taobao.com>).
Copyright (c) 2009-2011, agentzh C<< <agentzh@gmail.com> >>.
This module is licensed under the terms of the BSD license.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
=over
=item *
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
=item *
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
=item *
Neither the name of the Taobao Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
=back
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=head1 SEE ALSO
L<Test::Nginx::Socket>, L<Test::Base>.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff