gmid/regress/runtime
Omar Polo c836cdfadb handle CGI scripts that replies with the maximum header length allowed
the 1024 bytes limits is for the META only, not for the whole
response.  That means that the maximum size for the header line is
1029!
2021-03-29 09:42:06 +00:00

307 lines
7.5 KiB
Bash
Executable File

#!/bin/sh
set -e
ggflags=
# usage: config <global config> <stuff for localhost>
# generates a configuration file reg.conf
config() {
cat <<EOF > reg.conf
ipv6 off
port 10965
$1
server "localhost" {
cert "$PWD/cert.pem"
key "$PWD/key.pem"
root "$PWD/testdata"
$2
}
EOF
}
checkconf() {
./../gmid -n -c reg.conf
}
# usage: get <path>
# return the body of the request on stdout
get() {
./../gg -b $ggflags "gemini://localhost:10965/$1"
}
# usage: head <path>
# return the meta response line on stdout
head() {
./../gg -h $ggflags "gemini://localhost:10965/$1"
}
# usage: raw <path>
# return both header and body
raw() {
./../gg $ggflags "gemini://localhost:10965/$1"
}
run() {
./../gmid -f -c reg.conf &
pid=$!
# give gmid time to bind the port, otherwise we end up
# executing gg when gmid isn't ready yet.
sleep 1
}
# usage: check [exit-message]
# check if gmid is still running
check() {
if ! ps $pid >/dev/null; then
echo ${1:-"gmid crashed?"}
exit 1
fi
}
restart() {
kill -HUP $pid
sleep 1
}
# quit gmid
quit() {
kill $pid || true
wait || true
}
count() {
wc -l | xargs
}
# 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
}
# tests
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
config 'mime "text/x-funny-text" "gmi"' 'default type "application/x-trash"'
checkconf
restart
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
restart
eq "$(head /)" "20 text/gemini; lang=it" "Unexpected head for /"
echo OK GET / with custom lang
check "should be running"
# make sure we can use different lang in different location rules
config '' 'lang "it" location "/en/*" { lang "en" } location "/de/*" { lang "de" }'
checkconf
echo OK parse multiple locations correctly
restart
# try with CGI scripts
config '' 'cgi "*"'
checkconf
restart
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
eq "$(head /err)" "42 CGI error" "Unexpected head for /err"
eq "$(get /err)" "" "Unexpected body for /err"
echo OK GET /err with cgi
eq "$(raw /invalid | wc -c | xargs)" 2048 "Unexpected body for /invalid"
echo OK GET /invalid with cgi
eq "$(raw /max-length-reply | wc -c | xargs)" 1029 "Unexpected header for /max-length-reply"
echo OK GET /max-length-reply with cgi
# 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
# 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"
check "should be running"
config '' 'index "foo.gmi"'
checkconf
restart
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"
config '' 'location "/dir/*" { default type "text/plain" index "hello" }'
checkconf
restart
eq "$(head /dir/hello)" "20 text/plain" "Unexpected head for /"
echo OK GET /dir/hello with location and default type
eq "$(head /dir/)" "20 text/plain" "Unexpected head for /dir/"
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"
config '' 'location "/dir/*" { auto index on }'
checkconf
restart
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/"
eq "$(get /dir/|wc -l|xargs)" "5" "Unexpected body for /dir/"
echo OK GET /dir/ with auto index on
check "should be running"
# test block return and strip
config '' 'location "*" { block }'
checkconf
restart
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
restart
eq "$(head /dir/foo.gmi)" "40 % /foo.gmi 10965 localhost test"
echo OK GET /dir/foo.gmi with strip and block
eq "$(head /bigfile)" "40 % 10965 localhost test"
echo OK GET /bigfile with strip and block
check "should be running"
# 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
# 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=''