2021-01-22 17:48:04 +01:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
2021-07-10 11:09:26 +02:00
|
|
|
if [ "${SKIP_RUNTIME_TESTS:-0}" -eq 1 ]; then
|
2021-07-08 17:13:17 +02:00
|
|
|
echo
|
|
|
|
echo "======================"
|
|
|
|
echo "runtime tests skipped!"
|
|
|
|
echo "======================"
|
|
|
|
echo
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2021-02-09 23:30:04 +01:00
|
|
|
ggflags=
|
|
|
|
|
2021-07-19 13:15:44 +02:00
|
|
|
port=10965
|
|
|
|
|
|
|
|
config_common="
|
2021-07-06 13:52:28 +02:00
|
|
|
ipv6 off
|
2021-07-19 13:15:44 +02:00
|
|
|
port $port
|
|
|
|
"
|
2021-07-06 13:52:28 +02:00
|
|
|
|
2021-01-22 17:48:04 +01:00
|
|
|
# usage: config <global config> <stuff for localhost>
|
|
|
|
# generates a configuration file reg.conf
|
|
|
|
config() {
|
|
|
|
cat <<EOF > reg.conf
|
2021-07-06 13:52:28 +02:00
|
|
|
$config_common
|
2021-01-22 17:48:04 +01:00
|
|
|
$1
|
|
|
|
server "localhost" {
|
2021-02-01 12:04:21 +01:00
|
|
|
cert "$PWD/cert.pem"
|
|
|
|
key "$PWD/key.pem"
|
|
|
|
root "$PWD/testdata"
|
2021-01-22 17:48:04 +01:00
|
|
|
$2
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
checkconf() {
|
|
|
|
./../gmid -n -c reg.conf
|
|
|
|
}
|
|
|
|
|
|
|
|
# usage: get <path>
|
|
|
|
# return the body of the request on stdout
|
|
|
|
get() {
|
2021-07-06 15:09:24 +02:00
|
|
|
./gg -T30 -b $ggflags "gemini://localhost:10965/$1"
|
2021-01-22 17:48:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# usage: head <path>
|
|
|
|
# return the meta response line on stdout
|
|
|
|
head() {
|
2021-07-06 15:09:24 +02:00
|
|
|
./gg -T30 -h $ggflags "gemini://localhost:10965/$1"
|
2021-01-23 18:10:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# usage: raw <path>
|
|
|
|
# return both header and body
|
|
|
|
raw() {
|
2021-07-06 15:09:24 +02:00
|
|
|
./gg -T30 $ggflags "gemini://localhost:10965/$1"
|
2021-01-22 17:48:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
run() {
|
2021-07-06 13:53:24 +02:00
|
|
|
./../gmid -f -c reg.conf &
|
2021-01-22 17:48:04 +01:00
|
|
|
pid=$!
|
2021-01-23 18:10:00 +01:00
|
|
|
# give gmid time to bind the port, otherwise we end up
|
|
|
|
# executing gg when gmid isn't ready yet.
|
|
|
|
sleep 1
|
2021-01-22 17:48:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# usage: check [exit-message]
|
|
|
|
# check if gmid is still running
|
|
|
|
check() {
|
|
|
|
if ! ps $pid >/dev/null; then
|
|
|
|
echo ${1:-"gmid crashed?"}
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-02-06 18:35:48 +01:00
|
|
|
restart() {
|
2021-03-20 09:51:58 +01:00
|
|
|
kill -HUP $pid
|
2021-02-06 18:35:48 +01:00
|
|
|
sleep 1
|
|
|
|
}
|
|
|
|
|
2021-01-22 17:48:04 +01:00
|
|
|
# quit gmid
|
|
|
|
quit() {
|
2021-03-20 09:51:58 +01:00
|
|
|
kill $pid || true
|
2021-01-22 17:48:04 +01:00
|
|
|
wait || true
|
|
|
|
}
|
|
|
|
|
2021-02-07 19:55:04 +01:00
|
|
|
count() {
|
|
|
|
wc -l | xargs
|
|
|
|
}
|
|
|
|
|
2021-01-22 17:48:04 +01:00
|
|
|
# usage: eq a b errmsg
|
|
|
|
# if a and b aren't equal strings, exit with errmsg
|
|
|
|
eq() {
|
|
|
|
if ! [ "$1" = "$2" ]; then
|
|
|
|
echo "$3: \"$1\" not equal \"$2\""
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
onexit() {
|
|
|
|
rm -f bigfile bigfile.sha
|
|
|
|
quit
|
|
|
|
}
|
|
|
|
|
2021-07-19 13:15:44 +02:00
|
|
|
# configless tests
|
|
|
|
|
2021-07-19 13:37:01 +02:00
|
|
|
./../gmid -p $port -H localhost -d . testdata &
|
2021-07-19 13:15:44 +02:00
|
|
|
pid=$!
|
|
|
|
sleep 1
|
|
|
|
|
|
|
|
eq "$(head /)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
eq "$(get /)" "# hello world$ln" "Unexpected body for /"
|
|
|
|
echo OK GET / in configless mode
|
|
|
|
quit
|
|
|
|
|
|
|
|
# daemon tests
|
2021-01-22 17:48:04 +01:00
|
|
|
|
|
|
|
trap 'onexit' INT TERM EXIT
|
|
|
|
|
|
|
|
endl=`printf "\r\n"`
|
|
|
|
lf=`echo`
|
|
|
|
|
|
|
|
config "" ""
|
|
|
|
checkconf
|
|
|
|
run
|
|
|
|
|
|
|
|
eq "$(head /)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
eq "$(get /)" "# hello world$ln" "Unexpected body for /"
|
|
|
|
echo OK GET /
|
|
|
|
|
|
|
|
eq "$(head /foo)" "51 not found" "Unexpected head /foo"
|
|
|
|
eq "$(get /foo)" "" "Unexpected body /foo"
|
|
|
|
echo OK GET /foo
|
|
|
|
|
|
|
|
# should redirect if asked for a directory but without the trailing /
|
|
|
|
eq "$(head /dir)" "30 /dir/" "Unexpected redirect for /dir"
|
|
|
|
eq "$(get /dir)" "" "Unexpected body for redirect"
|
|
|
|
echo OK GET /dir
|
|
|
|
|
|
|
|
# 51 for a directory without index.gmi
|
|
|
|
eq "$(head /dir/)" "51 not found" "Unexpected head for /"
|
|
|
|
eq "$(get /dir/)" "" "Unexpected body for error"
|
|
|
|
echo OK GET /dir/
|
|
|
|
|
|
|
|
eq "$(head /dir/foo.gmi)" "20 text/gemini" "Unexpected head for /dir/foo.gmi"
|
|
|
|
eq "$(get /dir/foo.gmi)" "# hello world$ln" "Unexpected body for /dir/foo.gmi"
|
|
|
|
echo OK GET /dir/foo.gmi
|
|
|
|
|
|
|
|
# try a big file
|
|
|
|
eq "$(head /bigfile)" "20 application/octet-stream" "Unexpected head for /bigfile"
|
|
|
|
get /bigfile > bigfile
|
|
|
|
./sha bigfile bigfile.sha
|
|
|
|
eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /bigfile"
|
|
|
|
echo OK GET /bigfile
|
|
|
|
|
|
|
|
# shouldn't be executing cgi scripts
|
|
|
|
eq "$(head /hello)" "20 application/octet-stream" "Unexpected head for /hello"
|
|
|
|
echo OK GET /hello
|
|
|
|
|
|
|
|
check "should be running"
|
|
|
|
|
|
|
|
# try with custom mime
|
2021-07-08 22:29:05 +02:00
|
|
|
config 'map "text/x-funny-text" to-ext "gmi"' 'default type "application/x-trash"'
|
2021-01-22 17:48:04 +01:00
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-01-22 17:48:04 +01:00
|
|
|
|
|
|
|
eq "$(head /)" "20 text/x-funny-text" "Unexpected head for /"
|
|
|
|
echo OK GET / with custom mime
|
|
|
|
|
|
|
|
eq "$(head /hello)" "20 application/x-trash" "Unexpected head for /hello"
|
|
|
|
echo OK GET /hello with custom mime
|
|
|
|
|
|
|
|
check "should be running"
|
|
|
|
|
|
|
|
# try with custom lang
|
|
|
|
config '' 'lang "it"'
|
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-01-22 17:48:04 +01:00
|
|
|
|
|
|
|
eq "$(head /)" "20 text/gemini; lang=it" "Unexpected head for /"
|
|
|
|
echo OK GET / with custom lang
|
|
|
|
|
|
|
|
check "should be running"
|
|
|
|
|
2021-02-10 17:37:08 +01:00
|
|
|
# make sure we can use different lang in different location rules
|
|
|
|
config '' 'lang "it" location "/en/*" { lang "en" } location "/de/*" { lang "de" }'
|
|
|
|
checkconf
|
2021-02-12 12:27:52 +01:00
|
|
|
echo OK parse multiple locations correctly
|
2021-02-10 17:37:08 +01:00
|
|
|
restart
|
|
|
|
|
2021-02-07 19:55:04 +01:00
|
|
|
# try with CGI scripts
|
2021-02-02 23:38:35 +01:00
|
|
|
config '' 'cgi "*"'
|
2021-01-22 17:48:04 +01:00
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-01-22 17:48:04 +01:00
|
|
|
|
|
|
|
eq "$(head /hello)" "20 text/gemini" "Unexpected head for /hello"
|
|
|
|
eq "$(get /hello)" "# hello world$ln" "Unexpected body for /hello"
|
|
|
|
echo OK GET /hello with cgi
|
|
|
|
|
|
|
|
eq "$(head /slow)" "20 text/gemini" "Unexpected head for /slow"
|
|
|
|
eq "$(get /slow)" "# hello world$ln" "Unexpected body for /slow"
|
|
|
|
echo OK GET /slow with cgi
|
|
|
|
|
2021-02-01 23:04:51 +01:00
|
|
|
eq "$(head /err)" "42 CGI error" "Unexpected head for /err"
|
2021-01-22 17:48:04 +01:00
|
|
|
eq "$(get /err)" "" "Unexpected body for /err"
|
|
|
|
echo OK GET /err with cgi
|
|
|
|
|
2021-01-23 18:44:23 +01:00
|
|
|
eq "$(raw /invalid | wc -c | xargs)" 2048 "Unexpected body for /invalid"
|
2021-01-23 16:32:38 +01:00
|
|
|
echo OK GET /invalid with cgi
|
|
|
|
|
2021-03-29 11:42:06 +02:00
|
|
|
eq "$(raw /max-length-reply | wc -c | xargs)" 1029 "Unexpected header for /max-length-reply"
|
|
|
|
echo OK GET /max-length-reply with cgi
|
|
|
|
|
2021-01-24 11:24:34 +01:00
|
|
|
# try a big file
|
|
|
|
eq "$(head /serve-bigfile)" "20 application/octet-stream" "Unexpected head for /serve-bigfile"
|
|
|
|
get /bigfile > bigfile
|
|
|
|
./sha bigfile bigfile.sha
|
|
|
|
eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /serve-bigfile"
|
|
|
|
echo OK GET /serve-bigfile with cgi
|
|
|
|
|
2021-02-07 19:55:04 +01:00
|
|
|
# ensure we split the query correctly
|
|
|
|
eq "$(get /env | awk /^-/ | count)" 1 "Unexpected number of arguments"
|
|
|
|
eq "$(get /env?foo | awk /^-/ | count)" 2 "Unexpected number of arguments"
|
|
|
|
eq "$(get /env?foo+bar | awk /^-/ | count)" 3 "Unexpected number of arguments"
|
|
|
|
eq "$(get /env?foo+bar=5 | awk /^-/ | count)" 1 "Unexpected number of arguments"
|
|
|
|
eq "$(get /env?foo+bar%3d5 | awk /^-/ | count)" 3 "Unexpected number of arguments"
|
|
|
|
|
2021-01-22 17:48:04 +01:00
|
|
|
check "should be running"
|
2021-01-24 10:14:01 +01:00
|
|
|
|
|
|
|
config '' 'index "foo.gmi"'
|
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-01-24 10:14:01 +01:00
|
|
|
|
|
|
|
eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
eq "$(get /dir/)" "# hello world$ln" "Unexpected body for error"
|
|
|
|
echo OK GET /dir/ with custom index
|
|
|
|
|
|
|
|
check "should be running"
|
2021-01-24 15:11:40 +01:00
|
|
|
|
2021-02-10 17:37:08 +01:00
|
|
|
config '' 'location "/dir/*" { default type "text/plain" index "hello" }'
|
2021-01-24 15:11:40 +01:00
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-01-24 15:11:40 +01:00
|
|
|
|
|
|
|
eq "$(head /dir/hello)" "20 text/plain" "Unexpected head for /"
|
|
|
|
echo OK GET /dir/hello with location and default type
|
|
|
|
|
2021-01-24 19:53:26 +01:00
|
|
|
eq "$(head /dir/)" "20 text/plain" "Unexpected head for /dir/"
|
2021-01-24 15:11:40 +01:00
|
|
|
eq "$(get /dir/|tail -1)" 'echo "# hello world"' "Unexpected body for /dir/"
|
|
|
|
echo OK GET /dir/ with location and custom index
|
|
|
|
|
|
|
|
check "should be running"
|
2021-01-24 19:53:26 +01:00
|
|
|
|
2021-02-10 17:37:08 +01:00
|
|
|
config '' 'location "/dir/*" { auto index on }'
|
2021-01-24 19:53:26 +01:00
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-01-24 19:53:26 +01:00
|
|
|
|
|
|
|
eq "$(head /)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
eq "$(get /)" "# hello world$ln" "Unexpected body for /"
|
|
|
|
echo OK GET / with auto index
|
|
|
|
|
|
|
|
eq "$(head /dir)" "30 /dir/" "Unexpected head for /dir"
|
|
|
|
eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /dir/"
|
2021-02-02 10:48:32 +01:00
|
|
|
eq "$(get /dir/|wc -l|xargs)" "5" "Unexpected body for /dir/"
|
2021-01-24 19:53:26 +01:00
|
|
|
echo OK GET /dir/ with auto index on
|
|
|
|
|
|
|
|
check "should be running"
|
2021-02-06 18:22:37 +01:00
|
|
|
|
|
|
|
# test block return and strip
|
|
|
|
|
|
|
|
config '' 'location "*" { block }'
|
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-02-06 18:22:37 +01:00
|
|
|
|
|
|
|
eq "$(head /)" "40 temporary failure" "Unexpected head for /"
|
|
|
|
eq "$(get /)" "" "Unexpected body for /"
|
|
|
|
echo OK GET / with block
|
|
|
|
|
|
|
|
eq "$(head /nonexists)" "40 temporary failure" "Unexpected head for /nonexists"
|
|
|
|
eq "$(get /nonexists)" "" "Unexpected body for /nonexists"
|
|
|
|
echo OK GET /nonexists with block
|
|
|
|
|
|
|
|
check "should be running"
|
|
|
|
|
|
|
|
config '' '
|
|
|
|
location "/dir" {
|
|
|
|
strip 1
|
|
|
|
block return 40 "%% %p %q %P %N test"
|
|
|
|
}
|
|
|
|
location "*" {
|
|
|
|
strip 99
|
|
|
|
block return 40 "%% %p %q %P %N test"
|
|
|
|
}'
|
|
|
|
checkconf
|
2021-02-06 18:35:48 +01:00
|
|
|
restart
|
2021-02-06 18:22:37 +01:00
|
|
|
|
|
|
|
eq "$(head /dir/foo.gmi)" "40 % /foo.gmi 10965 localhost test"
|
|
|
|
echo OK GET /dir/foo.gmi with strip and block
|
|
|
|
|
2021-04-30 21:07:37 +02:00
|
|
|
eq "$(head /bigfile)" "40 % / 10965 localhost test"
|
2021-02-06 18:22:37 +01:00
|
|
|
echo OK GET /bigfile with strip and block
|
|
|
|
|
|
|
|
check "should be running"
|
2021-02-06 18:35:48 +01:00
|
|
|
|
2021-02-06 19:28:43 +01:00
|
|
|
# test the entrypoint
|
|
|
|
|
|
|
|
config '' 'entrypoint "/env"'
|
|
|
|
checkconf
|
|
|
|
restart
|
|
|
|
|
|
|
|
eq "$(head /foo/bar)" "20 text/plain; lang=en" "Unknown head for /foo/bar"
|
|
|
|
eq "$(get /foo/bar|grep PATH_INFO)" "PATH_INFO=/foo/bar" "Unexpected PATH_INFO"
|
|
|
|
echo OK GET /foo/bar with entrypoint
|
|
|
|
|
2021-02-09 23:30:04 +01:00
|
|
|
# test with require ca
|
|
|
|
|
|
|
|
config '' 'require client ca "'$PWD'/testca.pem"'
|
|
|
|
checkconf
|
|
|
|
restart
|
|
|
|
|
|
|
|
eq "$(head /)" "60 client certificate required" "Unexpected head for /"
|
|
|
|
echo OK GET / without client certificate
|
|
|
|
|
|
|
|
ggflags="-C valid.crt -K valid.key"
|
|
|
|
eq "$(head /)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
echo OK GET / with valid client certificate
|
|
|
|
|
|
|
|
ggflags="-C invalid.cert.pem -K invalid.key.pem"
|
|
|
|
eq "$(head /)" "61 certificate not authorised" "Unexpected head for /"
|
|
|
|
echo OK GET / with invalid client certificate
|
|
|
|
|
|
|
|
ggflags=''
|
2021-04-30 19:16:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
# test with root inside a location
|
|
|
|
|
|
|
|
config '' 'location "/foo/*" { root "'$PWD'/testdata" strip 1 }'
|
|
|
|
checkconf
|
|
|
|
restart
|
|
|
|
|
2021-04-30 21:08:27 +02:00
|
|
|
eq "$(head /foo)" "51 not found" "Unexpected head for /foo"
|
|
|
|
eq "$(head /foo/)" "20 text/gemini" "Unexpected head for /foo/"
|
2021-06-12 15:47:01 +02:00
|
|
|
echo OK /foo and /foo/ with root inside location
|
2021-04-30 21:08:27 +02:00
|
|
|
|
|
|
|
# how to match both /foo and /foo/*
|
|
|
|
config '' '
|
|
|
|
location "/foo" { block return 31 "%p/" }
|
|
|
|
location "/foo/*" { root "'$PWD'/testdata" strip 1 }
|
|
|
|
'
|
|
|
|
checkconf
|
|
|
|
restart
|
2021-04-30 19:16:34 +02:00
|
|
|
|
2021-04-30 21:08:27 +02:00
|
|
|
eq "$(head /foo)" "31 /foo/" "Unexpected head for /foo"
|
2021-04-30 19:16:34 +02:00
|
|
|
eq "$(head /foo/)" "20 text/gemini" "Unexpected head for /foo/"
|
2021-06-12 15:47:01 +02:00
|
|
|
echo OK /foo and /foo/ with root inside location
|
|
|
|
|
|
|
|
# test with fastcgi
|
|
|
|
|
|
|
|
# NB: the fcgi spawn is NOT supported outside of this test suite
|
|
|
|
|
|
|
|
config 'prefork 1' 'fastcgi spawn "'$PWD'/fcgi-test"'
|
|
|
|
checkconf
|
|
|
|
restart
|
|
|
|
|
|
|
|
eq "$(head /)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
eq "$(get /)" "# Hello, world!" "Unexpected body for /"
|
|
|
|
echo OK GET / with fastcgi
|
2021-07-06 13:52:28 +02:00
|
|
|
|
|
|
|
# test macro expansion
|
|
|
|
|
|
|
|
cat <<EOF > reg.conf
|
|
|
|
pwd = "$PWD"
|
|
|
|
$config_common
|
|
|
|
|
|
|
|
server "localhost" {
|
|
|
|
# the quoting of \$ is for sh
|
|
|
|
cert \$pwd "/cert.pem"
|
|
|
|
key \$pwd "/key.pem"
|
|
|
|
root \$pwd "/testdata"
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
checkconf
|
|
|
|
restart
|
|
|
|
|
|
|
|
eq "$(head /)" "20 text/gemini" "Unexpected head for /"
|
|
|
|
eq "$(get /)" "# hello world$ln" "Unexpected body for /"
|
|
|
|
echo OK GET / with macro expansion
|