diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-07-07 15:00:31 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2021-09-04 08:08:26 -0400 |
commit | f47261159720e90dc4444082b2a28bd1491634d4 (patch) | |
tree | b122b826a424df0013b77a91e6f4942400aa1f97 /tests | |
parent | 91472ab7681b26f36b813f3b245c0e98f91b4c3f (diff) | |
download | lighttpd-git-f47261159720e90dc4444082b2a28bd1491634d4.tar.gz |
[tests] combine *.t using tests/lighttpd.conf
combine tests/*.t using tests/lighttpd.conf into tests/request.t
Platforms which are horrifically slow starting processes (e.g. Windows)
take much more time to start and stop lighttpd many times for
independent *.t instances run through the Perl Test::More framework
Diffstat (limited to 'tests')
-rw-r--r-- | tests/404-handler.conf | 37 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 17 | ||||
-rw-r--r-- | tests/Makefile.am | 21 | ||||
-rwxr-xr-x | tests/core-404-handler.t | 83 | ||||
-rwxr-xr-x | tests/core-condition.t | 88 | ||||
-rwxr-xr-x | tests/core-keepalive.t | 116 | ||||
-rwxr-xr-x | tests/core-request.t | 86 | ||||
-rwxr-xr-x | tests/core-response.t | 100 | ||||
-rw-r--r-- | tests/fastcgi-responder.conf | 1 | ||||
-rw-r--r-- | tests/lighttpd.conf | 141 | ||||
-rw-r--r-- | tests/lowercase.conf | 43 | ||||
-rwxr-xr-x | tests/lowercase.t | 94 | ||||
-rw-r--r-- | tests/meson.build | 17 | ||||
-rw-r--r-- | tests/mod-auth.conf | 46 | ||||
-rwxr-xr-x | tests/mod-auth.t | 202 | ||||
-rwxr-xr-x | tests/mod-cgi.t | 185 | ||||
-rw-r--r-- | tests/mod-deflate.conf | 35 | ||||
-rwxr-xr-x | tests/mod-deflate.t | 103 | ||||
-rw-r--r-- | tests/mod-extforward.conf | 30 | ||||
-rwxr-xr-x | tests/mod-extforward.t | 57 | ||||
-rwxr-xr-x | tests/mod-proxy.t | 66 | ||||
-rw-r--r-- | tests/mod-secdownload.conf | 47 | ||||
-rwxr-xr-x | tests/mod-secdownload.t | 209 | ||||
-rwxr-xr-x | tests/mod-setenv.t | 76 | ||||
-rwxr-xr-x | tests/mod-ssi.t | 45 | ||||
-rwxr-xr-x | tests/request.t | 1360 | ||||
-rw-r--r-- | tests/scgi-responder.conf | 1 | ||||
-rwxr-xr-x | tests/symlink.t | 115 | ||||
-rw-r--r-- | tests/var-include.conf | 1 |
29 files changed, 1489 insertions, 1933 deletions
diff --git a/tests/404-handler.conf b/tests/404-handler.conf deleted file mode 100644 index 415adb6b..00000000 --- a/tests/404-handler.conf +++ /dev/null @@ -1,37 +0,0 @@ -debug.log-request-handling = "enable" -debug.log-response-header = "enable" -debug.log-request-header = "enable" - -server.systemd-socket-activation = "enable" -server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" -server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" -server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" -server.name = "www.example.org" -server.tag = "Apache 1.3.29" - -server.compat-module-load = "disable" -server.modules = ( - "mod_cgi", - "mod_accesslog", - "mod_staticfile", -) - -accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" - -mimetype.assign = ( - ".html" => "text/html", -) - -cgi.assign = ( - ".pl" => env.PERL, -) - -$HTTP["url"] =~ "^/static/" { - server.error-handler-404 = "/404.html" -} -else $HTTP["url"] =~ "^/dynamic/redirect_status/" { - server.error-handler = "/404.pl" -} -else $HTTP["url"] =~ "." { - server.error-handler-404 = "/404.pl" -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0db1a440..0b81ba9b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,24 +3,11 @@ add_executable(scgi-responder scgi-responder.c) set(T_FILES prepare.sh - core-404-handler.t + request.t core-condition.t - core-keepalive.t - core-request.t - core-response.t core-var-include.t - lowercase.t - mod-auth.t - mod-cgi.t - mod-deflate.t - mod-extforward.t mod-fastcgi.t - mod-proxy.t - mod-secdownload.t - mod-setenv.t - mod-ssi.t - request.t - symlink.t + mod-scgi.t cleanup.sh ) diff --git a/tests/Makefile.am b/tests/Makefile.am index a23c519a..b298f699 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,35 +12,16 @@ TESTS=\ cleanup.sh CONFS=\ - 404-handler.conf \ condition.conf \ - core-404-handler.t \ core-condition.t \ - core-keepalive.t \ - core-request.t \ - core-response.t \ core-var-include.t \ fastcgi-responder.conf \ LightyTest.pm \ - lowercase.conf \ - lowercase.t \ - mod-auth.conf \ - mod-auth.t \ - mod-cgi.t \ - mod-deflate.conf \ - mod-deflate.t \ - mod-extforward.conf \ - mod-extforward.t \ mod-fastcgi.t \ - mod-proxy.t \ - mod-secdownload.conf \ - mod-secdownload.t \ - mod-setenv.t \ - mod-ssi.t \ + mod-scgi.t \ proxy.conf \ request.t \ scgi-responder.conf \ - symlink.t \ var-include-sub.conf \ var-include.conf diff --git a/tests/core-404-handler.t b/tests/core-404-handler.t deleted file mode 100755 index f292b4c4..00000000 --- a/tests/core-404-handler.t +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env perl -# -# combinations we have to test: -# plain 404 case -# 404-handler -> static file (verify content) -# 404-handler -> fastcgi -# returning 200 -# returning 302 + Location -# returning 404 -# returning no status -> 200 -# -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 9; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; -$tf->{CONFIGFILE} = '404-handler.conf'; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /static/notfound HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "static not found\n" } ]; -ok($tf->handle_http($t) == 0, '404 handler => static'); - -# -# -# -$t->{REQUEST} = ( <<EOF -GET /dynamic/200/notfound HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "found here\n" } ]; -ok($tf->handle_http($t) == 0, '404 handler => dynamic(200)'); - -$t->{REQUEST} = ( <<EOF -GET /dynamic/302/notfound HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => "http://www.example.org/" } ]; -ok($tf->handle_http($t) == 0, '404 handler => dynamic(302)'); - -$t->{REQUEST} = ( <<EOF -GET /dynamic/404/notfound HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => "Not found here\n" } ]; -ok($tf->handle_http($t) == 0, '404 handler => dynamic(404)'); - -$t->{REQUEST} = ( <<EOF -GET /dynamic/redirect_status/ HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => "REDIRECT_STATUS\n" } ]; -ok($tf->handle_http($t) == 0, 'error handler => dynamic(REDIRECT_STATUS)'); - -$t->{REQUEST} = ( <<EOF -GET /dynamic/nostatus/notfound HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "found here\n" } ]; -ok($tf->handle_http($t) == 0, '404 handler => dynamic(nostatus)'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?send404 HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => "send404\n" } ]; -ok($tf->handle_http($t) == 0, '404 generated by CGI should stay 404'); - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/core-condition.t b/tests/core-condition.t index 53b69c5e..40647041 100755 --- a/tests/core-condition.t +++ b/tests/core-condition.t @@ -8,7 +8,7 @@ BEGIN { use strict; use IO::Socket; -use Test::More tests => 21; +use Test::More tests => 10; use LightyTest; my $tf = LightyTest->new(); @@ -80,89 +80,3 @@ $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Serve ok($tf->handle_http($t) == 0, 'condition: handle if before else branches #2'); ok($tf->stop_proc == 0, "Stopping lighttpd"); - -$tf->{CONFIGFILE} = 'lighttpd.conf'; -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /nofile.png HTTP/1.0 -Host: referer.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; -ok($tf->handle_http($t) == 0, 'condition: Referer - no referer'); - -$t->{REQUEST} = ( <<EOF -GET /nofile.png HTTP/1.0 -Host: referer.example.org -Referer: http://referer.example.org/ -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; -ok($tf->handle_http($t) == 0, 'condition: Referer - referer matches regex'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'condition: Referer - no referer'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -Host: www.example.org -Referer: http://referer.example.org/ -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'condition: Referer - referer matches regex'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -Host: www.example.org -Referer: http://evil-referer.example.org/ -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'condition: Referer - referer doesn\'t match'); - -$t->{REQUEST} = ( <<EOF -GET /nofile HTTP/1.1 -Host: bug255.example.org - -GET /nofile HTTP/1.1 -Host: bug255.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 403 }, { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'remote ip cache (#255)'); - -$t->{REQUEST} = ( <<EOF -GET /empty-ref.noref HTTP/1.0 -Cookie: empty-ref -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'condition: $HTTP["referer"] == "" and Referer is no set'); - -$t->{REQUEST} = ( <<EOF -GET /empty-ref.noref HTTP/1.0 -Cookie: empty-ref -Referer: -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'condition: $HTTP["referer"] == "" and Referer is empty'); - -$t->{REQUEST} = ( <<EOF -GET /empty-ref.noref HTTP/1.0 -Cookie: empty-ref -Referer: foobar -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; -ok($tf->handle_http($t) == 0, 'condition: $HTTP["referer"] == "" and Referer: foobar'); - -ok($tf->stop_proc == 0, "Stopping lighttpd"); diff --git a/tests/core-keepalive.t b/tests/core-keepalive.t deleted file mode 100755 index a0badc22..00000000 --- a/tests/core-keepalive.t +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 9; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.0 -Connection: keep-alive -Host: 123.example.org - -GET /12345.txt HTTP/1.0 -Host: 123.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'Explicit HTTP/1.0 Keep-Alive'); - -undef $t->{RESPONSE}; - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.0 -Connection: keep-alive -Host: 123.example.org - -GET /12345.txt HTTP/1.0 -Host: 123.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'Explicit HTTP/1.0 Keep-Alive'); - -undef $t->{RESPONSE}; - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.0 -Connection: keep-alive -Host: 123.example.org - -GET /12345.txt HTTP/1.0 -Host: 123.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.0 Keep-Alive'); - - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.1 -Connection: keep-alive -Host: 123.example.org - -GET /12345.txt HTTP/1.1 -Host: 123.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Explicit HTTP/1.1 Keep-Alive'); - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.1 -Host: 123.example.org - -GET /12345.txt HTTP/1.1 -Host: 123.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.1 Keep-Alive'); - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.1 -Host: 123.example.org - - -GET /12345.txt HTTP/1.1 -Host: 123.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.1 Keep-Alive w/ extra blank b/w requests'); - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.1 -Host: 123.example.org - - - -GET /12345.txt HTTP/1.1 -Host: 123.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; -ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.1 Keep-Alive w/ excess blank b/w requests'); - -ok($tf->stop_proc == 0, "Stopping lighttpd"); diff --git a/tests/core-request.t b/tests/core-request.t deleted file mode 100755 index d30e952c..00000000 --- a/tests/core-request.t +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 10; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - - -$t->{REQUEST} = ( <<EOF -GET / HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Valid HTTP/1.0 Request') or die(); - -$t->{REQUEST} = ( <<EOF -OPTIONS * HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'OPTIONS'); - -$t->{REQUEST} = ( <<EOF -OPTIONS / HTTP/1.1 -Host: www.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'OPTIONS'); - - -## Low-Level Request-Header Parsing - URI - -$t->{REQUEST} = ( <<EOF -GET /index.html%00 HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; -ok($tf->handle_http($t) == 0, 'URL-encoding, %00'); - -$t->{REQUEST} = ( <<EOF -POST /12345.txt HTTP/1.0 -Host: 123.example.org -Content-Length: 2147483648 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 413 } ]; -ok($tf->handle_http($t) == 0, 'Content-Length > max-request-size'); - - -print "\nContent-Type\n"; -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ]; -ok($tf->handle_http($t) == 0, 'Content-Type - image/jpeg'); - -$t->{REQUEST} = ( <<EOF -GET /image.JPG HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ]; -ok($tf->handle_http($t) == 0, 'Content-Type - image/jpeg (upper case)'); - -$t->{REQUEST} = ( <<EOF -GET /Foo.txt HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'uppercase filenames'); - - -ok($tf->stop_proc == 0, "Stopping lighttpd"); diff --git a/tests/core-response.t b/tests/core-response.t deleted file mode 100755 index 1c19e85c..00000000 --- a/tests/core-response.t +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 11; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -## Low-Level Response-Header Parsing - HTTP/1.1 - -$t->{REQUEST} = ( <<EOF -GET / HTTP/1.1 -Host: www.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, '+Date' => '' } ]; -ok($tf->handle_http($t) == 0, 'Date header'); - - -## Low-Level Response-Header Parsing - Content-Length - - -$t->{REQUEST} = ( <<EOF -GET /12345.html HTTP/1.0 -Host: 123.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => '6' } ]; -ok($tf->handle_http($t) == 0, 'Content-Length for text/html'); - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.0 -Host: 123.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => '6' } ]; -ok($tf->handle_http($t) == 0, 'Content-Length for text/plain'); - - -## Low-Level Response-Header Parsing - Location - -$t->{REQUEST} = ( <<EOF -GET /dummydir HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/dummydir/' } ]; -ok($tf->handle_http($t) == 0, 'internal redirect in directory'); - -$t->{REQUEST} = ( <<EOF -GET /dummydir?foo HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/dummydir/?foo' } ]; -ok($tf->handle_http($t) == 0, 'internal redirect in directory + querystring'); - -$t->{REQUEST} = ( <<EOF -GET /~test%20ä_ HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/~test%20%C3%A4_/' } ]; -ok($tf->handle_http($t) == 0, 'internal redirect in directory with special characters'); - -$t->{REQUEST} = ( <<EOF -GET /~test%20ä_?foo HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/~test%20%C3%A4_/?foo' } ]; -ok($tf->handle_http($t) == 0, 'internal redirect in directory with special characters + querystring'); - -## simple-vhost - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.0 -Host: no-simple.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => '6' } ]; -ok($tf->handle_http($t) == 0, 'disabling simple-vhost via conditionals'); - -$t->{REQUEST} = ( <<EOF -GET /12345.txt HTTP/1.0 -Host: simple.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; -ok($tf->handle_http($t) == 0, 'simple-vhost via conditionals'); - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/fastcgi-responder.conf b/tests/fastcgi-responder.conf index f2394b66..427d71af 100644 --- a/tests/fastcgi-responder.conf +++ b/tests/fastcgi-responder.conf @@ -7,7 +7,6 @@ server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" server.name = "www.example.org" -server.tag = "Apache 1.3.29" server.compat-module-load = "disable" server.modules = ( diff --git a/tests/lighttpd.conf b/tests/lighttpd.conf index 9ef82424..687fc8b7 100644 --- a/tests/lighttpd.conf +++ b/tests/lighttpd.conf @@ -11,11 +11,14 @@ server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" server.name = "www.example.org" -server.tag = "Apache 1.3.29" +server.tag = "lighttpd-1.4.x" server.dir-listing = "enable" server.modules = ( + "mod_extforward", + "mod_auth", + "mod_authn_file", "mod_setenv", "mod_access", "mod_expire", @@ -23,6 +26,9 @@ server.modules = ( "mod_cgi", "mod_userdir", "mod_ssi", + "mod_status", + "mod_secdownload", + "mod_deflate", "mod_accesslog", ) @@ -84,6 +90,12 @@ cgi.assign = ( ".cgi" => env.PERL, ) +extforward.headers = ( "Forwarded", "X-Forwarded-For" ) +extforward.forwarder = ( + "127.0.0.1" => "trust", + "127.0.30.1" => "trust", +) + userdir.include-user = ( "jan", ) @@ -99,30 +111,20 @@ expire.url = ( "/expire/modification" => "access plus 1 seconds 2 minutes", ) -$HTTP["host"] == "zzz.example.org" { - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - server.name = "zzz.example.org" - static-file.disable-pathinfo = "enable" -} - $HTTP["host"] == "symlink.example.org" { server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - server.name = "symlink.example.org" server.follow-symlink = "enable" } $HTTP["host"] == "nosymlink.example.org" { server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - server.name = "symlink.example.org" server.follow-symlink = "disable" } $HTTP["host"] == "no-simple.example.org" { server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/123.example.org/pages/" - server.name = "zzz.example.org" } - -$HTTP["host"] !~ "(no-simple\.example\.org)" { +else { simple-vhost.document-root = "pages" simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/" simple-vhost.default-host = "www.example.org" @@ -164,12 +166,119 @@ $HTTP["host"] =~ "allow\.example\.org$" { url.access-deny = ( ".txt" ) } -$HTTP["host"] == "etag.example.org" { - static-file.etags = "disable" -} - $HTTP["host"] == "cgi.example.org" { index-file.names = ( "nonexistent.txt", "index.pl" ) server.error-handler-404 = "/indexfile/index.pl" cgi.x-sendfile = "enable" } + +$HTTP["host"] == "errors.example.org" { + $HTTP["url"] =~ "^/static/" { + server.error-handler-404 = "/404.html" + } + else $HTTP["url"] =~ "^/dynamic/redirect_status/" { + server.error-handler = "/404.pl" + } + else $HTTP["url"] =~ "." { + server.error-handler-404 = "/404.pl" + } +} + +$HTTP["host"] == "lowercase-allow" { + server.force-lowercase-filenames = "enable" +} +$HTTP["host"] == "lowercase-deny" { + server.force-lowercase-filenames = "enable" + url.access-deny = ( + ".jpg", + ) +} +$HTTP["host"] == "lowercase-exclude" { + server.force-lowercase-filenames = "enable" + static-file.exclude-extensions = ( + ".jpg", + ) +} +$HTTP["host"] == "lowercase-auth" { + server.force-lowercase-filenames = "enable" + auth.backend = "plain" + auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" + auth.require = ( + "/image.jpg" => ( + "method" => "digest", + "realm" => "download archiv", + "require" => "valid-user", + ), + ) +} + +$HTTP["host"] =~ "^deflate(?:-cache)?\.example\.org$" { + $HTTP["url"] == "/index.txt" { + # (force Content-Type for test; do not copy) + setenv.set-response-header = ( + "Content-Type" => "text/plain; charset=utf-8" + ) + } + deflate.mimetypes = ( + "text/plain", + "text/html", + ) + deflate.allowed-encodings = ( + "gzip", + "deflate", + ) + $HTTP["host"] == "deflate-cache.example.org" { + deflate.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" + } +} + +$HTTP["host"] =~ "^auth-" { + $HTTP["host"] == "auth-htpasswd.example.org" { + auth.backend = "htpasswd" + auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd" + } + $HTTP["host"] == "auth-plain.example.org" { + auth.backend = "plain" + auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" + } + auth.require = ( + "/server-status" => ( + "method" => "digest", + "realm" => "download archiv", + "require" => "group=www|user=jan|host=192.168.2.10", + ), + "/server-config" => ( + "method" => "basic", + "realm" => "download archiv", + "require" => "valid-user", + ), + ) + status.status-url = "/server-status" + status.config-url = "/server-config" +} + +$HTTP["host"] == "vvv.example.org" { + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + secdownload.secret = "verysecret" + secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + secdownload.uri-prefix = "/sec/" + secdownload.timeout = 120 + secdownload.algorithm = "md5" +} +$HTTP["host"] == "vvv-sha1.example.org" { + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + secdownload.secret = "verysecret" + secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + secdownload.uri-prefix = "/sec/" + secdownload.timeout = 120 + secdownload.algorithm = "hmac-sha1" +} +$HTTP["host"] == "vvv-sha256.example.org" { + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + secdownload.secret = "verysecret" + secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + secdownload.uri-prefix = "/sec/" + secdownload.timeout = 120 + secdownload.algorithm = "hmac-sha256" + secdownload.hash-querystr = "enable" +} diff --git a/tests/lowercase.conf b/tests/lowercase.conf deleted file mode 100644 index 4d13b69a..00000000 --- a/tests/lowercase.conf +++ /dev/null @@ -1,43 +0,0 @@ -server.systemd-socket-activation = "enable" -server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" -server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" -server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" - -server.force-lowercase-filenames = "enable" - -server.compat-module-load = "disable" -server.modules = ( - "mod_access", - "mod_auth", - "mod_authn_file", - "mod_staticfile", -) - -mimetype.assign = ( - ".jpg" => "image/jpeg", -) - -auth.backend = "plain" -auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" - -$HTTP["host"] == "lowercase-auth" { - auth.require = ( - "/image.jpg" => ( - "method" => "digest", - "realm" => "download archiv", - "require" => "valid-user", - ), - ) -} - -$HTTP["host"] == "lowercase-deny" { - url.access-deny = ( - ".jpg", - ) -} - -$HTTP["host"] == "lowercase-exclude" { - static-file.exclude-extensions = ( - ".jpg", - ) -} diff --git a/tests/lowercase.t b/tests/lowercase.t deleted file mode 100755 index f6f6f2c4..00000000 --- a/tests/lowercase.t +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 10; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -$tf->{CONFIGFILE} = 'lowercase.conf'; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -## check if lower-casing works - -$t->{REQUEST} = ( <<EOF -GET /image.JPG HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'uppercase access'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'lowercase access'); - -## check that mod-auth works - -$t->{REQUEST} = ( <<EOF -GET /image.JPG HTTP/1.0 -Host: lowercase-auth -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'uppercase access'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -Host: lowercase-auth -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'lowercase access'); - - -## check that mod-staticfile exclude works -$t->{REQUEST} = ( <<EOF -GET /image.JPG HTTP/1.0 -Host: lowercase-exclude -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'upper case access to staticfile.exclude-extension'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -Host: lowercase-exclude -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'lowercase access'); - - -## check that mod-access exclude works -$t->{REQUEST} = ( <<EOF -GET /image.JPG HTTP/1.0 -Host: lowercase-deny -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'uppercase access to url.access-deny protected location'); - -$t->{REQUEST} = ( <<EOF -GET /image.jpg HTTP/1.0 -Host: lowercase-deny -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; -ok($tf->handle_http($t) == 0, 'lowercase access'); - - - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/meson.build b/tests/meson.build index 943c1adf..c6f03be6 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -13,24 +13,11 @@ env.set('srcdir', meson.current_source_dir()) env.set('top_builddir', meson.build_root()) tests = [ - 'core-404-handler.t', + 'request.t', 'core-condition.t', - 'core-keepalive.t', - 'core-request.t', - 'core-response.t', 'core-var-include.t', - 'lowercase.t', - 'mod-auth.t', - 'mod-cgi.t', - 'mod-deflate.t', - 'mod-extforward.t', 'mod-fastcgi.t', - 'mod-proxy.t', - 'mod-secdownload.t', - 'mod-setenv.t', - 'mod-ssi.t', - 'request.t', - 'symlink.t', + 'mod-scgi.t', ] # just hope it will run the tests in the given order diff --git a/tests/mod-auth.conf b/tests/mod-auth.conf deleted file mode 100644 index a5742246..00000000 --- a/tests/mod-auth.conf +++ /dev/null @@ -1,46 +0,0 @@ -debug.log-request-handling = "enable" -debug.log-request-header = "enable" -debug.log-response-header = "enable" - -server.systemd-socket-activation = "enable" -server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" -server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" -server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" -server.name = "www.example.org" -server.tag = "Apache 1.3.29" - -server.compat-module-load = "disable" -server.modules = ( - "mod_auth", - "mod_authn_file", - "mod_status", - "mod_accesslog", - "mod_staticfile", -) - -accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" - -$HTTP["host"] == "auth-htpasswd.example.org" { - auth.backend = "htpasswd" -} - -auth.backend = "plain" -auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" - -auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd" - -auth.require = ( - "/server-status" => ( - "method" => "digest", - "realm" => "download archiv", - "require" => "group=www|user=jan|host=192.168.2.10", - ), - "/server-config" => ( - "method" => "basic", - "realm" => "download archiv", - "require" => "valid-user", - ), -) - -status.status-url = "/server-status" -status.config-url = "/server-config" diff --git a/tests/mod-auth.t b/tests/mod-auth.t deleted file mode 100755 index c940ef33..00000000 --- a/tests/mod-auth.t +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 20; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -$tf->{CONFIGFILE} = 'mod-auth.conf'; -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /server-status HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'Missing Auth-token'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Authorization: Basic \x80mFuOmphb -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid base64 Auth-token'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Authorization: Basic bm90Oml0Cg== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Wrong Auth-token'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Authorization: Basic amFuOmphbg== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - plain'); - -SKIP: { - skip "no crypt-des under openbsd", 2 if $^O eq 'openbsd'; -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: Basic ZGVzOmRlcw== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (des)'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: basic ZGVzOmRlcw== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (des) (lowercase)'); -} - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: Basic c2hhOnNoYQ== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (sha)'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: Basic c2hhOnNoYg== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (sha, wrong password)'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: Basic YXByLW1kNTphcHItbWQ1 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (apr-md5)'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: Basic YXByLW1kNTphcHItbWQ2 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (apr-md5, wrong password)'); - -SKIP: { - skip "no crypt-md5 under cygwin", 1 if $^O eq 'cygwin'; - skip "no crypt-md5 under darwin", 1 if $^O eq 'darwin'; - skip "no crypt-md5 under openbsd",1 if $^O eq 'openbsd'; -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Host: auth-htpasswd.example.org -Authorization: Basic bWQ1Om1kNQ== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (crypt-md5)'); -} - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Authorization: Basic bWQ1Om1kNA== -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token'); - -## this should not crash -$t->{REQUEST} = ( <<EOF -GET /server-status HTTP/1.0 -User-Agent: Wget/1.9.1 -Authorization: Digest username="jan", realm="jan", nonce="9a5428ccc05b086a08d918e73b01fc6f", - uri="/server-status", response="ea5f7d9a30b8b762f9610ccb87dea74f" -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; -ok($tf->handle_http($t) == 0, 'Digest-Auth: missing qop, no crash'); - -# (Note: test case is invalid; mismatch between request line and uri="..." -# is not what is intended to be tested here, but that is what is invalid) -# https://redmine.lighttpd.net/issues/477 -## this should not crash -$t->{REQUEST} = ( <<EOF -GET /server-status HTTP/1.0 -User-Agent: Wget/1.9.1 -Authorization: Digest username="jan", realm="jan", - nonce="b1d12348b4620437c43dd61c50ae4639", - uri="/MJ-BONG.xm.mpc", qop=auth, noncecount=00000001", - cnonce="036FCA5B86F7E7C4965C7F9B8FE714B7", - response="29B32C2953C763C6D033C8A49983B87E" -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; -ok($tf->handle_http($t) == 0, 'Digest-Auth: missing nc (noncecount instead), no crash'); - -$t->{REQUEST} = ( <<EOF -GET /server-config HTTP/1.0 -Authorization: Basic = -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; -ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid Base64'); - -$t->{REQUEST} = ( <<EOF -GET /server-status HTTP/1.0 -Authorization: Digest username="jan", realm="download archiv", - nonce="b3b26457000000003a9b34a3cd56d26e48a52a498ac9765d4b", - uri="/server-status", qop=auth, nc=00000001, - algorithm="md5-sess", response="049b000fb00ab51dddea6f093a96aa2e" -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; -ok($tf->handle_http($t) == 0, 'Digest-Auth: md5-sess + missing cnonce'); - - $t->{REQUEST} = ( <<EOF -GET /server-status HTTP/1.0 -Authorization: Digest username="jan", realm="download archiv", - nonce="b3b26457000000003a9b34a3cd56d26e48a52a498ac9765d4b", - uri="/server-status", qop=auth, nc=00000001, cnonce="65ee1b37", - algorithm="md5", response="049b000fb00ab51dddea6f093a96aa2e" -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401, 'WWW-Authenticate' => '/, stale=true$/' } ]; -ok($tf->handle_http($t) == 0, 'Digest-Auth: stale nonce'); - -$t->{REQUEST} = ( <<EOF -GET /server-status HTTP/1.0 -Authorization: Digest username = "jan", realm = "download archiv", - nonce = "b3b26457000000003a9b34a3cd56d26e48a52a498ac9765d4b", - uri = "/server-status", qop = auth, nc = 00000001, cnonce = "65ee1b37", - algorithm = "md5", response = "049b000fb00ab51dddea6f093a96aa2e" -EOF - ); # note: trailing whitespace at end of request line above is intentional -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401, 'WWW-Authenticate' => '/, stale=true$/' } ]; -ok($tf->handle_http($t) == 0, 'Digest-Auth: BWS, trailing WS, stale nonce'); - - - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/mod-cgi.t b/tests/mod-cgi.t deleted file mode 100755 index c591c916..00000000 --- a/tests/mod-cgi.t +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 23; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -# mod-cgi -# -$t->{REQUEST} = ( <<EOF -GET /cgi.pl HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'perl via cgi'); - -if ($^O ne "cygwin") { - $t->{REQUEST} = ( <<EOF -GET /cgi.pl%20%20%20 HTTP/1.0 -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - ok($tf->handle_http($t) == 0, 'No source retrieval'); -} else { - ok(1, 'No source retrieval; skipped on cygwin; see response.c'); -} - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl/foo?env=SCRIPT_NAME HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/cgi.pl' } ]; -ok($tf->handle_http($t) == 0, 'perl via cgi + pathinfo'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?internal-redir HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'perl via cgi and internal redirect from CGI'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?xsendfile HTTP/1.0 -Host: cgi.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => 4348 } ]; -ok($tf->handle_http($t) == 0, 'X-Sendfile'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?external-redir HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => 'http://www.example.org:2048/' } ]; -ok($tf->handle_http($t) == 0, 'Status + Location via FastCGI'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl/?external-redir HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => 'http://www.example.org:2048/' } ]; -ok($tf->handle_http($t) == 0, 'Trailing slash as path-info (#1989: workaround broken operating systems)'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?nph=30 HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 502 } ]; -ok($tf->handle_http($t) == 0, 'NPH + perl, invalid status-code (#14)'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?nph=304 HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; -ok($tf->handle_http($t) == 0, 'NPH + perl, setting status-code (#1125)'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?nph=200 HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf->handle_http($t) == 0, 'NPH + perl, setting status-code'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=GATEWAY_INTERFACE HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'CGI/1.1' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: GATEWAY_INTERFACE'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?query_string HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'query_string', 'Content-Type' => 'text/plain' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: QUERY_STRING'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=SCRIPT_NAME HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/cgi.pl' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: SCRIPT_NAME'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl/path/info?env=SCRIPT_NAME HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/cgi.pl' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: SCRIPT_NAME w/ PATH_INFO'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl/path/info?env=PATH_INFO HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/path/info' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: PATH_INFO'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=HTTP_XX_YY123 HTTP/1.0 -xx-yy123: foo -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'foo' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: quoting headers with numbers'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=HTTP_HOST HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'www.example.org' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: HTTP_HOST'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=HTTP_HOST HTTP/1.1 -Host: www.example.org -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, '+Content-Length' => '' } ]; -ok($tf->handle_http($t) == 0, 'cgi-env: HTTP_HOST'); - -# broken header crash -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?crlfcrash HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => 'http://www.example.org/' } ]; -ok($tf->handle_http($t) == 0, 'broken header via perl cgi'); - -$t->{REQUEST} = ( <<EOF -GET /indexfile/ HTTP/1.0 -Host: cgi.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/indexfile/index.pl' } ]; -ok($tf->handle_http($t) == 0, 'index-file handling, Bug #3, Bug #6'); - -$t->{REQUEST} = ( <<EOF -POST /indexfile/abc HTTP/1.0 -Host: cgi.example.org -Content-Length: 0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => '/indexfile/index.pl' } ]; -ok($tf->handle_http($t) == 0, 'server.error-handler-404, Bug #12'); - - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/mod-deflate.conf b/tests/mod-deflate.conf deleted file mode 100644 index be197714..00000000 --- a/tests/mod-deflate.conf +++ /dev/null @@ -1,35 +0,0 @@ -debug.log-request-handling = "enable" -debug.log-response-header = "disable" -debug.log-request-header = "disable" - -server.systemd-socket-activation = "enable" -server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" -server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" -server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" -server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" -server.name = "www.example.org" - -server.compat-module-load = "disable" -server.modules = ( - "mod_deflate", - "mod_staticfile", -) - -mimetype.assign = ( - ".html" => "text/html", - ".txt" => "text/plain; charset=utf-8", -) - -$HTTP["host"] == "cache.example.org" { - deflate.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" -} - -deflate.mimetypes = ( - "text/plain", - "text/html", -) - -deflate.allowed-encodings = ( - "gzip", - "deflate", -) diff --git a/tests/mod-deflate.t b/tests/mod-deflate.t deleted file mode 100755 index 7cabcb9f..00000000 --- a/tests/mod-deflate.t +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 11; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -$tf->{CONFIGFILE} = 'mod-deflate.conf'; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Accept-Encoding: deflate -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '' } ]; -ok($tf->handle_http($t) == 0, 'Vary is set'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Accept-Encoding: deflate -Host: no-cache.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1288', '+Content-Encoding' => '' } ]; -ok($tf->handle_http($t) == 0, 'deflate - Content-Length and Content-Encoding is set'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Accept-Encoding: deflate -Host: cache.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1288', '+Content-Encoding' => '' } ]; -ok($tf->handle_http($t) == 0, 'deflate - Content-Length and Content-Encoding is set'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Accept-Encoding: gzip -Host: no-cache.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1306', '+Content-Encoding' => '' } ]; -ok($tf->handle_http($t) == 0, 'gzip - Content-Length and Content-Encoding is set'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Accept-Encoding: gzip -Host: cache.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1306', '+Content-Encoding' => '' } ]; -ok($tf->handle_http($t) == 0, 'gzip - Content-Length and Content-Encoding is set'); - - -$t->{REQUEST} = ( <<EOF -GET /index.txt HTTP/1.0 -Accept-Encoding: gzip, deflate -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', '+Content-Encoding' => '' } ]; -ok($tf->handle_http($t) == 0, 'gzip, deflate - Content-Length and Content-Encoding is set'); - -$t->{REQUEST} = ( <<EOF -GET /index.txt HTTP/1.0 -Accept-Encoding: gzip, deflate -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', '+Content-Encoding' => '', 'Content-Type' => "text/plain; charset=utf-8" } ]; -ok($tf->handle_http($t) == 0, 'Content-Type is from the original file'); - -$t->{REQUEST} = ( <<EOF -GET /index.txt HTTP/1.0 -Accept-encoding: -X-Accept-encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0 -User-Agent: MYOB/6.66 (AN/ON) -Connection: close -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '-Content-Encoding' => '', 'Content-Type' => "text/plain; charset=utf-8" } ]; -ok($tf->handle_http($t) == 0, 'Empty Accept-Encoding'); - -$t->{REQUEST} = ( <<EOF -GET /index.txt HTTP/1.0 -Accept-Encoding: bzip2, gzip, deflate -Host: cache.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Encoding' => 'gzip', 'Content-Type' => "text/plain; charset=utf-8" } ]; -ok($tf->handle_http($t) == 0, 'bzip2 requested but disabled'); - - -ok($tf->stop_proc == 0, "Stopping lighttpd"); diff --git a/tests/mod-extforward.conf b/tests/mod-extforward.conf deleted file mode 100644 index e67867aa..00000000 --- a/tests/mod-extforward.conf +++ /dev/null @@ -1,30 +0,0 @@ -debug.log-request-handling = "enable" -debug.log-response-header = "disable" -debug.log-request-header = "disable" - -server.systemd-socket-activation = "enable" -server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" -server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" -server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" -server.name = "www.example.org" -server.tag = "Apache 1.3.29" - -server.compat-module-load = "disable" -server.modules = ( - "mod_cgi", - "mod_extforward", -) - -mimetype.assign = ( - ".html" => "text/html", -) - -cgi.assign = ( - ".pl" => env.PERL, -) - -extforward.headers = ( "Forwarded", "X-Forwarded-For", "Forwarded-For" ) -extforward.forwarder = ( - "127.0.0.1" => "trust", - "127.0.30.1" => "trust", -) diff --git a/tests/mod-extforward.t b/tests/mod-extforward.t deleted file mode 100755 index 69c8cf11..00000000 --- a/tests/mod-extforward.t +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 6; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -$tf->{CONFIGFILE} = 'mod-extforward.conf'; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 -Host: www.example.org -X-Forwarded-For: 127.0.10.1 -EOF -); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.10.1' } ]; -ok($tf->handle_http($t) == 0, 'expect 127.0.10.1, from single ip'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 -Host: www.example.org -X-Forwarded-For: 127.0.10.1, 127.0.20.1 -EOF -); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; -ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from two ips'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 -Host: www.example.org -X-Forwarded-For: 127.0.10.1, 127.0.20.1, 127.0.30.1 -EOF -); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; -ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from chained proxies'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 -Host: www.example.org -Forwarded: for=127.0.10.1, for=127.0.20.1;proto=https, for=127.0.30.1;proto=http -EOF -); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; -ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from chained proxies'); - -ok($tf->stop_proc == 0, "Stopping lighttpd"); diff --git a/tests/mod-proxy.t b/tests/mod-proxy.t deleted file mode 100755 index 809fd1a0..00000000 --- a/tests/mod-proxy.t +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 7; -use LightyTest; - -my $tf_real = LightyTest->new(); -my $tf_proxy = LightyTest->new(); - -my $t; - -## we need two procs -## 1. the real webserver -## 2. the proxy server - -$tf_real->{CONFIGFILE} = 'lighttpd.conf'; -$tf_proxy->{CONFIGFILE} = 'proxy.conf'; - -ok($tf_real->start_proc == 0, "Starting lighttpd") or goto cleanup; - -$ENV{EPHEMERAL_PORT} = $tf_real->{PORT}; -ok($tf_proxy->start_proc == 0, "Starting lighttpd as proxy") or goto cleanup; - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; -ok($tf_proxy->handle_http($t) == 0, 'valid request'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'Apache 1.3.29' } ]; -ok($tf_proxy->handle_http($t) == 0, 'drop Server from real server'); - - $t->{REQUEST} = ( <<EOF -GET /rewrite/all/some+test%3axxx%20with%20space HTTP/1.0 -Host: www.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/some+test%3Axxx%20with%20space' } ]; - ok($tf_proxy->handle_http($t) == 0, 'rewrited urls work with encoded path'); - -ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy"); - -ok($tf_real->stop_proc == 0, "Stopping lighttpd"); - -exit 0; - -cleanup: - -$tf_real->stop_proc; -$tf_proxy->stop_proc; - -die(); diff --git a/tests/mod-secdownload.conf b/tests/mod-secdownload.conf deleted file mode 100644 index 63407df9..00000000 --- a/tests/mod-secdownload.conf +++ /dev/null @@ -1,47 +0,0 @@ -debug.log-request-handling = "enable" -debug.log-request-header = "enable" -debug.log-response-header = "enable" - -server.systemd-socket-activation = "enable" -server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" -server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" -server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" -server.name = "www.example.org" -server.tag = "Apache 1.3.29" - -server.compat-module-load = "disable" -server.modules = ( - "mod_secdownload", - "mod_accesslog", - "mod_staticfile", -) - -accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" - -$HTTP["host"] == "vvv.example.org" { - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - secdownload.secret = "verysecret" - secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - secdownload.uri-prefix = "/sec/" - secdownload.timeout = 120 - secdownload.algorithm = "md5" -} - -$HTTP["host"] == "vvv-sha1.example.org" { - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - secdownload.secret = "verysecret" - secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - secdownload.uri-prefix = "/sec/" - secdownload.timeout = 120 - secdownload.algorithm = "hmac-sha1" -} - -$HTTP["host"] == "vvv-sha256.example.org" { - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - secdownload.secret = "verysecret" - secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" - secdownload.uri-prefix = "/sec/" - secdownload.timeout = 120 - secdownload.algorithm = "hmac-sha256" - secdownload.hash-querystr = "enable" -} diff --git a/tests/mod-secdownload.t b/tests/mod-secdownload.t deleted file mode 100755 index fcbc5f30..00000000 --- a/tests/mod-secdownload.t +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 16; -use LightyTest; -use Digest::MD5 qw(md5_hex); -use Digest::SHA qw(hmac_sha1 hmac_sha256); -use MIME::Base64 qw(encode_base64url); - -my $tf = LightyTest->new(); -my $t; - -$tf->{CONFIGFILE} = 'mod-secdownload.conf'; -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -my $secret = "verysecret"; -my ($f, $thex, $m); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'skipping secdownload - direct access'); - -## MD5 -$f = "/index.html"; -$thex = sprintf("%08x", time); -$m = md5_hex($secret.$f.$thex); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload (md5)'); - -$thex = sprintf("%08x", time - 1800); -$m = md5_hex($secret.$f.$thex); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 410 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - gone (timeout) (md5)'); - -$t->{REQUEST} = ( <<EOF -GET /sec$f HTTP/1.0 -Host: vvv.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - direct access (md5)'); - -$f = "/noexists"; -$thex = sprintf("%08x", time); -$m = md5_hex($secret.$f.$thex); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - timeout (md5)'); - - -if (!$tf->has_crypto()) { - - for (1..4) { ok(1, "secdownload (hmac-sha1) (skipped) - (missing SSL support)"); } - for (1..5) { ok(1, "secdownload (hmac-sha256) (skipped) - (missing SSL support)"); } - -} -else { - -## HMAC-SHA1 -$f = "/index.html"; -$thex = sprintf("%08x", time); -$m = encode_base64url(hmac_sha1("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha1.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload (hmac-sha1)'); - -$thex = sprintf("%08x", time - 1800); -$m = encode_base64url(hmac_sha1("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha1.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 410 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - gone (timeout) (hmac-sha1)'); - -$t->{REQUEST} = ( <<EOF -GET /sec$f HTTP/1.0 -Host: vvv-sha1.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - direct access (hmac-sha1)'); - - -$f = "/noexists"; -$thex = sprintf("%08x", time); -$m = encode_base64url(hmac_sha1("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha1.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - timeout (hmac-sha1)'); - -## HMAC-SHA256 -$f = "/index.html"; -$thex = sprintf("%08x", time); -$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha256.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload (hmac-sha256)'); - -## HMAC-SHA256 -$f = "/index.html?qs=1"; -$thex = sprintf("%08x", time); -$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha256.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload (hmac-sha256) with hash-querystr'); - -$thex = sprintf("%08x", time - 1800); -$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha256.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 410 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - gone (timeout) (hmac-sha256)'); - -$t->{REQUEST} = ( <<EOF -GET /sec$f HTTP/1.0 -Host: vvv-sha256.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - direct access (hmac-sha256)'); - - -$f = "/noexists"; -$thex = sprintf("%08x", time); -$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); - -$t->{REQUEST} = ( <<EOF -GET /sec/$m/$thex$f HTTP/1.0 -Host: vvv-sha256.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; - -ok($tf->handle_http($t) == 0, 'secdownload - timeout (hmac-sha256)'); - -} # SKIP if lighttpd built without crypto algorithms (e.g. without openssl) - -## THE END - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/mod-setenv.t b/tests/mod-setenv.t deleted file mode 100755 index 486c39c5..00000000 --- a/tests/mod-setenv.t +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 9; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=TRAC_ENV HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'tracenv' } ]; -ok($tf->handle_http($t) == 0, 'query first setenv'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=SETENV HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'setenv' } ]; -ok($tf->handle_http($t) == 0, 'query second setenv'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=NEWENV HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'newenv' } ]; -ok($tf->handle_http($t) == 0, 'query set-environment'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=HTTP_FOO HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'foo' } ]; -ok($tf->handle_http($t) == 0, 'query add-request-header'); - -$t->{REQUEST} = ( <<EOF -GET /cgi.pl?env=HTTP_FOO2 HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'foo2' } ]; -ok($tf->handle_http($t) == 0, 'query set-request-header'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'BAR' => 'foo' } ]; -ok($tf->handle_http($t) == 0, 'query add-response-header'); - -$t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: www.example.org -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'BAR2' => 'bar2' } ]; -ok($tf->handle_http($t) == 0, 'query set-response-header'); - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/mod-ssi.t b/tests/mod-ssi.t deleted file mode 100755 index f2f3bf4c..00000000 --- a/tests/mod-ssi.t +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 5; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; - -ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -$t->{REQUEST} = ( <<EOF -GET /ssi.shtml HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "/ssi.shtml\n" } ]; -ok($tf->handle_http($t) == 0, 'ssi - echo '); - - -## bug #280 -$t->{REQUEST} = ( <<EOF -GET /exec-date.shtml HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "2\n\n" } ]; -ok($tf->handle_http($t) == 0, 'ssi - echo '); - - -$t->{REQUEST} = ( <<EOF -GET /ssi-include.shtml HTTP/1.0 -EOF - ); -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "/ssi-include.shtml\n/ssi-include.shtml\n/ssi-include.shtml\nssi-include\n\nssi-include\n\n" } ]; -ok($tf->handle_http($t) == 0, 'ssi - include'); - - -ok($tf->stop_proc == 0, "Stopping lighttpd"); - diff --git a/tests/request.t b/tests/request.t index f2264486..30bc303f 100755 --- a/tests/request.t +++ b/tests/request.t @@ -8,7 +8,7 @@ BEGIN { use strict; use IO::Socket; -use Test::More tests => 44; +use Test::More tests => 181; use LightyTest; my $tf = LightyTest->new(); @@ -19,6 +19,66 @@ ok($tf->start_proc == 0, "Starting lighttpd") or die(); ## Basic Request-Handling $t->{REQUEST} = ( <<EOF +GET / HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Valid HTTP/1.0 Request') or die(); + +$t->{REQUEST} = ( <<EOF +OPTIONS * HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'OPTIONS'); + +$t->{REQUEST} = ( <<EOF +OPTIONS / HTTP/1.1 +Host: www.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'OPTIONS'); + +$t->{REQUEST} = ( <<EOF +GET /index.html%00 HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; +ok($tf->handle_http($t) == 0, 'URL-encoding, %00'); + +$t->{REQUEST} = ( <<EOF +POST /12345.txt HTTP/1.0 +Host: 123.example.org +Content-Length: 2147483648 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 413 } ]; +ok($tf->handle_http($t) == 0, 'Content-Length > max-request-size'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ]; +ok($tf->handle_http($t) == 0, 'Content-Type - image/jpeg'); + +$t->{REQUEST} = ( <<EOF +GET /image.JPG HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ]; +ok($tf->handle_http($t) == 0, 'Content-Type - image/jpeg (upper case)'); + +$t->{REQUEST} = ( <<EOF +GET /Foo.txt HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'uppercase filenames'); + +$t->{REQUEST} = ( <<EOF GET /foobar?foobar HTTP/1.0 EOF ); @@ -510,5 +570,1301 @@ EOF $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain', 'Connection' => 'close' } ]; ok($tf->handle_http($t) == 0, 'Connection-header, comma and space after value'); -ok($tf->stop_proc == 0, "Stopping lighttpd"); +## Low-Level Response-Header Parsing - HTTP/1.1 + +$t->{REQUEST} = ( <<EOF +GET / HTTP/1.1 +Host: www.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, '+Date' => '' } ]; +ok($tf->handle_http($t) == 0, 'Date header'); + + +## Low-Level Response-Header Parsing - Content-Length + + +$t->{REQUEST} = ( <<EOF +GET /12345.html HTTP/1.0 +Host: 123.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => '6' } ]; +ok($tf->handle_http($t) == 0, 'Content-Length for text/html'); + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.0 +Host: 123.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => '6' } ]; +ok($tf->handle_http($t) == 0, 'Content-Length for text/plain'); + + +## Low-Level Response-Header Parsing - Location + +$t->{REQUEST} = ( <<EOF +GET /dummydir HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/dummydir/' } ]; +ok($tf->handle_http($t) == 0, 'internal redirect in directory'); + +$t->{REQUEST} = ( <<EOF +GET /dummydir?foo HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/dummydir/?foo' } ]; +ok($tf->handle_http($t) == 0, 'internal redirect in directory + querystring'); + +$t->{REQUEST} = ( <<EOF +GET /~test%20ä_ HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/~test%20%C3%A4_/' } ]; +ok($tf->handle_http($t) == 0, 'internal redirect in directory with special characters'); + +$t->{REQUEST} = ( <<EOF +GET /~test%20ä_?foo HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => '/~test%20%C3%A4_/?foo' } ]; +ok($tf->handle_http($t) == 0, 'internal redirect in directory with special characters + querystring'); + + +## simple-vhost + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.0 +Host: no-simple.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => '6' } ]; +ok($tf->handle_http($t) == 0, 'disabling simple-vhost via conditionals'); + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.0 +Host: simple.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; +ok($tf->handle_http($t) == 0, 'simple-vhost via conditionals'); + + +## keep-alive + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.0 +Connection: keep-alive +Host: 123.example.org + +GET /12345.txt HTTP/1.0 +Host: 123.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Explicit HTTP/1.0 Keep-Alive'); +undef $t->{RESPONSE}; + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.0 +Connection: keep-alive +Host: 123.example.org + +GET /12345.txt HTTP/1.0 +Host: 123.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Explicit HTTP/1.0 Keep-Alive'); +undef $t->{RESPONSE}; + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.0 +Connection: keep-alive +Host: 123.example.org + +GET /12345.txt HTTP/1.0 +Host: 123.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.0 Keep-Alive'); + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.1 +Connection: keep-alive +Host: 123.example.org + +GET /12345.txt HTTP/1.1 +Host: 123.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Explicit HTTP/1.1 Keep-Alive'); + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.1 +Host: 123.example.org + +GET /12345.txt HTTP/1.1 +Host: 123.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.1 Keep-Alive'); + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.1 +Host: 123.example.org + + +GET /12345.txt HTTP/1.1 +Host: 123.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.1 Keep-Alive w/ extra blank b/w requests'); + +$t->{REQUEST} = ( <<EOF +GET /12345.txt HTTP/1.1 +Host: 123.example.org + + + +GET /12345.txt HTTP/1.1 +Host: 123.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; +ok($tf->handle_http($t) == 0, 'Implicit HTTP/1.1 Keep-Alive w/ excess blank b/w requests'); + + +## 404 handlers + +$t->{REQUEST} = ( <<EOF +GET /static/notfound HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "static not found\n" } ]; +ok($tf->handle_http($t) == 0, '404 handler => static'); + +$t->{REQUEST} = ( <<EOF +GET /dynamic/200/notfound HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "found here\n" } ]; +ok($tf->handle_http($t) == 0, '404 handler => dynamic(200)'); + +$t->{REQUEST} = ( <<EOF +GET /dynamic/302/notfound HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => "http://www.example.org/" } ]; +ok($tf->handle_http($t) == 0, '404 handler => dynamic(302)'); + +$t->{REQUEST} = ( <<EOF +GET /dynamic/404/notfound HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => "Not found here\n" } ]; +ok($tf->handle_http($t) == 0, '404 handler => dynamic(404)'); + +$t->{REQUEST} = ( <<EOF +GET /dynamic/redirect_status/ HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => "REDIRECT_STATUS\n" } ]; +ok($tf->handle_http($t) == 0, 'error handler => dynamic(REDIRECT_STATUS)'); + +$t->{REQUEST} = ( <<EOF +GET /dynamic/nostatus/notfound HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "found here\n" } ]; +ok($tf->handle_http($t) == 0, '404 handler => dynamic(nostatus)'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?send404 HTTP/1.0 +Host: errors.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => "send404\n" } ]; +ok($tf->handle_http($t) == 0, '404 generated by CGI should stay 404'); + + +## config conditions + +$t->{REQUEST} = ( <<EOF +GET /nofile.png HTTP/1.0 +Host: referer.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; +ok($tf->handle_http($t) == 0, 'condition: Referer - no referer'); + +$t->{REQUEST} = ( <<EOF +GET /nofile.png HTTP/1.0 +Host: referer.example.org +Referer: http://referer.example.org/ +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; +ok($tf->handle_http($t) == 0, 'condition: Referer - referer matches regex'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'condition: Referer - no referer'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: www.example.org +Referer: http://referer.example.org/ +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'condition: Referer - referer matches regex'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: www.example.org +Referer: http://evil-referer.example.org/ +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'condition: Referer - referer doesn\'t match'); + +$t->{REQUEST} = ( <<EOF +GET /nofile HTTP/1.1 +Host: bug255.example.org + +GET /nofile HTTP/1.1 +Host: bug255.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 403 }, { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'remote ip cache (#255)'); + +$t->{REQUEST} = ( <<EOF +GET /empty-ref.noref HTTP/1.0 +Cookie: empty-ref +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'condition: $HTTP["referer"] == "" and Referer is no set'); + +$t->{REQUEST} = ( <<EOF +GET /empty-ref.noref HTTP/1.0 +Cookie: empty-ref +Referer: +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'condition: $HTTP["referer"] == "" and Referer is empty'); + +$t->{REQUEST} = ( <<EOF +GET /empty-ref.noref HTTP/1.0 +Cookie: empty-ref +Referer: foobar +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; +ok($tf->handle_http($t) == 0, 'condition: $HTTP["referer"] == "" and Referer: foobar'); + + +## case-insensitive filesystem policy + +## check if lower-casing works + +$t->{REQUEST} = ( <<EOF +GET /image.JPG HTTP/1.0 +Host: lowercase-allow +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'uppercase access'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: lowercase-allow +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'lowercase access'); + +## check that mod_auth works + +$t->{REQUEST} = ( <<EOF +GET /image.JPG HTTP/1.0 +Host: lowercase-auth +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'uppercase access'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: lowercase-auth +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'lowercase access'); + + +## check that mod_staticfile exclude works +$t->{REQUEST} = ( <<EOF +GET /image.JPG HTTP/1.0 +Host: lowercase-exclude +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'upper case access to staticfile.exclude-extension'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: lowercase-exclude +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'lowercase access'); + + +## check that mod_access exclude works +$t->{REQUEST} = ( <<EOF +GET /image.JPG HTTP/1.0 +Host: lowercase-deny +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'uppercase access to url.access-deny protected location'); + +$t->{REQUEST} = ( <<EOF +GET /image.jpg HTTP/1.0 +Host: lowercase-deny +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; +ok($tf->handle_http($t) == 0, 'lowercase access'); + + +## symlink policy + +my $docroot = $tf->{'TESTDIR'}."/tmp/lighttpd/servers/www.example.org/pages"; + +sub init_testbed { + return 0 unless eval { symlink("",""); 1 }; + my $f = "$docroot/index.html"; + my $l = "$docroot/index.xhtml"; + my $rc = undef; + unless (-l $l) { + return 0 unless symlink($f,$l); + }; + $f = "$docroot/expire"; + $l = "$docroot/symlinked"; + $rc = undef; + unless (-l $l) { + return 0 unless symlink($f,$l); + } + return 1; +}; + +SKIP: { + skip "perl does not support symlinking or setting up the symlinks failed.", 8 unless init_testbed; + +# allow case +# simple file + $t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: symlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + ok($tf->handle_http($t) == 0, 'allow: simple file'); + +# symlinked file + $t->{REQUEST} = ( <<EOF +GET /index.xhtml HTTP/1.0 +Host: symlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + ok($tf->handle_http($t) == 0, 'allow: symlinked file'); + +# directly symlinked dir + $t->{REQUEST} = ( <<EOF +GET /symlinked/ HTTP/1.0 +Host: symlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + ok($tf->handle_http($t) == 0, 'allow: directly symlinked dir'); + +# symlinked dir in path + $t->{REQUEST} = ( <<EOF +GET /symlinked/access.txt HTTP/1.0 +Host: symlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + ok($tf->handle_http($t) == 0, 'allow: symlinked dir in path'); + +# deny case +# simple file + $t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: nosymlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + ok($tf->handle_http($t) == 0, 'deny: simple file'); + +# symlinked file + $t->{REQUEST} = ( <<EOF +GET /index.xhtml HTTP/1.0 +Host: nosymlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; + ok($tf->handle_http($t) == 0, 'deny: symlinked file'); + +# directly symlinked dir + $t->{REQUEST} = ( <<EOF +GET /symlinked/ HTTP/1.0 +Host: nosymlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; + ok($tf->handle_http($t) == 0, 'deny: directly symlinked dir'); + +# symlinked dir in path + $t->{REQUEST} = ( <<EOF +GET /symlinked/access.txt HTTP/1.0 +Host: nosymlink.example.org +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; + ok($tf->handle_http($t) == 0, 'deny: symlinked dir in path'); + +}; + + +## mod_auth + +$t->{REQUEST} = ( <<EOF +GET /server-status HTTP/1.0 +Host: auth-plain.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'Missing Auth-token'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-plain.example.org +Authorization: Basic \x80mFuOmphb +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid base64 Auth-token'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-plain.example.org +Authorization: Basic bm90Oml0Cg== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Wrong Auth-token'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-plain.example.org +Authorization: Basic amFuOmphbg== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - plain'); + +SKIP: { + skip "no crypt-des under openbsd", 2 if $^O eq 'openbsd'; +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: Basic ZGVzOmRlcw== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (des)'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: basic ZGVzOmRlcw== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (des) (lowercase)'); +} + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: Basic c2hhOnNoYQ== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (sha)'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: Basic c2hhOnNoYg== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (sha, wrong password)'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: Basic YXByLW1kNTphcHItbWQ1 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (apr-md5)'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: Basic YXByLW1kNTphcHItbWQ2 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (apr-md5, wrong password)'); + +SKIP: { + skip "no crypt-md5 under cygwin", 1 if $^O eq 'cygwin'; + skip "no crypt-md5 under darwin", 1 if $^O eq 'darwin'; + skip "no crypt-md5 under openbsd",1 if $^O eq 'openbsd'; +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-htpasswd.example.org +Authorization: Basic bWQ1Om1kNQ== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token - htpasswd (crypt-md5)'); +} + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-plain.example.org +Authorization: Basic bWQ1Om1kNA== +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Valid Auth-token'); + +## this should not crash +$t->{REQUEST} = ( <<EOF +GET /server-status HTTP/1.0 +Host: auth-plain.example.org +User-Agent: Wget/1.9.1 +Authorization: Digest username="jan", realm="jan", nonce="9a5428ccc05b086a08d918e73b01fc6f", + uri="/server-status", response="ea5f7d9a30b8b762f9610ccb87dea74f" +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; +ok($tf->handle_http($t) == 0, 'Digest-Auth: missing qop, no crash'); + +# (Note: test case is invalid; mismatch between request line and uri="..." +# is not what is intended to be tested here, but that is what is invalid) +# https://redmine.lighttpd.net/issues/477 +## this should not crash +$t->{REQUEST} = ( <<EOF +GET /server-status HTTP/1.0 +Host: auth-plain.example.org +User-Agent: Wget/1.9.1 +Authorization: Digest username="jan", realm="jan", + nonce="b1d12348b4620437c43dd61c50ae4639", + uri="/MJ-BONG.xm.mpc", qop=auth, noncecount=00000001", + cnonce="036FCA5B86F7E7C4965C7F9B8FE714B7", + response="29B32C2953C763C6D033C8A49983B87E" +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; +ok($tf->handle_http($t) == 0, 'Digest-Auth: missing nc (noncecount instead), no crash'); + +$t->{REQUEST} = ( <<EOF +GET /server-config HTTP/1.0 +Host: auth-plain.example.org +Authorization: Basic = +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; +ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid Base64'); + +$t->{REQUEST} = ( <<EOF +GET /server-status HTTP/1.0 +Host: auth-plain.example.org +Authorization: Digest username="jan", realm="download archiv", + nonce="b3b26457000000003a9b34a3cd56d26e48a52a498ac9765d4b", + uri="/server-status", qop=auth, nc=00000001, + algorithm="md5-sess", response="049b000fb00ab51dddea6f093a96aa2e" +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; +ok($tf->handle_http($t) == 0, 'Digest-Auth: md5-sess + missing cnonce'); + + $t->{REQUEST} = ( <<EOF +GET /server-status HTTP/1.0 +Host: auth-plain.example.org +Authorization: Digest username="jan", realm="download archiv", + nonce="b3b26457000000003a9b34a3cd56d26e48a52a498ac9765d4b", + uri="/server-status", qop=auth, nc=00000001, cnonce="65ee1b37", + algorithm="md5", response="049b000fb00ab51dddea6f093a96aa2e" +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401, 'WWW-Authenticate' => '/, stale=true$/' } ]; +ok($tf->handle_http($t) == 0, 'Digest-Auth: stale nonce'); + +$t->{REQUEST} = ( <<EOF +GET /server-status HTTP/1.0 +Host: auth-plain.example.org +Authorization: Digest username = "jan", realm = "download archiv", + nonce = "b3b26457000000003a9b34a3cd56d26e48a52a498ac9765d4b", + uri = "/server-status", qop = auth, nc = 00000001, cnonce = "65ee1b37", + algorithm = "md5", response = "049b000fb00ab51dddea6f093a96aa2e" +EOF + ); # note: trailing whitespace at end of request line above is intentional +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401, 'WWW-Authenticate' => '/, stale=true$/' } ]; +ok($tf->handle_http($t) == 0, 'Digest-Auth: BWS, trailing WS, stale nonce'); + + +## mod_cgi + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'perl via cgi'); + +if ($^O ne "cygwin") { + $t->{REQUEST} = ( <<EOF +GET /cgi.pl%20%20%20 HTTP/1.0 +EOF + ); + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + ok($tf->handle_http($t) == 0, 'No source retrieval'); +} else { + ok(1, 'No source retrieval; skipped on cygwin; see response.c'); +} + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl/foo?env=SCRIPT_NAME HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/cgi.pl' } ]; +ok($tf->handle_http($t) == 0, 'perl via cgi + pathinfo'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?internal-redir HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'perl via cgi and internal redirect from CGI'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?xsendfile HTTP/1.0 +Host: cgi.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Length' => 4348 } ]; +ok($tf->handle_http($t) == 0, 'X-Sendfile'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?external-redir HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => 'http://www.example.org:2048/' } ]; +ok($tf->handle_http($t) == 0, 'Status + Location via FastCGI'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl/?external-redir HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => 'http://www.example.org:2048/' } ]; +ok($tf->handle_http($t) == 0, 'Trailing slash as path-info (#1989: workaround broken operating systems)'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?nph=30 HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 502 } ]; +ok($tf->handle_http($t) == 0, 'NPH + perl, invalid status-code (#14)'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?nph=304 HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; +ok($tf->handle_http($t) == 0, 'NPH + perl, setting status-code (#1125)'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?nph=200 HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf->handle_http($t) == 0, 'NPH + perl, setting status-code'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=GATEWAY_INTERFACE HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'CGI/1.1' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: GATEWAY_INTERFACE'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?query_string HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'query_string', 'Content-Type' => 'text/plain' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: QUERY_STRING'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=SCRIPT_NAME HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/cgi.pl' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: SCRIPT_NAME'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl/path/info?env=SCRIPT_NAME HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/cgi.pl' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: SCRIPT_NAME w/ PATH_INFO'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl/path/info?env=PATH_INFO HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/path/info' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: PATH_INFO'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=HTTP_XX_YY123 HTTP/1.0 +xx-yy123: foo +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'foo' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: quoting headers with numbers'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=HTTP_HOST HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'www.example.org' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: HTTP_HOST'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=HTTP_HOST HTTP/1.1 +Host: www.example.org +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, '+Content-Length' => '' } ]; +ok($tf->handle_http($t) == 0, 'cgi-env: HTTP_HOST'); + +# broken header crash +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?crlfcrash HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 302, 'Location' => 'http://www.example.org/' } ]; +ok($tf->handle_http($t) == 0, 'broken header via perl cgi'); + +$t->{REQUEST} = ( <<EOF +GET /indexfile/ HTTP/1.0 +Host: cgi.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/indexfile/index.pl' } ]; +ok($tf->handle_http($t) == 0, 'index-file handling, Bug #3, Bug #6'); + +$t->{REQUEST} = ( <<EOF +POST /indexfile/abc HTTP/1.0 +Host: cgi.example.org +Content-Length: 0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'HTTP-Content' => '/indexfile/index.pl' } ]; +ok($tf->handle_http($t) == 0, 'server.error-handler-404, Bug #12'); + + +## mod_deflate + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: deflate.example.org +Accept-Encoding: deflate +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '' } ]; +ok($tf->handle_http($t) == 0, 'Vary is set'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Accept-Encoding: deflate +Host: deflate.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1288', '+Content-Encoding' => '' } ]; +ok($tf->handle_http($t) == 0, 'deflate - Content-Length and Content-Encoding is set'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Accept-Encoding: deflate +Host: deflate-cache.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1288', '+Content-Encoding' => '' } ]; +ok($tf->handle_http($t) == 0, 'deflate - Content-Length and Content-Encoding is set'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Accept-Encoding: gzip +Host: deflate.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1306', '+Content-Encoding' => '' } ]; +ok($tf->handle_http($t) == 0, 'gzip - Content-Length and Content-Encoding is set'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Accept-Encoding: gzip +Host: deflate-cache.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Length' => '1306', '+Content-Encoding' => '' } ]; +ok($tf->handle_http($t) == 0, 'gzip - Content-Length and Content-Encoding is set'); + + +$t->{REQUEST} = ( <<EOF +GET /index.txt HTTP/1.0 +Host: deflate.example.org +Accept-Encoding: gzip, deflate +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', '+Content-Encoding' => '' } ]; +ok($tf->handle_http($t) == 0, 'gzip, deflate - Content-Length and Content-Encoding is set'); + +$t->{REQUEST} = ( <<EOF +GET /index.txt HTTP/1.0 +Host: deflate.example.org +Accept-Encoding: gzip, deflate +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', '+Content-Encoding' => '', 'Content-Type' => "text/plain; charset=utf-8" } ]; +ok($tf->handle_http($t) == 0, 'Content-Type is from the original file'); + +$t->{REQUEST} = ( <<EOF +GET /index.txt HTTP/1.0 +Host: deflate.example.org +Accept-encoding: +X-Accept-encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0 +User-Agent: MYOB/6.66 (AN/ON) +Connection: close +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '-Content-Encoding' => '', 'Content-Type' => "text/plain; charset=utf-8" } ]; +ok($tf->handle_http($t) == 0, 'Empty Accept-Encoding'); + +$t->{REQUEST} = ( <<EOF +GET /index.txt HTTP/1.0 +Accept-Encoding: bzip2, gzip, deflate +Host: deflate-cache.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Encoding' => 'gzip', 'Content-Type' => "text/plain; charset=utf-8" } ]; +ok($tf->handle_http($t) == 0, 'bzip2 requested but disabled'); + + +## mod_extforward + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 +Host: www.example.org +X-Forwarded-For: 127.0.10.1 +EOF +); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.10.1' } ]; +ok($tf->handle_http($t) == 0, 'expect 127.0.10.1, from single ip'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 +Host: www.example.org +X-Forwarded-For: 127.0.10.1, 127.0.20.1 +EOF +); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; +ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from two ips'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 +Host: www.example.org +X-Forwarded-For: 127.0.10.1, 127.0.20.1, 127.0.30.1 +EOF +); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; +ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from chained proxies'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=REMOTE_ADDR HTTP/1.0 +Host: www.example.org +Forwarded: for=127.0.10.1, for=127.0.20.1;proto=https, for=127.0.30.1;proto=http +EOF +); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '127.0.20.1' } ]; +ok($tf->handle_http($t) == 0, 'expect 127.0.20.1, from chained proxies'); + + +## mod_proxy + +do { + +my $tf_proxy = LightyTest->new(); +$tf_proxy->{CONFIGFILE} = 'proxy.conf'; + +local $ENV{EPHEMERAL_PORT} = $tf->{PORT}; +ok($tf_proxy->start_proc == 0, "Starting lighttpd as proxy") or last; + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; +ok($tf_proxy->handle_http($t) == 0, 'valid request'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'lighttpd-1.4.x' } ]; +ok($tf_proxy->handle_http($t) == 0, 'drop Server from real server'); + +$t->{REQUEST} = ( <<EOF +GET /rewrite/all/some+test%3axxx%20with%20space HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/some+test%3Axxx%20with%20space' } ]; +ok($tf_proxy->handle_http($t) == 0, 'rewrited urls work with encoded path'); + +ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy"); + +} while (0); + + +## mod_secdownload + +use Digest::MD5 qw(md5_hex); +use Digest::SHA qw(hmac_sha1 hmac_sha256); +use MIME::Base64 qw(encode_base64url); + +my $secret = "verysecret"; +my ($f, $thex, $m); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + +ok($tf->handle_http($t) == 0, 'skipping secdownload - direct access'); + +## MD5 +$f = "/index.html"; +$thex = sprintf("%08x", time); +$m = md5_hex($secret.$f.$thex); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload (md5)'); + +$thex = sprintf("%08x", time - 1800); +$m = md5_hex($secret.$f.$thex); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 410 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - gone (timeout) (md5)'); + +$t->{REQUEST} = ( <<EOF +GET /sec$f HTTP/1.0 +Host: vvv.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - direct access (md5)'); + +$f = "/noexists"; +$thex = sprintf("%08x", time); +$m = md5_hex($secret.$f.$thex); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - timeout (md5)'); + + +if (!$tf->has_crypto()) { + + for (1..4) { ok(1, "secdownload (hmac-sha1) (skipped) - (missing SSL support)"); } + for (1..5) { ok(1, "secdownload (hmac-sha256) (skipped) - (missing SSL support)"); } + +} +else { + +## HMAC-SHA1 +$f = "/index.html"; +$thex = sprintf("%08x", time); +$m = encode_base64url(hmac_sha1("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha1.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload (hmac-sha1)'); + +$thex = sprintf("%08x", time - 1800); +$m = encode_base64url(hmac_sha1("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha1.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 410 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - gone (timeout) (hmac-sha1)'); + +$t->{REQUEST} = ( <<EOF +GET /sec$f HTTP/1.0 +Host: vvv-sha1.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - direct access (hmac-sha1)'); + + +$f = "/noexists"; +$thex = sprintf("%08x", time); +$m = encode_base64url(hmac_sha1("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha1.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - timeout (hmac-sha1)'); + +## HMAC-SHA256 +$f = "/index.html"; +$thex = sprintf("%08x", time); +$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha256.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload (hmac-sha256)'); + +## HMAC-SHA256 +$f = "/index.html?qs=1"; +$thex = sprintf("%08x", time); +$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha256.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload (hmac-sha256) with hash-querystr'); + +$thex = sprintf("%08x", time - 1800); +$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha256.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 410 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - gone (timeout) (hmac-sha256)'); + +$t->{REQUEST} = ( <<EOF +GET /sec$f HTTP/1.0 +Host: vvv-sha256.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - direct access (hmac-sha256)'); + + +$f = "/noexists"; +$thex = sprintf("%08x", time); +$m = encode_base64url(hmac_sha256("/$thex$f", $secret)); + +$t->{REQUEST} = ( <<EOF +GET /sec/$m/$thex$f HTTP/1.0 +Host: vvv-sha256.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; + +ok($tf->handle_http($t) == 0, 'secdownload - timeout (hmac-sha256)'); + +} # SKIP if lighttpd built without crypto algorithms (e.g. without openssl) + + +## mod_setenv + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=TRAC_ENV HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'tracenv' } ]; +ok($tf->handle_http($t) == 0, 'query first setenv'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=SETENV HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'setenv' } ]; +ok($tf->handle_http($t) == 0, 'query second setenv'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=NEWENV HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'newenv' } ]; +ok($tf->handle_http($t) == 0, 'query set-environment'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=HTTP_FOO HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'foo' } ]; +ok($tf->handle_http($t) == 0, 'query add-request-header'); + +$t->{REQUEST} = ( <<EOF +GET /cgi.pl?env=HTTP_FOO2 HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'foo2' } ]; +ok($tf->handle_http($t) == 0, 'query set-request-header'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'BAR' => 'foo' } ]; +ok($tf->handle_http($t) == 0, 'query add-response-header'); + +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +Host: www.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'BAR2' => 'bar2' } ]; +ok($tf->handle_http($t) == 0, 'query set-response-header'); + + +## mod_ssi + +$t->{REQUEST} = ( <<EOF +GET /ssi.shtml HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "/ssi.shtml\n" } ]; +ok($tf->handle_http($t) == 0, 'ssi - echo '); + + +## bug #280 +$t->{REQUEST} = ( <<EOF +GET /exec-date.shtml HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "2\n\n" } ]; +ok($tf->handle_http($t) == 0, 'ssi - echo '); + + +$t->{REQUEST} = ( <<EOF +GET /ssi-include.shtml HTTP/1.0 +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => "/ssi-include.shtml\n/ssi-include.shtml\n/ssi-include.shtml\nssi-include\n\nssi-include\n\n" } ]; +ok($tf->handle_http($t) == 0, 'ssi - include'); + + +ok($tf->stop_proc == 0, "Stopping lighttpd"); diff --git a/tests/scgi-responder.conf b/tests/scgi-responder.conf index 0fe5181d..b1368d7e 100644 --- a/tests/scgi-responder.conf +++ b/tests/scgi-responder.conf @@ -7,7 +7,6 @@ server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" server.name = "www.example.org" -server.tag = "Apache 1.3.29" server.compat-module-load = "disable" server.modules = ( diff --git a/tests/symlink.t b/tests/symlink.t deleted file mode 100755 index 9b275bd7..00000000 --- a/tests/symlink.t +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env perl -BEGIN { - # add current source dir to the include-path - # we need this for make distcheck - (my $srcdir = $0) =~ s,/[^/]+$,/,; - unshift @INC, $srcdir; -} - -use strict; -use IO::Socket; -use Test::More tests => 10; -use LightyTest; - -my $tf = LightyTest->new(); -my $t; -my $docroot = $tf->{'TESTDIR'}."/tmp/lighttpd/servers/www.example.org/pages"; - -sub init_testbed { - return 0 unless eval { symlink("",""); 1 }; - my $f = "$docroot/index.html"; - my $l = "$docroot/index.xhtml"; - my $rc = undef; - unless (-l $l) { - return 0 unless symlink($f,$l); - }; - $f = "$docroot/expire"; - $l = "$docroot/symlinked"; - $rc = undef; - unless (-l $l) { - return 0 unless symlink($f,$l); - } - return 1; -}; - -SKIP: { - skip "perl does not support symlinking or setting up the symlinks failed.", 10 unless init_testbed; - ok($tf->start_proc == 0, "Starting lighttpd") or die(); - -# allow case -# simple file - $t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: symlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - ok($tf->handle_http($t) == 0, 'allow: simple file'); - -# symlinked file - $t->{REQUEST} = ( <<EOF -GET /index.xhtml HTTP/1.0 -Host: symlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - ok($tf->handle_http($t) == 0, 'allow: symlinked file'); - -# directly symlinked dir - $t->{REQUEST} = ( <<EOF -GET /symlinked/ HTTP/1.0 -Host: symlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - ok($tf->handle_http($t) == 0, 'allow: directly symlinked dir'); - -# symlinked dir in path - $t->{REQUEST} = ( <<EOF -GET /symlinked/access.txt HTTP/1.0 -Host: symlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - ok($tf->handle_http($t) == 0, 'allow: symlinked dir in path'); - -# deny case -# simple file - $t->{REQUEST} = ( <<EOF -GET /index.html HTTP/1.0 -Host: nosymlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; - ok($tf->handle_http($t) == 0, 'deny: simple file'); - -# symlinked file - $t->{REQUEST} = ( <<EOF -GET /index.xhtml HTTP/1.0 -Host: nosymlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; - ok($tf->handle_http($t) == 0, 'deny: symlinked file'); - -# directly symlinked dir - $t->{REQUEST} = ( <<EOF -GET /symlinked/ HTTP/1.0 -Host: nosymlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; - ok($tf->handle_http($t) == 0, 'deny: directly symlinked dir'); - -# symlinked dir in path - $t->{REQUEST} = ( <<EOF -GET /symlinked/access.txt HTTP/1.0 -Host: nosymlink.example.org -EOF - ); - $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; - ok($tf->handle_http($t) == 0, 'deny: symlinked dir in path'); - -# cleanup - ok($tf->stop_proc == 0, "Stopping lighttpd"); -}; diff --git a/tests/var-include.conf b/tests/var-include.conf index da23167f..e300e8e2 100644 --- a/tests/var-include.conf +++ b/tests/var-include.conf @@ -6,7 +6,6 @@ server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.o server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log" server.name = "www.example.org" -server.tag = "Apache 1.3.29" server.compat-module-load = "disable" server.modules = ( |