[mod_cgi] FreeBSD 9.3/MacOSX does not have pipe2() (fixes #2765)
[lighttpd.git] / tests / core-request.t
blob6cbfb71895e03f37a4b425e9f7a99bdc19561678
1 #!/usr/bin/env perl
2 BEGIN {
3 # add current source dir to the include-path
4 # we need this for make distcheck
5 (my $srcdir = $0) =~ s,/[^/]+$,/,;
6 unshift @INC, $srcdir;
9 use strict;
10 use IO::Socket;
11 use Test::More tests => 38;
12 use LightyTest;
14 my $tf = LightyTest->new();
15 my $t;
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
23 EOF
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
30 EOF
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
40 GET / HTTP/1.0
41 Host: www.example.org
42 EOF
44 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
45 ok($tf->handle_http($t) == 0, 'hostname');
47 $t->{REQUEST} = ( <<EOF
48 GET / HTTP/1.0
49 Host: 127.0.0.1
50 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
56 GET / HTTP/1.0
57 Host: [::1]
58 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
64 GET / HTTP/1.0
65 Host: www.example.org:80
66 EOF
68 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
69 ok($tf->handle_http($t) == 0, 'hostname + port');
71 $t->{REQUEST} = ( <<EOF
72 GET / HTTP/1.0
73 Host: 127.0.0.1:80
74 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
80 GET / HTTP/1.0
81 Host: [::1]:80
82 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
88 GET / HTTP/1.0
89 Host: ../123.org
90 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
96 GET / HTTP/1.0
97 Host: .jsdh.sfdg.sdfg.
98 EOF
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
104 GET / HTTP/1.0
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
112 GET / HTTP/1.0
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
121 GET / HTTP/1.0
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
129 GET / HTTP/1.0
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
137 GET / HTTP/1.0
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
146 GET / HTTP/1.0
147 Host: :80
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
154 GET / HTTP/1.0
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
162 GET / HTTP/1.0
163 Host: a.b-c.d123
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
170 GET / HTTP/1.0
171 Host: -a.c
174 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
175 ok($tf->handle_http($t) == 0, 'leading dash');
177 $t->{REQUEST} = ( <<EOF
178 GET / HTTP/1.0
179 Host: .
182 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
183 ok($tf->handle_http($t) == 0, 'dot only');
185 $t->{REQUEST} = ( <<EOF
186 GET / HTTP/1.0
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
194 GET / HTTP/1.0
195 Host: 192.168.2:1234
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
202 GET / HTTP/1.0
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
210 GET / HTTP/1.0
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
224 Content-Length: -2
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
242 Content-Length:
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
250 GET / HTTP/1.1
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
272 GET /a HTTP/1.0
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
279 GET HTTP/1.0
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
293 GET / HTTP/1.0
294 Location: foo
295 Location: foobar
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
303 GET / HTTP/1.0
304 Location:
305 Location: foobar
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
313 GET / HTTP/1.0
315 Location: foobar
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");