aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--bulkredirect.lua21
-rw-r--r--t/a.tab6
-rw-r--r--t/b.tab6
-rw-r--r--t/c.tab9
-rw-r--r--t/d.tab11
-rw-r--r--t/haproxy.cfg.in13
-rwxr-xr-xt/testsuite389
8 files changed, 453 insertions, 6 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..65dc152
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*~
+\#*
+.emacs*
+tmp/
diff --git a/bulkredirect.lua b/bulkredirect.lua
index 20666ca..522d570 100644
--- a/bulkredirect.lua
+++ b/bulkredirect.lua
@@ -171,6 +171,11 @@ function bulkredirect.request (txn)
end
if location then
+ if not (location:match('^http://') or location:match('^https://')
+ or location:match('^/')) then
+ location = '/'..location
+ end
+
if not exact or i == path or i..'/' == path then
if not strippath then
location = location .. path:sub(i:len() + 1)
@@ -338,19 +343,19 @@ local function load_redirect_file (f, filename)
parseopt(optlist, optab, filename .. ':' .. ln)
end
- if optab['exact'] then
+ if optab['exact'] ~= exact then
if type(dst) == 'string' then dst = { dst } end
dst[2] = optab['exact']
end
- if optab['strippath'] then
+ if optab['strippath'] ~= strippath then
if type(dst) == 'string' then dst = { dst } end
dst[3] = optab['strippath']
end
- if optab['stripquery'] then
+ if optab['stripquery'] ~= stripquery then
if type(dst) == 'string' then dst = { dst } end
dst[4] = optab['stripquery']
end
- if optab['temporary'] then
+ if optab['temporary'] ~= temporary then
if type(dst) == 'string' then dst = { dst } end
dst[5] = optab['temporary']
end
@@ -399,17 +404,21 @@ local function load_redirect_file (f, filename)
end
if www then
+ crt = {}
for d,t in pairs(rt) do
local compl = www_complement(d)
if rt[compl] then
for k,v in pairs(t) do
-- FIXME: Error message if rt[compl][k] exists
- rt[compl][k] = clone(v)
+ crt[compl][k] = clone(v)
end
else
- rt[compl] = d
+ crt[compl] = d
end
end
+ for d,t in pairs(crt) do
+ rt[d] = t
+ end
www = nil
end
diff --git a/t/a.tab b/t/a.tab
new file mode 100644
index 0000000..09aa015
--- /dev/null
+++ b/t/a.tab
@@ -0,0 +1,6 @@
+[example.com]
+/foo /alpha
+/foo/bar /beta
+/foo/bar/baz /gamma
+
+
diff --git a/t/b.tab b/t/b.tab
new file mode 100644
index 0000000..3e2e928
--- /dev/null
+++ b/t/b.tab
@@ -0,0 +1,6 @@
+option www
+[example.com]
+/foo /alpha
+/foo/bar /beta
+/foo/bar/baz /gamma nowww
+
diff --git a/t/c.tab b/t/c.tab
new file mode 100644
index 0000000..1a822af
--- /dev/null
+++ b/t/c.tab
@@ -0,0 +1,9 @@
+[*]
+/foo /alpha
+/foo/bar /beta
+[example.org]
+/foo/bar/baz /gamma
+/foo /delta exact
+/bar /epsilon strippath
+/baz /zeta stripquery
+/dux /eta temporary
diff --git a/t/d.tab b/t/d.tab
new file mode 100644
index 0000000..c097565
--- /dev/null
+++ b/t/d.tab
@@ -0,0 +1,11 @@
+option www,strippath,stripquery
+[example.org]
+/a /A
+/b /B nostrippath
+option nostrippath
+/c /C
+/d /D nowww
+option nostripquery
+/e /E
+
+
diff --git a/t/haproxy.cfg.in b/t/haproxy.cfg.in
new file mode 100644
index 0000000..bcc5884
--- /dev/null
+++ b/t/haproxy.cfg.in
@@ -0,0 +1,13 @@
+global
+ lua-load %TOPDIR%/bulkredirect.lua
+ daemon
+
+defaults
+ timeout connect 5
+ timeout client 5
+ timeout server 5
+
+frontend http-in
+ mode http
+ bind :::%PORT% v4v6
+ http-request lua.bulkredirect
diff --git a/t/testsuite b/t/testsuite
new file mode 100755
index 0000000..69b4325
--- /dev/null
+++ b/t/testsuite
@@ -0,0 +1,389 @@
+#!/bin/sh
+
+sourcename=bulkredirect.lua
+
+while getopts "b:C:p:" OPTION
+do
+ case $OPTION in
+ C) cd $OPTARG || exit 2;;
+ p) haproxy_port=$OPTARG;;
+ b) haproxy_bin=$OPTARG;;
+ *) echo >&2 "$0: usage error"
+ exit 2
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+if [ ! -f haproxy.cfg.in ]; then
+ echo >&2 "$0: must be run from the t/ subdirectory"
+ exit 2
+fi
+if [ ! -f ../$sourcename ]; then
+ echo >&2 "$0: must be run from the t/ subdirectory"
+ exit 2
+fi
+
+top_srcdir=$(cd ..; pwd)
+testsource_dir=$(pwd)
+PATH=/usr/sbin:$PATH
+testsuite_dir=$(pwd)/testsuite.dir
+numfile=$testsuite_dir/numbers
+: ${haproxy_bin:=haproxy}
+: ${haproxy_port:=8080}
+
+# Check if haproxy is installed
+if ! $haproxy_bin -v >/dev/null 2>&1; then
+ echo >&2 "$0: haproxy not installed or unusable"
+ exit 2
+fi
+
+# Test if egrep is installed
+if ! egrep --help >/dev/null 2>&1; then
+ echo >&2 "$0: egrep not installed or unusable"
+ exit 2
+fi
+
+# Test if curl is installed
+if ! curl --help >/dev/null 2>&1; then
+ echo >&2 "$0: curl not installed or unusable"
+ exit 2
+fi
+
+# Test if nc is available and supports the -z option
+if ! nc -h 2>&1 | egrep -q '^[[:space:]]+-z'; then
+ echo >&2 "$0: nc is not available or does not support -z option"
+ exit 2
+fi
+
+# Test if sleep supports sub-second resolution
+if sleep 0.1 >/dev/null 2>&1; then
+ haproxy_sleep_time=0.1
+ haproxy_start_init=20
+else
+ haproxy_sleep_time=1
+ haproxy_start_init=2
+fi
+
+# Test if the requested port is not in use
+if nc -z -w5 127.0.0.1 $haproxy_port 2>/dev/null; then
+ echo >&2 "$0: requested port $haproxy_port is in use; use -p option to select another port"
+ exit 2
+fi
+
+haproxy_create_config() {
+ sed -e "s^%PORT%^$haproxy_port^" -e "s^%TOPDIR%^$top_srcdir^" \
+ $testsource_dir/haproxy.cfg.in > $testsuite_dir/haproxy.cfg
+}
+
+haproxy_start() {
+ ( export HAPROXY_BULKREDIRECT=$testsource_dir/$1
+ exec > $testsuite_dir/$test_num/haproxy.err
+ exec 2>&1
+ exec $haproxy_bin -f $testsuite_dir/haproxy.cfg -db ) &
+ echo $! > $testsuite_dir/$test_num/haproxy.pid
+ haproxy_start_result=$haproxy_start_init
+ while ! nc -z -w5 127.0.0.1 $haproxy_port 2>/dev/null
+ do
+ if [ $haproxy_start_result -eq 0 ]; then
+ break
+ fi
+ haproxy_start_result=$(($haproxy_start_result - 1))
+ sleep $haproxy_sleep_time
+ done
+ if [ $haproxy_start_result -gt 0 ]; then
+ trap 'haproxy_stop' HUP INT QUIT TERM
+ fi
+}
+
+haproxy_stop() {
+ if [ -f $testsuite_dir/$test_num/haproxy.pid ]; then
+ kill $(cat $testsuite_dir/$test_num/haproxy.pid) >/dev/null 2>&1
+ fi
+}
+
+test_num=1
+
+# runtest
+runtest() {
+ local RTFILE
+ local HTTP_CODE=301
+ local URL
+ local HTTP_LOCATION
+ local DESCR=
+
+ while [ $# -gt 0 ]
+ do
+ case $1 in
+ DESCR=*)
+ DESCR=${1##DESCR=};;
+ RTFILE=*)
+ RTFILE=${1##RTFILE=};;
+ HTTP_CODE=*)
+ HTTP_CODE=${1##HTTP_CODE=};;
+ HTTP_LOCATION=*)
+ HTTP_LOCATION=${1##HTTP_LOCATION=};;
+ URL=*)
+ URL=${1##URL=};;
+ *)
+ echo >&2 "$0: INTERNAL ERROR: bad argument $1"
+ exit 3
+ esac
+ shift
+ done
+
+ if [ -z "$RTFILE" ]; then
+ echo >&2 "$0: INTERNAL ERROR: RTFILE not defined"
+ exit 3
+ fi
+
+ if [ -z "$URL" ]; then
+ echo >&2 "$0: INTERNAL ERROR: URL not defined"
+ exit 3
+ fi
+
+ rm -rf $testsuite_dir/$test_num
+ if [ -f $numfile ] && ! grep -q "^$test_num\$" $numfile; then
+ :
+ else
+ mkdir $testsuite_dir/$test_num
+ cd $testsuite_dir/$test_num
+ printf "%4d: %-60s " $test_num "${DESCR:-$URL}"
+ haproxy_start $RTFILE
+ if [ $haproxy_start_result -eq 0 ]; then
+ runtest_result=ERR
+ else
+ HOST=${URL%%/*}
+ URI=/${URL#*/}
+ curl -q -sS --stderr stderr -o stdout -D headers \
+ --connect-timeout 2 \
+ -H "Host: $HOST" "http://localhost:$haproxy_port$URI"
+ if [ $? -ne 0 ]; then
+ runtest_result=FAIL
+ else
+ cat headers | tr -d '\r' > headers.txt
+ http_code=$(sed -n -e '1s^HTTP/1\.1 \([0-9][0-9][0-9]\).*^\1^p' headers.txt)
+ http_location=$(sed -n -e 's/^location: //ip' headers.txt)
+ if [ -n "$HTTP_CODE" ] && [ "$http_code" != "$HTTP_CODE" ]; then
+ runtest_result=FAIL
+ elif [ -n "$HTTP_LOCATION" ] && [ "$http_location" != "$HTTP_LOCATION" ]; then
+ runtest_result=FAIL
+ else
+ runtest_result=OK
+ fi
+ fi
+ fi
+ printf "$runtest_result\n"
+ haproxy_stop
+ cd $testsuite_dir
+ case $runtest_result in
+ OK|XFAIL)
+ runtest_success_count=$(($runtest_success_count + 1))
+ rm -rf $test_num;;
+ *)
+ runtest_failure_count=$(($runtest_failure_count + 1))
+ esac
+ fi
+ test_num=$(($test_num + 1))
+}
+
+# ##############
+set -e
+rm -rf testsuite.dir
+mkdir testsuite.dir
+
+if [ $# -gt 0 ]; then
+ while [ $# -gt 0 ]
+ do
+ echo "$1"
+ shift
+ done > $numfile
+fi
+set +e
+
+group_header() {
+ echo
+ echo "# $* #" | sed -e 's/./#/g'
+ echo "# $* #"
+ echo "# $* #" | sed -e 's/./#/g'
+ echo
+}
+
+# ####################
+# Start tests
+haproxy_create_config
+
+runtest_success_count=0
+runtest_failure_count=0
+
+# ####################
+group_header Basic functionality
+
+runtest \
+ RTFILE=a.tab \
+ URL=example.com/foo \
+ HTTP_CODE=301 \
+ HTTP_LOCATION=/alpha
+
+runtest \
+ RTFILE=a.tab \
+ URL=example.com/foo/bar \
+ HTTP_LOCATION=/beta
+
+runtest \
+ RTFILE=a.tab \
+ URL=example.com/foo/bar/baz \
+ HTTP_LOCATION=/gamma
+
+runtest \
+ RTFILE=a.tab \
+ URL=example.com/foo/bar/mugu?q=1 \
+ HTTP_LOCATION=/beta/mugu?q=1
+
+runtest \
+ RTFILE=a.tab \
+ URL=example.org/foo \
+ HTTP_CODE=503
+
+# ####################
+group_header www option
+
+runtest \
+ RTFILE=b.tab \
+ URL=example.com/foo \
+ HTTP_LOCATION=/alpha
+
+runtest \
+ RTFILE=b.tab \
+ URL=www.example.com/foo \
+ HTTP_LOCATION=/alpha
+
+runtest \
+ RTFILE=b.tab \
+ URL=example.com/foo/bar \
+ HTTP_LOCATION=/beta
+
+runtest \
+ RTFILE=b.tab \
+ URL=example.com/foo/bar/baz \
+ HTTP_LOCATION=/gamma
+
+runtest \
+ RTFILE=b.tab \
+ URL=www.example.com/foo/bar/baz \
+ HTTP_LOCATION=/beta/baz
+
+runtest \
+ RTFILE=b.tab \
+ URL=example.com/foo/bar/mugu?q=1
+ HTTP_LOCATION=/beta/mugu?q=1
+
+# ####################
+group_header Default domain
+
+runtest \
+ RTFILE=c.tab \
+ URL=example.com/foo \
+ HTTP_LOCATION=/alpha
+
+runtest \
+ RTFILE=c.tab \
+ URL=www.example.com/foo \
+ HTTP_LOCATION=/alpha
+
+runtest \
+ RTFILE=c.tab \
+ URL=example.com/foo/bar/baz \
+ HTTP_LOCATION=/beta/baz
+
+runtest \
+ RTFILE=c.tab \
+ DESCR="Explicit domain" \
+ URL=example.org/foo/bar/baz \
+ HTTP_LOCATION=/gamma
+
+runtest \
+ RTFILE=c.tab \
+ DESCR="'exact' modifier: match" \
+ URL=example.org/foo \
+ HTTP_LOCATION=/delta \
+
+runtest \
+ RTFILE=c.tab \
+ DESCR="'exact' modifier: prefix match" \
+ URL=example.org/foo/bar \
+ HTTP_CODE=503
+
+runtest \
+ RTFILE=c.tab \
+ DESCR="strippath" \
+ URL=example.org/bar/baz/qux \
+ HTTP_LOCATION=/epsilon
+
+runtest \
+ RTFILE=c.tab \
+ DESCR="stripquery" \
+ URL=example.org/baz?q=10 \
+ HTTP_LOCATION=/zeta
+
+runtest \
+ RTFILE=c.tab \
+ DESCR="temporary" \
+ URL=example.org/dux \
+ HTTP_LOCATION=/eta \
+ HTTP_CODE=302
+
+# ####################
+group_header Option precedence
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="strippath" \
+ URL=example.org/a \
+ HTTP_LOCATION=/A
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="strippath: prefix" \
+ URL=example.org/a/b \
+ HTTP_LOCATION=/A
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="strippath: local override" \
+ URL=example.org/b/suffix \
+ HTTP_LOCATION=/B/suffix
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="strippath: option override" \
+ URL=example.org/c/suffix \
+ HTTP_LOCATION=/C/suffix
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="strippath: option override + local override (1)" \
+ URL=example.org/d/suffix \
+ HTTP_LOCATION=/D/suffix
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="strippath: option override + local override (2)" \
+ URL=www.example.org/d/suffix \
+ HTTP_CODE=503
+
+runtest \
+ RTFILE=d.tab \
+ DESCR="override additivity" \
+ URL=example.org/e/suffix?q=10 \
+ HTTP_LOCATION=/E/suffix?q=10
+
+echo
+echo "Run $(($runtest_success_count + $runtest_failure_count)) tests."
+if [ $runtest_failure_count -eq 0 ]; then
+ echo "All tests passed"
+ rm -rf $testsuite_dir
+else
+ echo "$runtest_failure_count failed unexpectedly."
+ echo "Examine the testsuite.dir directory."
+fi

Return to:

Send suggestions and report system problems to the System administrator.