3 # add current source dir to the include-path
4 # we need this for make distcheck
5 (my $srcdir = $0) =~ s
,/[^/]+$,/,;
11 use Test
::More tests
=> 38;
14 my $tf = LightyTest
->new();
17 ok
($tf->start_proc == 0, "Starting lighttpd") or die();
19 ## Low-Level Request-Header Parsing - URI
21 $t->{REQUEST
} = ( <<EOF
22 GET /index%2ehtml HTTP/1.0
25 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
26 ok
($tf->handle_http($t) == 0, 'URL-encoding');
28 $t->{REQUEST
} = ( <<EOF
29 GET /index.html%00 HTTP/1.0
32 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ];
33 ok
($tf->handle_http($t) == 0, 'URL-encoding, %00');
37 ## Low-Level Request-Header Parsing - Host
39 $t->{REQUEST
} = ( <<EOF
44 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
45 ok
($tf->handle_http($t) == 0, 'hostname');
47 $t->{REQUEST
} = ( <<EOF
52 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
53 ok
($tf->handle_http($t) == 0, 'IPv4 address');
55 $t->{REQUEST
} = ( <<EOF
60 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
61 ok
($tf->handle_http($t) == 0, 'IPv6 address');
63 $t->{REQUEST
} = ( <<EOF
65 Host: www.example.org:80
68 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
69 ok
($tf->handle_http($t) == 0, 'hostname + port');
71 $t->{REQUEST
} = ( <<EOF
76 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
77 ok
($tf->handle_http($t) == 0, 'IPv4 address + port');
79 $t->{REQUEST
} = ( <<EOF
84 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
85 ok
($tf->handle_http($t) == 0, 'IPv6 address + port');
87 $t->{REQUEST
} = ( <<EOF
92 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
93 ok
($tf->handle_http($t) == 0, 'directory traversal');
95 $t->{REQUEST
} = ( <<EOF
97 Host: .jsdh.sfdg.sdfg.
100 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
101 ok
($tf->handle_http($t) == 0, 'leading and trailing dot');
103 $t->{REQUEST
} = ( <<EOF
105 Host: jsdh.sfdg.sdfg.
108 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
109 ok
($tf->handle_http($t) == 0, 'trailing dot is ok');
111 $t->{REQUEST
} = ( <<EOF
113 Host: .jsdh.sfdg.sdfg
116 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
117 ok
($tf->handle_http($t) == 0, 'leading dot');
120 $t->{REQUEST
} = ( <<EOF
122 Host: jsdh..sfdg.sdfg
125 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
126 ok
($tf->handle_http($t) == 0, 'two dots');
128 $t->{REQUEST
} = ( <<EOF
130 Host: jsdh.sfdg.sdfg:asd
133 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
134 ok
($tf->handle_http($t) == 0, 'broken port-number');
136 $t->{REQUEST
} = ( <<EOF
138 Host: jsdh.sfdg.sdfg:-1
141 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
142 ok
($tf->handle_http($t) == 0, 'negative port-number');
145 $t->{REQUEST
} = ( <<EOF
150 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
151 ok
($tf->handle_http($t) == 0, 'port given but host missing');
153 $t->{REQUEST
} = ( <<EOF
155 Host: .jsdh.sfdg.:sdfg.
158 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
159 ok
($tf->handle_http($t) == 0, 'port and host are broken');
161 $t->{REQUEST
} = ( <<EOF
166 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
167 ok
($tf->handle_http($t) == 0, 'allowed characters in host-name');
169 $t->{REQUEST
} = ( <<EOF
174 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
175 ok
($tf->handle_http($t) == 0, 'leading dash');
177 $t->{REQUEST
} = ( <<EOF
182 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
183 ok
($tf->handle_http($t) == 0, 'dot only');
185 $t->{REQUEST
} = ( <<EOF
187 Host: a192.168.2.10:1234
190 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
191 ok
($tf->handle_http($t) == 0, 'broken IPv4 address - non-digit');
193 $t->{REQUEST
} = ( <<EOF
198 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
199 ok
($tf->handle_http($t) == 0, 'broken IPv4 address - too short');
201 $t->{REQUEST
} = ( <<EOF
203 Host: [::1]' UNION SELECT '/
206 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
207 ok
($tf->handle_http($t) == 0, 'IPv6 address + SQL injection');
209 $t->{REQUEST
} = ( <<EOF
211 Host: [::1]/../../../
214 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
215 ok
($tf->handle_http($t) == 0, 'IPv6 address + path traversal');
219 ## Low-Level Request-Header Parsing - Content-Length
222 $t->{REQUEST
} = ( <<EOF
223 GET /index.html HTTP/1.0
227 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
228 ok
($tf->handle_http($t) == 0, 'negative Content-Length');
230 $t->{REQUEST
} = ( <<EOF
231 POST /12345.txt HTTP/1.0
232 Host: 123.example.org
233 Content-Length: 2147483648
236 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 413 } ];
237 ok
($tf->handle_http($t) == 0, 'Content-Length > max-request-size');
239 $t->{REQUEST
} = ( <<EOF
240 POST /12345.txt HTTP/1.0
241 Host: 123.example.org
245 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 411 } ];
246 ok
($tf->handle_http($t) == 0, 'Content-Length is empty');
248 print "\nLow-Level Request-Header Parsing - HTTP/1.1\n";
249 $t->{REQUEST
} = ( <<EOF
253 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 400 } ];
254 ok
($tf->handle_http($t) == 0, 'Host missing');
256 print "\nContent-Type\n";
257 $t->{REQUEST
} = ( <<EOF
258 GET /image.jpg HTTP/1.0
261 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ];
262 ok
($tf->handle_http($t) == 0, 'Content-Type - image/jpeg');
264 $t->{REQUEST
} = ( <<EOF
265 GET /image.JPG HTTP/1.0
268 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ];
269 ok
($tf->handle_http($t) == 0, 'Content-Type - image/jpeg (upper case)');
271 $t->{REQUEST
} = ( <<EOF
275 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'application/octet-stream' } ];
276 ok
($tf->handle_http($t) == 0, 'Content-Type - unknown');
278 $t->{REQUEST
} = ( <<EOF
282 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
283 ok
($tf->handle_http($t) == 0, 'empty request-URI');
285 $t->{REQUEST
} = ( <<EOF
286 GET /Foo.txt HTTP/1.0
289 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
290 ok
($tf->handle_http($t) == 0, 'uppercase filenames');
292 $t->{REQUEST
} = ( <<EOF
299 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
300 ok
($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping');
302 $t->{REQUEST
} = ( <<EOF
309 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
310 ok
($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping - test 2');
312 $t->{REQUEST
} = ( <<EOF
319 $t->{RESPONSE
} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
320 ok
($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping - test 3');
325 ok
($tf->stop_proc == 0, "Stopping lighttpd");