Blob


1 #!/bin/sh
3 set -e
5 # usage: config <global config> <stuff for localhost>
6 # generates a configuration file reg.conf
7 config() {
8 cat <<EOF > reg.conf
9 ipv6 off
10 port 10965
11 $1
12 server "localhost" {
13 cert "$PWD/cert.pem"
14 key "$PWD/key.pem"
15 root "$PWD/testdata"
16 $2
17 }
18 EOF
19 }
21 checkconf() {
22 ./../gmid -n -c reg.conf
23 }
25 # usage: get <path>
26 # return the body of the request on stdout
27 get() {
28 ./../gg -b "gemini://localhost:10965/$1"
29 }
31 # usage: head <path>
32 # return the meta response line on stdout
33 head() {
34 ./../gg -h "gemini://localhost:10965/$1"
35 }
37 # usage: raw <path>
38 # return both header and body
39 raw() {
40 ./../gg "gemini://localhost:10965/$1"
41 }
43 run() {
44 # filter out logs for GET requests
45 (./../gmid -f -c reg.conf 2>&1 | grep -v GET) >&2 &
46 pid=$!
47 # give gmid time to bind the port, otherwise we end up
48 # executing gg when gmid isn't ready yet.
49 sleep 1
50 }
52 # usage: check [exit-message]
53 # check if gmid is still running
54 check() {
55 if ! ps $pid >/dev/null; then
56 echo ${1:-"gmid crashed?"}
57 exit 1
58 fi
59 }
61 restart() {
62 pkill -SIGHUP gmid
63 sleep 1
64 }
66 # quit gmid
67 quit() {
68 pkill gmid || true
69 wait || true
70 }
72 count() {
73 wc -l | xargs
74 }
76 # usage: eq a b errmsg
77 # if a and b aren't equal strings, exit with errmsg
78 eq() {
79 if ! [ "$1" = "$2" ]; then
80 echo "$3: \"$1\" not equal \"$2\""
81 exit 1
82 fi
83 }
85 onexit() {
86 rm -f bigfile bigfile.sha
87 quit
88 }
90 # tests
92 trap 'onexit' INT TERM EXIT
94 endl=`printf "\r\n"`
95 lf=`echo`
97 config "" ""
98 checkconf
99 run
101 eq "$(head /)" "20 text/gemini" "Unexpected head for /"
102 eq "$(get /)" "# hello world$ln" "Unexpected body for /"
103 echo OK GET /
105 eq "$(head /foo)" "51 not found" "Unexpected head /foo"
106 eq "$(get /foo)" "" "Unexpected body /foo"
107 echo OK GET /foo
109 # should redirect if asked for a directory but without the trailing /
110 eq "$(head /dir)" "30 /dir/" "Unexpected redirect for /dir"
111 eq "$(get /dir)" "" "Unexpected body for redirect"
112 echo OK GET /dir
114 # 51 for a directory without index.gmi
115 eq "$(head /dir/)" "51 not found" "Unexpected head for /"
116 eq "$(get /dir/)" "" "Unexpected body for error"
117 echo OK GET /dir/
119 eq "$(head /dir/foo.gmi)" "20 text/gemini" "Unexpected head for /dir/foo.gmi"
120 eq "$(get /dir/foo.gmi)" "# hello world$ln" "Unexpected body for /dir/foo.gmi"
121 echo OK GET /dir/foo.gmi
123 # try a big file
124 eq "$(head /bigfile)" "20 application/octet-stream" "Unexpected head for /bigfile"
125 get /bigfile > bigfile
126 ./sha bigfile bigfile.sha
127 eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /bigfile"
128 echo OK GET /bigfile
130 # shouldn't be executing cgi scripts
131 eq "$(head /hello)" "20 application/octet-stream" "Unexpected head for /hello"
132 echo OK GET /hello
134 check "should be running"
136 # try with custom mime
137 config 'mime "text/x-funny-text" "gmi"' 'default type "application/x-trash"'
138 checkconf
139 restart
141 eq "$(head /)" "20 text/x-funny-text" "Unexpected head for /"
142 echo OK GET / with custom mime
144 eq "$(head /hello)" "20 application/x-trash" "Unexpected head for /hello"
145 echo OK GET /hello with custom mime
147 check "should be running"
149 # try with custom lang
150 config '' 'lang "it"'
151 checkconf
152 restart
154 eq "$(head /)" "20 text/gemini; lang=it" "Unexpected head for /"
155 echo OK GET / with custom lang
157 check "should be running"
159 # try with CGI scripts
160 config '' 'cgi "*"'
161 checkconf
162 restart
164 eq "$(head /hello)" "20 text/gemini" "Unexpected head for /hello"
165 eq "$(get /hello)" "# hello world$ln" "Unexpected body for /hello"
166 echo OK GET /hello with cgi
168 eq "$(head /slow)" "20 text/gemini" "Unexpected head for /slow"
169 eq "$(get /slow)" "# hello world$ln" "Unexpected body for /slow"
170 echo OK GET /slow with cgi
172 eq "$(head /err)" "42 CGI error" "Unexpected head for /err"
173 eq "$(get /err)" "" "Unexpected body for /err"
174 echo OK GET /err with cgi
176 eq "$(raw /invalid | wc -c | xargs)" 2048 "Unexpected body for /invalid"
177 echo OK GET /invalid with cgi
179 # try a big file
180 eq "$(head /serve-bigfile)" "20 application/octet-stream" "Unexpected head for /serve-bigfile"
181 get /bigfile > bigfile
182 ./sha bigfile bigfile.sha
183 eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /serve-bigfile"
184 echo OK GET /serve-bigfile with cgi
186 # ensure we split the query correctly
187 eq "$(get /env | awk /^-/ | count)" 1 "Unexpected number of arguments"
188 eq "$(get /env?foo | awk /^-/ | count)" 2 "Unexpected number of arguments"
189 eq "$(get /env?foo+bar | awk /^-/ | count)" 3 "Unexpected number of arguments"
190 eq "$(get /env?foo+bar=5 | awk /^-/ | count)" 1 "Unexpected number of arguments"
191 eq "$(get /env?foo+bar%3d5 | awk /^-/ | count)" 3 "Unexpected number of arguments"
193 check "should be running"
195 config '' 'index "foo.gmi"'
196 checkconf
197 restart
199 eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /"
200 eq "$(get /dir/)" "# hello world$ln" "Unexpected body for error"
201 echo OK GET /dir/ with custom index
203 check "should be running"
205 config '' 'location "/dir/" { default type "text/plain" index "hello" }'
206 checkconf
207 restart
209 eq "$(head /dir/hello)" "20 text/plain" "Unexpected head for /"
210 echo OK GET /dir/hello with location and default type
212 eq "$(head /dir/)" "20 text/plain" "Unexpected head for /dir/"
213 eq "$(get /dir/|tail -1)" 'echo "# hello world"' "Unexpected body for /dir/"
214 echo OK GET /dir/ with location and custom index
216 check "should be running"
218 config '' 'location "/dir/" { auto index on }'
219 checkconf
220 restart
222 eq "$(head /)" "20 text/gemini" "Unexpected head for /"
223 eq "$(get /)" "# hello world$ln" "Unexpected body for /"
224 echo OK GET / with auto index
226 eq "$(head /dir)" "30 /dir/" "Unexpected head for /dir"
227 eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /dir/"
228 eq "$(get /dir/|wc -l|xargs)" "5" "Unexpected body for /dir/"
229 echo OK GET /dir/ with auto index on
231 check "should be running"
233 # test block return and strip
235 config '' 'location "*" { block }'
236 checkconf
237 restart
239 eq "$(head /)" "40 temporary failure" "Unexpected head for /"
240 eq "$(get /)" "" "Unexpected body for /"
241 echo OK GET / with block
243 eq "$(head /nonexists)" "40 temporary failure" "Unexpected head for /nonexists"
244 eq "$(get /nonexists)" "" "Unexpected body for /nonexists"
245 echo OK GET /nonexists with block
247 check "should be running"
249 config '' '
250 location "/dir" {
251 strip 1
252 block return 40 "%% %p %q %P %N test"
254 location "*" {
255 strip 99
256 block return 40 "%% %p %q %P %N test"
257 }'
258 checkconf
259 restart
261 eq "$(head /dir/foo.gmi)" "40 % /foo.gmi 10965 localhost test"
262 echo OK GET /dir/foo.gmi with strip and block
264 eq "$(head /bigfile)" "40 % 10965 localhost test"
265 echo OK GET /bigfile with strip and block
267 check "should be running"
269 # test the entrypoint
271 config '' 'entrypoint "/env"'
272 checkconf
273 restart
275 eq "$(head /foo/bar)" "20 text/plain; lang=en" "Unknown head for /foo/bar"
276 eq "$(get /foo/bar|grep PATH_INFO)" "PATH_INFO=/foo/bar" "Unexpected PATH_INFO"
277 echo OK GET /foo/bar with entrypoint
279 quit