Blob


1 #!/bin/sh
3 set -e
5 ggflags=
7 # usage: config <global config> <stuff for localhost>
8 # generates a configuration file reg.conf
9 config() {
10 cat <<EOF > reg.conf
11 ipv6 off
12 port 10965
13 $1
14 server "localhost" {
15 cert "$PWD/cert.pem"
16 key "$PWD/key.pem"
17 root "$PWD/testdata"
18 $2
19 }
20 EOF
21 }
23 checkconf() {
24 ./../gmid -n -c reg.conf
25 }
27 # usage: get <path>
28 # return the body of the request on stdout
29 get() {
30 ./../gg -b $ggflags "gemini://localhost:10965/$1"
31 }
33 # usage: head <path>
34 # return the meta response line on stdout
35 head() {
36 ./../gg -h $ggflags "gemini://localhost:10965/$1"
37 }
39 # usage: raw <path>
40 # return both header and body
41 raw() {
42 ./../gg $ggflags "gemini://localhost:10965/$1"
43 }
45 run() {
46 ./../gmid -f -c reg.conf &
47 pid=$!
48 # give gmid time to bind the port, otherwise we end up
49 # executing gg when gmid isn't ready yet.
50 sleep 1
51 }
53 # usage: check [exit-message]
54 # check if gmid is still running
55 check() {
56 if ! ps $pid >/dev/null; then
57 echo ${1:-"gmid crashed?"}
58 exit 1
59 fi
60 }
62 restart() {
63 kill -HUP $pid
64 sleep 1
65 }
67 # quit gmid
68 quit() {
69 kill $pid || true
70 wait || true
71 }
73 count() {
74 wc -l | xargs
75 }
77 # usage: eq a b errmsg
78 # if a and b aren't equal strings, exit with errmsg
79 eq() {
80 if ! [ "$1" = "$2" ]; then
81 echo "$3: \"$1\" not equal \"$2\""
82 exit 1
83 fi
84 }
86 onexit() {
87 rm -f bigfile bigfile.sha
88 quit
89 }
91 # tests
93 trap 'onexit' INT TERM EXIT
95 endl=`printf "\r\n"`
96 lf=`echo`
98 config "" ""
99 checkconf
100 run
102 eq "$(head /)" "20 text/gemini" "Unexpected head for /"
103 eq "$(get /)" "# hello world$ln" "Unexpected body for /"
104 echo OK GET /
106 eq "$(head /foo)" "51 not found" "Unexpected head /foo"
107 eq "$(get /foo)" "" "Unexpected body /foo"
108 echo OK GET /foo
110 # should redirect if asked for a directory but without the trailing /
111 eq "$(head /dir)" "30 /dir/" "Unexpected redirect for /dir"
112 eq "$(get /dir)" "" "Unexpected body for redirect"
113 echo OK GET /dir
115 # 51 for a directory without index.gmi
116 eq "$(head /dir/)" "51 not found" "Unexpected head for /"
117 eq "$(get /dir/)" "" "Unexpected body for error"
118 echo OK GET /dir/
120 eq "$(head /dir/foo.gmi)" "20 text/gemini" "Unexpected head for /dir/foo.gmi"
121 eq "$(get /dir/foo.gmi)" "# hello world$ln" "Unexpected body for /dir/foo.gmi"
122 echo OK GET /dir/foo.gmi
124 # try a big file
125 eq "$(head /bigfile)" "20 application/octet-stream" "Unexpected head for /bigfile"
126 get /bigfile > bigfile
127 ./sha bigfile bigfile.sha
128 eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /bigfile"
129 echo OK GET /bigfile
131 # shouldn't be executing cgi scripts
132 eq "$(head /hello)" "20 application/octet-stream" "Unexpected head for /hello"
133 echo OK GET /hello
135 check "should be running"
137 # try with custom mime
138 config 'mime "text/x-funny-text" "gmi"' 'default type "application/x-trash"'
139 checkconf
140 restart
142 eq "$(head /)" "20 text/x-funny-text" "Unexpected head for /"
143 echo OK GET / with custom mime
145 eq "$(head /hello)" "20 application/x-trash" "Unexpected head for /hello"
146 echo OK GET /hello with custom mime
148 check "should be running"
150 # try with custom lang
151 config '' 'lang "it"'
152 checkconf
153 restart
155 eq "$(head /)" "20 text/gemini; lang=it" "Unexpected head for /"
156 echo OK GET / with custom lang
158 check "should be running"
160 # make sure we can use different lang in different location rules
161 config '' 'lang "it" location "/en/*" { lang "en" } location "/de/*" { lang "de" }'
162 checkconf
163 echo OK parse multiple locations correctly
164 restart
166 # try with CGI scripts
167 config '' 'cgi "*"'
168 checkconf
169 restart
171 eq "$(head /hello)" "20 text/gemini" "Unexpected head for /hello"
172 eq "$(get /hello)" "# hello world$ln" "Unexpected body for /hello"
173 echo OK GET /hello with cgi
175 eq "$(head /slow)" "20 text/gemini" "Unexpected head for /slow"
176 eq "$(get /slow)" "# hello world$ln" "Unexpected body for /slow"
177 echo OK GET /slow with cgi
179 eq "$(head /err)" "42 CGI error" "Unexpected head for /err"
180 eq "$(get /err)" "" "Unexpected body for /err"
181 echo OK GET /err with cgi
183 eq "$(raw /invalid | wc -c | xargs)" 2048 "Unexpected body for /invalid"
184 echo OK GET /invalid with cgi
186 eq "$(raw /max-length-reply | wc -c | xargs)" 1029 "Unexpected header for /max-length-reply"
187 echo OK GET /max-length-reply with cgi
189 # try a big file
190 eq "$(head /serve-bigfile)" "20 application/octet-stream" "Unexpected head for /serve-bigfile"
191 get /bigfile > bigfile
192 ./sha bigfile bigfile.sha
193 eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /serve-bigfile"
194 echo OK GET /serve-bigfile with cgi
196 # ensure we split the query correctly
197 eq "$(get /env | awk /^-/ | count)" 1 "Unexpected number of arguments"
198 eq "$(get /env?foo | awk /^-/ | count)" 2 "Unexpected number of arguments"
199 eq "$(get /env?foo+bar | awk /^-/ | count)" 3 "Unexpected number of arguments"
200 eq "$(get /env?foo+bar=5 | awk /^-/ | count)" 1 "Unexpected number of arguments"
201 eq "$(get /env?foo+bar%3d5 | awk /^-/ | count)" 3 "Unexpected number of arguments"
203 check "should be running"
205 config '' 'index "foo.gmi"'
206 checkconf
207 restart
209 eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /"
210 eq "$(get /dir/)" "# hello world$ln" "Unexpected body for error"
211 echo OK GET /dir/ with custom index
213 check "should be running"
215 config '' 'location "/dir/*" { default type "text/plain" index "hello" }'
216 checkconf
217 restart
219 eq "$(head /dir/hello)" "20 text/plain" "Unexpected head for /"
220 echo OK GET /dir/hello with location and default type
222 eq "$(head /dir/)" "20 text/plain" "Unexpected head for /dir/"
223 eq "$(get /dir/|tail -1)" 'echo "# hello world"' "Unexpected body for /dir/"
224 echo OK GET /dir/ with location and custom index
226 check "should be running"
228 config '' 'location "/dir/*" { auto index on }'
229 checkconf
230 restart
232 eq "$(head /)" "20 text/gemini" "Unexpected head for /"
233 eq "$(get /)" "# hello world$ln" "Unexpected body for /"
234 echo OK GET / with auto index
236 eq "$(head /dir)" "30 /dir/" "Unexpected head for /dir"
237 eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /dir/"
238 eq "$(get /dir/|wc -l|xargs)" "5" "Unexpected body for /dir/"
239 echo OK GET /dir/ with auto index on
241 check "should be running"
243 # test block return and strip
245 config '' 'location "*" { block }'
246 checkconf
247 restart
249 eq "$(head /)" "40 temporary failure" "Unexpected head for /"
250 eq "$(get /)" "" "Unexpected body for /"
251 echo OK GET / with block
253 eq "$(head /nonexists)" "40 temporary failure" "Unexpected head for /nonexists"
254 eq "$(get /nonexists)" "" "Unexpected body for /nonexists"
255 echo OK GET /nonexists with block
257 check "should be running"
259 config '' '
260 location "/dir" {
261 strip 1
262 block return 40 "%% %p %q %P %N test"
264 location "*" {
265 strip 99
266 block return 40 "%% %p %q %P %N test"
267 }'
268 checkconf
269 restart
271 eq "$(head /dir/foo.gmi)" "40 % /foo.gmi 10965 localhost test"
272 echo OK GET /dir/foo.gmi with strip and block
274 eq "$(head /bigfile)" "40 % 10965 localhost test"
275 echo OK GET /bigfile with strip and block
277 check "should be running"
279 # test the entrypoint
281 config '' 'entrypoint "/env"'
282 checkconf
283 restart
285 eq "$(head /foo/bar)" "20 text/plain; lang=en" "Unknown head for /foo/bar"
286 eq "$(get /foo/bar|grep PATH_INFO)" "PATH_INFO=/foo/bar" "Unexpected PATH_INFO"
287 echo OK GET /foo/bar with entrypoint
289 # test with require ca
291 config '' 'require client ca "'$PWD'/testca.pem"'
292 checkconf
293 restart
295 eq "$(head /)" "60 client certificate required" "Unexpected head for /"
296 echo OK GET / without client certificate
298 ggflags="-C valid.crt -K valid.key"
299 eq "$(head /)" "20 text/gemini" "Unexpected head for /"
300 echo OK GET / with valid client certificate
302 ggflags="-C invalid.cert.pem -K invalid.key.pem"
303 eq "$(head /)" "61 certificate not authorised" "Unexpected head for /"
304 echo OK GET / with invalid client certificate
306 ggflags=''