diff options
Diffstat (limited to '')
1382 files changed, 58470 insertions, 0 deletions
diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes new file mode 100644 index 0000000..adf4530 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes @@ -0,0 +1,21 @@ +=head1 NAME + +Changes - Apache::TestMe changes logfile + +=head1 Changes + +=over 4 + +=item 0.01 + +new test basic/vhost.t which introduces a vhost entry in .pm. also +added a dummy vhost entry in t/conf/extra.conf.in, the setup needed by +t/minmaxclients.t from Apache-TestItSelf [Stas] + +write a basic mod_perl test: basic/hello.t [Stas] + +starting the config test suite used by Apache::TestItSelf [Stas] + +=back + +=cut diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL new file mode 100644 index 0000000..cd2ef90 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL @@ -0,0 +1,221 @@ +use 5.005; + +use lib qw(../../lib); # Apache-Test/lib + +use Apache::TestMM qw(test clean); +use Apache::TestMM (); +use Apache::TestReport; + +use ExtUtils::MakeMaker (); + +my $mp_gen = satisfy_mp_generation(); +warn "Goind to build against mod_perl/$mod_perl::VERSION Perl/$]\n"; + +Apache::TestMM::filter_args(); + +my @scripts = qw(t/TEST); +for (@scripts) { + Apache::TestMM::generate_script($_); +} +Apache::TestReport->generate_script; + +my @clean_files = (@scripts, qw(t/REPORT)); + + +my %common_opts = ( + NAME => 'Apache-TestMe', + VERSION => '0.01', + clean => { + FILES => "@clean_files", + }, +); + +if ($mp_gen == 1) { + require ExtUtils::MakeMaker; + ExtUtils::MakeMaker::WriteMakefile( + %common_opts, + ); + +} +else { + require ModPerl::MM; + ModPerl::MM::WriteMakefile( + %common_opts, + ); +} +# If a specific generation was passed as an argument, +# if satisfied +# return the same generation +# else +# die +# else @ARGV and %ENV will be checked for specific orders +# if the specification will be found +# if satisfied +# return the specified generation +# else +# die +# else if any mp generation is found +# return it +# else +# die + +sub satisfy_mp_generation { + my $wanted = shift || wanted_mp_generation(); + + unless ($wanted == 1 || $wanted == 2) { + die "don't know anything about mod_perl generation: $wanted\n" . + "currently supporting only generations 1 and 2"; + } + + my $selected = 0; + + if ($wanted == 1) { + require_mod_perl(); + if ($mod_perl::VERSION >= 1.99) { + # so we don't pick 2.0 version if 1.0 is wanted + die "You don't seem to have mod_perl 1.0 installed"; + } + $selected = 1; + } + elsif ($wanted == 2) { + #warn "Looking for mod_perl 2.0"; + require_mod_perl2(); + if ($mod_perl::VERSION < 1.99) { + die "You don't seem to have mod_perl 2.0 installed"; + } + $selected = 2; + } + else { + $selected = eval { require_mod_perl2() or require_mod_perl() }; + warn "Using $mod_perl::VERSION\n"; + } + + return $selected; +} + +sub require_mod_perl { + eval { require mod_perl }; + die "Can't find mod_perl installed\nThe error was: $@" if $@; + 1; +} + +sub require_mod_perl2 { + eval { require mod_perl2 }; + die "Can't find mod_perl installed\nThe error was: $@" if $@; + 2; +} + + +# the function looks at %ENV and Makefile.PL option to figure out +# whether a specific mod_perl generation was requested. +# It uses the following logic: +# via options: +# perl Makefile.PL MOD_PERL=2 +# or via %ENV: +# env MOD_PERL=1 perl Makefile.PL +# +# return value is: +# 1 or 2 if the specification was found (mp 1 and mp 2 respectively) +# 0 otherwise +sub wanted_mp_generation { + + # check if we have a command line specification + # flag: 0: unknown, 1: mp1, 2: mp2 + my $flag = 0; + my @pass; + while (@ARGV) { + my $key = shift @ARGV; + if ($key =~ /^MOD_PERL=(\d)$/) { + $flag = $1; + } + else { + push @pass, $key; + } + } + @ARGV = @pass; + + # check %ENV + my $env = exists $ENV{MOD_PERL} ? $ENV{MOD_PERL} : 0; + + # check for contradicting requirements + if ($env && $flag && $flag != $env) { + die <<EOF; +Can\'t decide which mod_perl version should be used, since you have +supplied contradicting requirements: + enviroment variable MOD_PERL=$env + Makefile.PL option MOD_PERL=$flag +EOF + } + + my $wanted = 0; + $wanted = 2 if $env == 2 || $flag == 2; + $wanted = 1 if $env == 1 || $flag == 1; + + unless ($wanted) { + # if still unknown try to require mod_perl.pm + eval { require mod_perl2 or require mod_perl }; + unless ($@) { + $wanted = $mod_perl::VERSION >= 1.99 ? 2 : 1; + } + } + + return $wanted; +} + + +# the function looks at %ENV and Makefile.PL option to figure out +# whether a specific mod_perl generation was requested. +# It uses the following logic: +# via options: +# perl Makefile.PL MOD_PERL=2 +# or via %ENV: +# env MOD_PERL=1 perl Makefile.PL +# +# return value is: +# 1 or 2 if the specification was found (mp 1 and mp 2 respectively) +# 0 otherwise +sub wanted_mp_generation { + + # check if we have a command line specification + # flag: 0: unknown, 1: mp1, 2: mp2 + my $flag = 0; + my @pass; + while (@ARGV) { + my $key = shift @ARGV; + if ($key =~ /^MOD_PERL=(\d)$/) { + $flag = $1; + } + else { + push @pass, $key; + } + } + @ARGV = @pass; + + # check %ENV + my $env = exists $ENV{MOD_PERL} ? $ENV{MOD_PERL} : 0; + + # check for contradicting requirements + if ($env && $flag && $flag != $env) { + die <<EOF; +Can\'t decide which mod_perl version should be used, since you have +supplied contradicting requirements: + enviroment variable MOD_PERL=$env + Makefile.PL option MOD_PERL=$flag +EOF + } + + my $wanted = 0; + $wanted = 2 if $env == 2 || $flag == 2; + $wanted = 1 if $env == 1 || $flag == 1; + + unless ($wanted) { + # if still unknown try to require mod_perl.pm + eval { require mod_perl2 or require mod_perl }; + unless ($@) { + $wanted = $mod_perl::VERSION >= 1.99 ? 2 : 1; + } + } + + return $wanted; +} + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README new file mode 100644 index 0000000..bc79ea1 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README @@ -0,0 +1,5 @@ +This package contains an Apache-Test test suite used by +Apache-TestItSelf. We use a dedicated test suite, so we can re-create +cases which normally won't fit into the core Apache-Test test suite. +This is the test suite that should be run from Apache-TestTestItSelf +as explained in Apache-TestItSelf/README diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL new file mode 100644 index 0000000..b5d3494 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL @@ -0,0 +1,37 @@ +use strict; + +use FindBin; +# test against the A-T source lib for easier dev +use lib "$FindBin::Bin/../../../lib"; + +use lib qw(lib ../lib); + +use warnings FATAL => 'all'; + +use Apache::TestRunPerl (); + +package MyTest; + +use vars qw(@ISA); +@ISA = qw(Apache::TestRunPerl); + +sub new_test_config { + my $self = shift; + + #$self->{conf_opts}->{authname} = 'gold club'; + + return $self->SUPER::new_test_config; +} + +sub bug_report { + my $self = shift; + + print <<EOI; ++-----------------------------------------------------+ +| To report problems please refer to the SUPPORT file | ++-----------------------------------------------------+ +EOI +} + +MyTest->new->run(@ARGV); + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t new file mode 100644 index 0000000..ced9f86 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t @@ -0,0 +1,20 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 3, have_lwp; + +my $response = GET '/TestBasic__Hello'; + +ok t_cmp $response->code, 200, '/handler returned HTTP_OK'; + +ok t_cmp $response->header('Content-Type'), 'text/plain', + '/handler set proper Content-Type'; + +chomp(my $content = $response->content); + +ok t_cmp $content, 'Hello', '/handler returned proper content'; + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/vhost.t b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/vhost.t new file mode 100644 index 0000000..4b4d315 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/vhost.t @@ -0,0 +1,7 @@ +use Apache::TestUtil; +use Apache::TestRequest 'GET_BODY_ASSERT'; + +my $module = 'TestBasic::Vhost'; +my $url = Apache::TestRequest::module2url($module); +t_debug("connecting to $url"); +print GET_BODY_ASSERT $url; diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/extra.conf.in b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/extra.conf.in new file mode 100644 index 0000000..e16d963 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/extra.conf.in @@ -0,0 +1,16 @@ +# this vhost entry is needed to check that when t/TEST -maxclients 1 +# or similar is called after t/TEST -conf was run, and extra.conf +# includes a vhost entry and httpd.conf includes an autogenerated +# vhost entry from some .pm file, we used to have a collision, since +# extra.conf wasn't reparsed and the same port was getting assigned to +# more than one vhost entry, preventing server startup: +# +#default_ VirtualHost overlap on port 8530, the first has precedence +#(98)Address already in use: make_sock: could not bind to address +#0.0.0.0:8530 no listening sockets available, shutting down +# +# XXX: for now using a dummy vhost entry. later if needed to put a +# real vhost entry in ths file, the dummy one can be removed +# +<VirtualHost foo_bar_tar> +</VirtualHost> diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl new file mode 100755 index 0000000..a9f939a --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl @@ -0,0 +1,2 @@ + +1; diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm new file mode 100644 index 0000000..953df81 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm @@ -0,0 +1,19 @@ +package TestBasic::Hello; + +use Apache2::RequestRec (); +use Apache2::RequestIO (); +use Apache2::Const -compile => qw(OK); + +# XXX: adjust the test that it'll work under mp1 as well + +sub handler { + + my $r = shift; + + $r->content_type('text/plain'); + $r->print('Hello'); + + return Apache2::OK; +} + +1; diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Vhost.pm b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Vhost.pm new file mode 100644 index 0000000..9692b49 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Vhost.pm @@ -0,0 +1,28 @@ +package TestBasic::Vhost; + +use Apache2::Const -compile => qw(OK); +use Apache::Test; + +# XXX: adjust the test that it'll work under mp1 as well + +sub handler { + + my $r = shift; + + plan $r, tests => 1; + + ok 1; + + return Apache2::OK; +} + +1; +__END__ +<NoAutoConfig> +<VirtualHost TestBasic::Vhost> + <Location /TestBasic__Vhost> + SetHandler modperl + PerlResponseHandler TestBasic::Vhost + </Location> +</VirtualHost> +</NoAutoConfig> diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Changes b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Changes new file mode 100644 index 0000000..04f23d7 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Changes @@ -0,0 +1,27 @@ +=head1 NAME + +Changes - Apache::TestItSelf changes logfile + +=head1 Changes + +=over 4 + +=item 0.01 + +Fix Makefile.PL to make sure that MakeMaker won't descend into +Apache-TestMe. NORECURS doesn't work in older MM versions, so use the +DIR attr as a workaround [Stas] + +new test: minmaxclients.t: testing a bug with vhosts reproducable by +t/TEST -conf followed by t/TEST -maxclients 1 [Stas] + +new test: interactive.t: the interactive config [Stas] + +new test: httpd_arg.t: passing -httpd argument to 'perl Makefile.PL' +and to 't/TEST' [Stas] + +starting the config test suite [Stas] + +=back + +=cut diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL new file mode 100644 index 0000000..ef0d9ae --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL @@ -0,0 +1,40 @@ +use 5.005; + +use lib qw(../lib); # Apache-Test/lib +use Apache::Test5005compat; + +use strict; +use warnings; + +use ExtUtils::MakeMaker; + +use Apache::TestMM (); + +Apache::TestMM::generate_script('t/TEST'); + +my @clean_files = + qw(t/TEST + Makefile.old + ); + +my %prereq = ( + # needed to be able to use one perl version to drive the test + # suite, but a different version from the tests themselves + 'Test::Harness' => '2.44', +); + +WriteMakefile( + NAME => 'Apache::TestItSelf', + PREREQ_PM => \%prereq, + VERSION => "0.01", + NORECURS => 1, # don't descend into Apache-TestMe + DIR => [], # NORECURS is broken in older MM + dist => { + COMPRESS => 'gzip -9f', SUFFIX=>'gz', + }, + clean => { + FILES => "@clean_files", + }, +); + + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/README b/debian/perl-framework/Apache-Test/Apache-TestItSelf/README new file mode 100644 index 0000000..dd332f2 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/README @@ -0,0 +1,73 @@ +This test suite tests various Apache-Test setups (i.e. whether the +configuration works correctly), something that can't be tested with +the normal run-time test suite. + +1) first of all move into Apache-TestItSelf + + % chdir Apache-TestItSelf + + + +2) now choose which test suite to run again, to test whether some + changes in A-T break its config, run 2a. But if the config testing + coverage is not complete, try other test suites and then try to + re-create this problem in 2a. + + You will need to adjust config files under sample/ to reflect the + location of your preinstalled httpd and mod_perl files. + + a. Apache-Test config test suite + + % t/TEST -config sample/testitself_conf_apache_test_core.pl + + this runs against the test suite under: + + Apache-Test/Apache-TestItSelf/Apache-TestMe/t + + it's the same as calling: + + % t/TEST -base ~/apache.org/Apache-Test/Apache-TestItSelf/Apache-TestMe \ + -config sample/testitself_conf_apache_test_core.pl + + + + b. Apache-Test + + assuming that Apache-Test is checked out under + ~/apache.org/Apache-Test, the following will run the tests against the + Apache-Test test suite + + % t/TEST -base ~/apache.org/Apache-Test \ + -config sample/testitself_conf_apache_test_core.pl + + + + c. modperl-2.0 + + assuming that modperl-2.0 is checked out under + ~/apache.org/modperl-2.0, the following will run the tests against the + modperl-2.0 test suite + + % t/TEST -base ~/apache.org/modperl-2.0 \ + -config sample/testitself_conf_mp2_core.pl t/httpd_arg.t t/interactive.t + + + + d. 3rd party modules ### + + assuming that Apache-VMonitor-2.0 is checked out under + ~/work/modules/Apache-VMonitor-2.0, the following will run the tests + against the Apache-VMonitor-2.0 test suite. of course any other 3rd + party module should do. + + + % t/TEST -base ~/work/modules/Apache-VMonitor-2.0 \ + -config sample/testitself_conf_mp2_modules.pl + + +----------------------------- + +DEBUGGING: + +env IPCRUNDEBUG=data t/TEST t/interactive.t +(for more options see IPC::Run / IPC::Run3 manpages) diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm b/debian/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm new file mode 100644 index 0000000..736eb6f --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm @@ -0,0 +1,160 @@ +package MyTest::Util; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestConfig; +use Apache::TestTrace; + +use Exporter (); +use IPC::Run3 (); +use Cwd; + +use vars qw(@ISA @EXPORT @EXPORT_OK); +@ISA = qw(Exporter); +@EXPORT = (); +@EXPORT_OK = qw(myrun3 go_in go_out work_dir dump_stds check_eval + test_configs); + +sub myrun3 { + my $cmd = shift; + my $out = ''; + my $err = ''; + + my $ok = IPC::Run3::run3($cmd, \undef, \$out, \$err); + die "IPC::Run3 failed to run $cmd" unless $ok; + + dump_stds($cmd, '', $out, $err) if $?; + + return ($out, $err); +} + +sub go_in { + my $orig_dir = cwd(); + my $dir = $ENV{APACHE_TESTITSELF_BASE_DIR} || ''; + debug "chdir $dir"; + chdir $dir or die "failed to chdir to $dir: $!"; + return $orig_dir; +} + +sub go_out { + my $dir = shift; + debug "chdir $dir"; + chdir $dir or die "failed to chdir to $dir: $!"; +} + +# the base dir from which the A-T tests are supposed to be run +# we might not be there +sub work_dir { $ENV{APACHE_TESTITSELF_BASE_DIR} } + +sub dump_stds { + my($cmd, $in, $out, $err) = @_; + $cmd = 'unknown' unless length $cmd; + $in = '' unless length $in; + $out = '' unless length $out; + $err = '' unless length $err; + + if ($cmd) { + $cmd =~ s/\n$//; + $cmd =~ s/^/# /gm; + print STDERR "\n\n#== CMD ===\n$cmd\n#============="; + } + if ($in) { + $in =~ s/\n$//; + $in =~ s/^/# /gm; + print STDERR "\n### STDIN ###\n$in\n##############\n\n\n"; + } + if ($out) { + $out =~ s/\n$//; + $out =~ s/^/# /gm; + print STDERR "\n### STDOUT ###\n$out\n##############\n\n\n"; + } + if ($err) { + $err =~ s/\n$//; + $err =~ s/^/# /gm; + print STDERR "\n### STDERR ###\n$err\n##############\n\n\n"; + } +} + +# if $@ is set dumps the $out and $err streams and dies +# otherwise resets the $out and $err streams if $reset_std is true +sub check_eval { + my($cmd, $out, $err, $reset_std, $msg) = @_; + $msg ||= "unknown"; + if ($@) { + dump_stds($cmd, '', $out, $err); + die "$@\nError: $msg\n"; + } + # reset the streams in caller + ($_[1], $_[2]) = ("", "") if $reset_std; +} + +# this function returns an array of configs (hashes) coming from +# -config-file command line option +sub test_configs { + my $config_file = $ENV{APACHE_TESTITSELF_CONFIG_FILE} || ''; + + # reset + %Apache::TestItSelf::Config = (); + @Apache::TestItSelf::Configs = (); + + require $config_file; + unless (@Apache::TestItSelf::Configs) { + error "can't find test configs in '$config_file'"; + exit 1; + } + + my %global = %Apache::TestItSelf::Config; + + # merge the global config with instance configs + my @configs = map { { %global, %$_ } } @Apache::TestItSelf::Configs; + + return @configs; +} + + +1; + +__END__ + +=head1 NAME + +MyTest::Util -- helper functions + +=head1 Config files format + +the -config-file command line option specifies which file contains the +configurations to run with. + +META: expand + + %Apache::TestItSelf::Config = ( + perl_exec => "/home/$ENV{USER}/perl/5.8.5-ithread/bin/perl5.8.5", + mp_gen => '2.0', + httpd_gen => '2.0', + httpd_version => 'Apache/2.0.55', + timeout => 200, + makepl_arg => 'MOD_PERL=2 -libmodperl mod_perl-5.8.5-ithread.so', + ); + + my $path = "/home/$ENV{USER}/httpd"; + + @Apache::TestItSelf::Configs = ( + { + apxs_exec => "$path/prefork/bin/apxs", + httpd_exec => "$path/prefork/bin/httpd", + httpd_mpm => "prefork", + test_verbose => 0, + }, + { + apxs_exec => "$path/worker/bin/apxs", + httpd_exec => "$path/worker/bin/httpd", + httpd_mpm => "worker", + test_verbose => 1, + }, + ); + 1; + + +=cut + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_apache_test_core.pl b/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_apache_test_core.pl new file mode 100644 index 0000000..d873eb7 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_apache_test_core.pl @@ -0,0 +1,44 @@ +# This is a config file for testing Apache-Test + +use strict; +use warnings FATAL => 'all'; + +my $base = "/home/$ENV{USER}"; + +my $perl_base = "$base/perl"; +my $perl_ver = "5.8.8-ithread"; +my $PERL = "$perl_base/$perl_ver/bin/perl$perl_ver"; + +my $httpd_base = "$base/httpd"; +my $httpd_gen = '2.0'; +my $httpd_ver = 'Apache/2.2.3'; +my @mpms = (qw(prefork worker)); + +my $mp_gen = 2.0; +my $mod_perl_so = "mod_perl-$perl_ver.so"; + +%Apache::TestItSelf::Config = ( + repos_type => 'apache_test_core', + perl_exec => $PERL, + mp_gen => $mp_gen, + httpd_gen => $httpd_gen, + httpd_version => $httpd_ver, + timeout => 200, + test_verbose => 0, +); + +@Apache::TestItSelf::Configs = (); +foreach my $mpm (@mpms) { + push @Apache::TestItSelf::Configs, + { + apxs_exec => "$httpd_base/$mpm/bin/apxs", + httpd_exec => "$httpd_base/$mpm/bin/httpd", + httpd_conf => "$httpd_base/$mpm/conf/httpd.conf", + httpd_mpm => $mpm, + makepl_arg => "MOD_PERL=2 -libmodperl $httpd_base/$mpm/modules/$mod_perl_so", + }; +} + +1; + + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_mp2_core.pl b/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_mp2_core.pl new file mode 100644 index 0000000..865c33b --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_mp2_core.pl @@ -0,0 +1,43 @@ +# This is a config file for testing modperl 2.0 core + +use strict; +use warnings FATAL => 'all'; + +my $base = "/home/$ENV{USER}"; + +my $perl_base = "$base/perl"; +my $perl_ver = "5.8.8-ithread"; +my $PERL = "$perl_base/$perl_ver/bin/perl$perl_ver"; + +my $httpd_base = "$base/httpd/svn"; +my $httpd_gen = '2.0'; +my $httpd_ver = 'Apache/2.2.3'; +my @mpms = (qw(prefork worker)); + +my $mp_gen = 2.0; +my $mod_perl_so = "mod_perl-$perl_ver.so"; +my $common_makepl_arg = "MP_MAINTAINER=1"; + +%Apache::TestItSelf::Config = ( + repos_type => 'mp2_core', + perl_exec => $PERL, + mp_gen => $mp_gen, + httpd_gen => $httpd_gen, + httpd_version => $httpd_ver,, + timeout => 900, # make test may take a long time + test_verbose => 0, +); + +@Apache::TestItSelf::Configs = (); +foreach my $mpm (@mpms) { + push @Apache::TestItSelf::Configs, + { + apxs_exec => "$httpd_base/$mpm/bin/apxs", + httpd_exec => "$httpd_base/$mpm/bin/httpd", + httpd_conf => "$httpd_base/$mpm/conf/httpd.conf", + httpd_mpm => $mpm, + makepl_arg => "MP_APXS=$httpd_base/$mpm/bin/apxs $common_makepl_arg", + }; +} + +1; diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_mp2_modules.pl b/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_mp2_modules.pl new file mode 100644 index 0000000..07b6fe0 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/sample/testitself_conf_mp2_modules.pl @@ -0,0 +1,43 @@ +# This is a config file for testing modperl 2.0 Apache:: 3rd party modules + +use strict; +use warnings FATAL => 'all'; + +my $base = "/home/$ENV{USER}"; + +my $perl_base = "$base/perl"; +my $perl_ver = "5.8.8-ithread"; +my $PERL = "$perl_base/$perl_ver/bin/perl$perl_ver"; + +my $httpd_base = "$base/httpd/svn"; +my $httpd_gen = '2.0'; +my $httpd_ver = 'Apache/2.2.3'; +my @mpms = (qw(prefork worker)); + +my $mp_gen = 2.0; +my $mod_perl_so = "mod_perl-$perl_ver.so"; + +%Apache::TestItSelf::Config = ( + repos_type => 'mp2_cpan_modules', + perl_exec => $PERL, + mp_gen => $mp_gen, + httpd_gen => $httpd_gen, + httpd_version => $httpd_ver, + timeout => 200, + test_verbose => 0, +); + + +@Apache::TestItSelf::Configs = (); +foreach my $mpm (@mpms) { + push @Apache::TestItSelf::Configs, + { + apxs_exec => "$httpd_base/$mpm/bin/apxs", + httpd_exec => "$httpd_base/$mpm/bin/httpd", + httpd_conf => "$httpd_base/$mpm/conf/httpd.conf", + httpd_mpm => $mpm, + makepl_arg => "MOD_PERL=2 -libmodperl $httpd_base/$mpm/modules/$mod_perl_so", + }; +} + +1; diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL new file mode 100644 index 0000000..8e28ce4 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL @@ -0,0 +1,123 @@ +use strict; + +use lib qw(../../lib ../lib ./lib); + +use strict; +use warnings FATAL => 'all'; + +use Test::Harness; +use FindBin; +use File::Spec::Functions qw(catdir); +use Apache::TestTrace; +use Cwd qw(cwd); + +use Getopt::Long qw(GetOptions); + +my %usage = ( + 'base-dir' => 'which dir to run the tests in (default: Apache-TestMe)', + 'config-file' => 'which config file to use', + 'help' => 'display this message', + 'trace=T' => 'change tracing default to: warning, notice, ' . + 'info, debug, ...', + 'verbose[=1]' => 'verbose output', +); + +my @flag_opts = qw(verbose help); +my @string_opts = qw(config-file base-dir trace); + +my %opts; +# grab from @ARGV only the options that we expect +GetOptions(\%opts, @flag_opts, (map "$_=s", @string_opts)); + +# t/TEST -v -base /home/$ENV{USER}/apache.org/Apache-Test \ +# -config /home/$ENV{USER}/.apache-test/apache_test_config.pm +# + +$Test::Harness::verbose = 1 if $opts{verbose}; + +opt_help() if $opts{help}; +opt_help() unless $opts{'config-file'}; + +if ($opts{'base-dir'}) { + unless (-d $opts{'base-dir'}) { + error "can't find $opts{'base-dir'}"; + opt_help(); + } +} +else { + my $dir = catdir $FindBin::Bin, qw(.. Apache-TestMe); + # get rid of relative paths + die "can't find the default dir $dir" unless -d $dir; + my $from = cwd(); + chdir $dir or die "can't chdir to $dir: $!"; + $dir = cwd(); + chdir $from or die "can't chdir to $from: $!"; + $opts{'base-dir'} = $dir; +} + + +unless (-r $opts{'config-file'}) { + error "can't read $opts{'config-file'}"; + opt_help(); +} + + if ($opts{trace}) { + my %levels = map {$_ => 1} @Apache::TestTrace::Levels; + if (exists $levels{ $opts{trace} }) { + $Apache::TestTrace::Level = $opts{trace}; + # propogate the override for the server-side. + # -trace overrides any previous APACHE_TEST_TRACE_LEVEL settings + $ENV{APACHE_TEST_TRACE_LEVEL} = $opts{trace}; + } + else { + error "unknown trace level: $opts{trace}", + "valid levels are: @Apache::TestTrace::Levels"; + opt_help(); + } + } + +# forward the data to the sub-processes run by Test::Harness +$ENV{APACHE_TESTITSELF_CONFIG_FILE} = $opts{'config-file'}; +$ENV{APACHE_TESTITSELF_BASE_DIR} = $opts{'base-dir'}; + +run_my_tests(); + +sub run_my_tests { + + my $base = "t"; + unless (-d $base) { + # try to move into the top-level directory + chdir ".." or die "Can't chdir: $!"; + } + + my @tests; + if (@ARGV) { + for (@ARGV) { + if (-d $_) { + push @tests, <$_/*.t>; + } else { + $_ .= ".t" unless /\.t$/; + push @tests, $_; + } + } + } else { + chdir $base; + @tests = sort (<*.t>); + chdir ".."; + @tests = map { "$base/$_" } @tests; + } + + runtests @tests; +} + +sub opt_help { + print <<EOM; +usage: TEST [options ...] + where options include: +EOM + + for (sort keys %usage){ + printf " -%-13s %s\n", $_, $usage{$_}; + } + exit; +} diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t new file mode 100644 index 0000000..835b328 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t @@ -0,0 +1,117 @@ +# +# basic testing with -httpd argument passed explicitly (to +# Makefile.PL, to t/TEST, etc.) +# + +# XXX: -apxs should be really the same test but passing -apxs instead +# of -httpd, so consider to just run both in this test + +use strict; +use warnings FATAL => 'all'; + +use Test::More; +use MyTest::Util qw(myrun3 go_in go_out test_configs); +use Apache::TestConfig (); + +my @configs = test_configs(); +my $tests_per_config = 18; +plan tests => $tests_per_config * @configs; + +my $orig_dir = go_in(); + +for my $c (@configs) { + Apache::TestConfig::custom_config_nuke(); + $ENV{APACHE_TEST_NO_STICKY_PREFERENCES} = 1; + makefile_pl_plus_httpd_arg($c); + + # this one will have custom config, but it shouldn't interrupt + # with the explicit one + # XXX: useless at the moment, since the previously stored custom + # config and the explicit config both point to the same config + $ENV{APACHE_TEST_NO_STICKY_PREFERENCES} = 0; + makefile_pl_plus_httpd_arg($c); + + Apache::TestConfig::custom_config_nuke(); + t_TEST_plus_httpd_arg($c); +} + +go_out($orig_dir); + +# 6 tests +# explicit Makefile.PL -httpd argument +sub makefile_pl_plus_httpd_arg { + my $c = shift; + + my($cmd, $out, $err); + + # clean and ignore the results + $cmd = "make clean"; + ($out, $err) = myrun3($cmd); + + my $makepl_arg = $c->{makepl_arg} || ''; + $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg " . + "-httpd $c->{httpd_exec} -httpd_conf $c->{httpd_conf}"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + $cmd = "make"; + ($out, $err) = myrun3($cmd); + is $err, "", $cmd; + + my $test_verbose = $c->{test_verbose} ? "TEST_VERBOSE=1" : ""; + $cmd = "make test $test_verbose"; + ($out, $err) = myrun3($cmd); + like $out, qr/using $c->{httpd_version} \($c->{httpd_mpm} MPM\)/, $cmd; + like $out, qr/All tests successful/, $cmd; + unlike $err, qr/\[ error\]/, $cmd; + + # test that httpd is found in t/REPORT (if exists) + SKIP: { + $cmd = "t/REPORT"; + skip "$cmd doesn't exist", 1 unless -e $cmd; + + ($out, $err) = myrun3($cmd); + like $out, qr/Server version: $c->{httpd_version}/, $cmd; + } +} + +# explicit t/TEST -httpd argument +sub t_TEST_plus_httpd_arg { + my $c = shift; + + my($cmd, $out, $err); + + # clean and ignore the results + $cmd = "make clean"; + ($out, $err) = myrun3($cmd); + + my $makepl_arg = $c->{makepl_arg} || ''; + $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + $cmd = "make"; + ($out, $err) = myrun3($cmd); + is $err, "", $cmd; + + my $test_verbose = $c->{test_verbose} ? "-v " : ""; + $cmd = "t/TEST -httpd $c->{httpd_exec} $test_verbose"; + ($out, $err) = myrun3($cmd); + like $out, + qr/using $c->{httpd_version} \($c->{httpd_mpm} MPM\)/, + $cmd; + like $out, qr/All tests successful/, $cmd; + unlike $err, qr/\[ error\]/, $cmd; + + # test that httpd is found in t/REPORT (if exists) + SKIP: { + $cmd = "t/REPORT"; + skip "$cmd doesn't exist", 1 unless -e $cmd; + + ($out, $err) = myrun3($cmd); + like $out, qr/Server version: $c->{httpd_version}/, $cmd; + } +} + +__END__ + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t new file mode 100644 index 0000000..7afb2a0 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t @@ -0,0 +1,158 @@ +# +# interactive testing (when A-T) can't figure out the configuration +# + +use Test::More; + +use strict; +use warnings FATAL => 'all'; + +use IPC::Run qw(start pump finish timeout); +use Cwd qw(cwd); +use File::Spec::Functions qw(catfile); + +use MyTest::Util qw(myrun3 go_in go_out work_dir check_eval + test_configs); + +use Apache::TestConfig (); +use Apache::TestTrace; + +# in this test we don't want any cached preconfiguration to kick in +# A-T is aware of this env var and won't load neither custom config, nor +# Apache/Build.pm from mod_perl2. +local $ENV{APACHE_TEST_INTERACTIVE_CONFIG_TEST} = 1; + +my @configs = test_configs(); +if ($configs[0]{repos_type} eq 'mp2_core') { + plan skip_all => "modperl2 doesn't run interactive config"; +} +else { + my $tests_per_config = 11; + plan tests => $tests_per_config * @configs + 1; +} + +my $orig_dir = go_in(); + +my $cwd = cwd(); +my $expected_work_dir = work_dir(); +is $cwd, $expected_work_dir, "working in $expected_work_dir"; + +debug "cwd: $cwd"; + +for my $c (@configs) { + + # install the sticky custom config + install($c); + + # interactive config doesn't work with this var on + $ENV{APACHE_TEST_NO_STICKY_PREFERENCES} = 0; + basic($c); +} + +go_out($orig_dir); + +# 4 tests +sub install { + my $c = shift; + + my($cmd, $out, $err); + + $cmd = "make clean"; + ($out, $err) = myrun3($cmd); + # ignore the results + + my $makepl_arg = $c->{makepl_arg} || ''; + $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg " . + "-httpd $c->{httpd_exec} -apxs $c->{apxs_exec}"; + ($out, $err) = myrun3($cmd); + my $makefile = catfile $expected_work_dir, "Makefile"; + is -e $makefile, 1, "generated $makefile"; + unlike $err, qr/\[ error\]/, "checking for errors"; + + $cmd = "make"; + ($out, $err) = myrun3($cmd); + is $err, "", $cmd; + + $cmd = "make install"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; +} + +# 7 tests +sub basic { + my $c = shift; + + my($cmd, $out, $err); + + # clean and ignore the results + $cmd = "make clean"; + ($out, $err) = myrun3($cmd); + + my $makepl_arg = $c->{makepl_arg} || ''; + $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + $cmd = "make"; + ($out, $err) = myrun3($cmd); + is $err, "", $cmd; + + { + my $in; + my $expected = ''; + my @cmd = qw(make test); + push @cmd, "TEST_VERBOSE=1" if $c->{test_verbose}; + $cmd = join " ", @cmd; + + # bypass the -t STDIN checks to still ensure the interactive + # config prompts + $ENV{APACHE_TEST_INTERACTIVE_PROMPT_OK} = 1; + + $in = ''; + $out = ''; + $err = ''; + my $h = start \@cmd, \$in, \$out, \$err, timeout($c->{timeout}); + + # here the expect fails if the interactive config doesn't kick + # in, but for example somehow figures out the needed + # information (httpd/apxs) and runs the test suite normally + $expected = "Please provide a full path to 'httpd' executable"; + eval { $h->pump until $out =~ /$expected/gc }; + my $reset_std = 1; + check_eval($cmd, $out, $err, $reset_std, + "interactive config wasn't invoked"); + + $in .= "$c->{httpd_exec}\n" ; + $expected = "Please provide a full path to .*? 'apxs' executable"; + eval { $h->pump until $out =~ /$expected/gc }; + $reset_std = 1; + check_eval($cmd, $out, $err, $reset_std, + "interactive config had a problem"); + + $in .= "$c->{apxs_exec}\n" ; + eval { $h->finish }; + $reset_std = 0; # needed for later sub-tests + check_eval($cmd, $out, $err, $reset_std, + "failed to finish $cmd"); + like $out, qr/using $c->{httpd_version} \($c->{httpd_mpm} MPM\)/, + "$cmd: using $c->{httpd_version} \($c->{httpd_mpm} MPM"; + like $out, qr/All tests successful/, "$cmd: All tests successful"; + unlike $err, qr/\[ error\]/, "$cmd: no error messages"; + } + + $cmd = "make install"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + # test that httpd is found in t/REPORT (if exists) + SKIP: { + $cmd = "t/REPORT"; + skip "$cmd doesn't exist", 1 unless -e $cmd; + + ($out, $err) = myrun3($cmd); + like $out, qr/Server version: $c->{httpd_version}/, $cmd; + } +} + +__END__ + diff --git a/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/minmaxclients.t b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/minmaxclients.t new file mode 100644 index 0000000..7ba65e0 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Apache-TestItSelf/t/minmaxclients.t @@ -0,0 +1,101 @@ +# +# -minclients / -maxclients argument passed explicitly (to +# Makefile.PL, to t/TEST, etc.) +# + +use strict; +use warnings FATAL => 'all'; + +use Test::More; +use MyTest::Util qw(myrun3 go_in go_out test_configs); +use Apache::TestConfig (); + +my @configs = test_configs(); +my $tests_per_config = 18; +plan tests => $tests_per_config * @configs; + +my $orig_dir = go_in(); + +# min/maxclients of 10 should work for pretty much any test suite, so +# for now hardcoded the number in this test +my $clients = 10; +for my $c (@configs) { + for my $opt_name (qw(minclients maxclients)) { + my $opt = "-$opt_name $clients"; + makefile_pl_plus_opt($c, $opt); + t_TEST_plus_opt($c, $opt); + } +} + +go_out($orig_dir); + +# 4 sub tests +# explicit Makefile.PL -(mix|max)clients +sub makefile_pl_plus_opt { + my $c = shift; + my $opt = shift; + + my($cmd, $out, $err); + + # clean and ignore the results + $cmd = "make clean"; + ($out, $err) = myrun3($cmd); + + my $makepl_arg = $c->{makepl_arg} || ''; + $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg $opt " . + "-httpd $c->{httpd_exec} -httpd_conf $c->{httpd_conf}"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + $cmd = "make"; + ($out, $err) = myrun3($cmd); + is $err, "", $cmd; + + my $test_verbose = $c->{test_verbose} ? "TEST_VERBOSE=1" : ""; + $cmd = "make test $test_verbose"; + ($out, $err) = myrun3($cmd); + like $out, qr/All tests successful/, $cmd; + unlike $err, qr/\[ error\]/, $cmd; +} + +# 5 tests +# explicit t/TEST -(mix|max)clients +sub t_TEST_plus_opt { + my $c = shift; + my $opt = shift; + + my($cmd, $out, $err); + + # clean and ignore the results + $cmd = "make clean"; + ($out, $err) = myrun3($cmd); + + my $makepl_arg = $c->{makepl_arg} || ''; + $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + $cmd = "make"; + ($out, $err) = myrun3($cmd); + is $err, "", $cmd; + + # the bug was: + # t/TEST -conf + # t/TEST -maxclients 1 + #default_ VirtualHost overlap on port 8530, the first has precedence + #(98)Address already in use: make_sock: could not bind to address + #0.0.0.0:8530 no listening sockets available, shutting down + + my $test_verbose = $c->{test_verbose} ? "-v " : ""; + $cmd = "t/TEST -httpd $c->{httpd_exec} $test_verbose -conf"; + ($out, $err) = myrun3($cmd); + unlike $err, qr/\[ error\]/, $cmd; + + $cmd = "t/TEST -httpd $c->{httpd_exec} $test_verbose $opt"; + ($out, $err) = myrun3($cmd); + like $out, qr/All tests successful/, $cmd; + unlike $err, qr/\[ error\]/, $cmd; +} + +__END__ + diff --git a/debian/perl-framework/Apache-Test/CONTRIBUTORS b/debian/perl-framework/Apache-Test/CONTRIBUTORS new file mode 100644 index 0000000..e281052 --- /dev/null +++ b/debian/perl-framework/Apache-Test/CONTRIBUTORS @@ -0,0 +1,26 @@ +Apache-Test was originally developed by: + + Doug MacEachern <dougm@cpan.org> + +Now maintained by: + + Fred Moyer <fred@redhotpenguin.com> + Philip M. Gollucci <pgollucci@p6m7g8.com> + +with contributions from the following helpful people +(in alphabetical order): + + Alessandro Forghieri <Alessandro.Forghieri@think3.com> + David Wheeler <david@kineticode.com> + Gary Benson <gbenson@redhat.com> + Geoffrey Young <geoff@modperlcookbook.org> + Ken Williams <ken@forum.swarthmore.edu> + Randy Kobes <randy@theoryx5.uwinnipeg.ca> + Rick Myers <rik@sumthin.nu> + Stas Bekman <stas@stason.org> + Steve Hay <steve.hay@uk.radan.com> + Steve Piner <stevep@marketview.co.nz> + Tatsuhiko Miyagawa <miyagawa@edge.co.jp> + + + diff --git a/debian/perl-framework/Apache-Test/Changes b/debian/perl-framework/Apache-Test/Changes new file mode 100644 index 0000000..052e335 --- /dev/null +++ b/debian/perl-framework/Apache-Test/Changes @@ -0,0 +1,1244 @@ +=head1 NAME + +Changes - Apache::Test change logfile + +=head1 CHANGES + +=over 3 + +=item 1.42-dev + +=item 1.41 Jul 11 2019 + +Set DefaultStateDir for > 2.5.1 and add -t_state to override. [jorton] + +Inherit config via IncludeOptional as well as Include. [jorton] + +Increase size of MinSpare, MaxSpare and MaxClients to improve httpd test +framework runs with worker and preform MPMs. [rjung] + +Changed the openssl version detection to work with other *SSL libraries. +[icing] + +Switch test framework from using Net::SSL for +raw TLS sockets to IO::Socket::SSL. [rjung] + +Fix mod_ssl tests under OpenSSL 1.1.1 / TLSv1.3. [jorton] + +Add cwd to generated lib path in TEST script since Perl >=5.26 don't +do that any more. [jorton] + +Override loglevel to trace8 if running in 2.4. [covener] + +Allow an empty PREFIX. [sf] + +Add need_min_apache_fix(). [covener] + +=item 1.40 Sep 6 2016 + +Specify licence (Apache 2.0) in META.yml. [Steve Hay, CPAN RT#111359] + +Fix broken POD. [Steve Hay] + +Switch argument order in "openssl gendsa". [rjung] + +Add (limited) checks for *_SAN_*_n and *_DN_Email variables. [kbrand] + +Update key sizes and message digest to what is common in 2015. [kbrand] + +=item 1.39 Apr 21 2015 + +Test scripts can now test if perl has a fork() implementation available by +using the Apache::Test::need_fork() function. [Steve Hay] + +CPAN RT#87620: Add -D APACHE2_4 to identify httpd-2.4. [Michael Schout] + +=item 1.38 Aug 6 2012 + +Fix log_watch.t on Windows, which can't (naturally) delete open files. +[Steve Hay] + +Fix t_filepath_cmp, t_catfile and t_catfile_apache in Apache::TestUtil on +Windows: their use of Win32::GetLongPathName() was broken for non-existent +files. [Steve Hay] + +Remove use of Nullsv as per modperl commit 1362399. [Steve Hay] + +have Apache::TestConfigPerl::configure_inc set up @INC to include +../blib/lib and ../blib/arch if they exist. The bundled Apache::Reload +may fail to load Apache2::Const & co otherwise when testing. +[Torsten Foertsch] + +=item 1.37 January 29, 2012 + +Apache::TestRequest: improve compatibility for SSL requests with LWP 6 and +IO::Socket::SSL, in particular [Kaspar Brand] + +As of httpd revision 1053230 (version 2.3.11) the NameVirtualHost directive +became superfluous and a warning is issued when it is met. So, Apache::Test +now wraps NameVirtualHost directives in <IfVersion> blocks. +[Kaspar Brand] + +Add comments about the source files of auto configurated tests to +the generated httpd.conf and improve indentation a bit. [Torsten Foertsch] + +Run t/TEST tests by default in alphabetical order and +only t/SMOKE tests by default in random order. [Rainer Jung] + +Add t_file_watch_for to Apache::TestUtil [Torsten Foertsch] + +Add $boolean parameter to Apache::TestHandler::ok and Apache::TestHandler::ok1 +Add a few bits of documentation [Torsten Foertsch] + +Apache::TestHandler forgot to require Apache2::RequestRec [Torsten Foertsch] + +=item 1.36 February 2, 2011 + +Skip sok.t unless perlio is enabled [Torsten Foertsch] + +Deprecate t/TEST -times=X in favor of t/SMOKE -times=X. Changes to +TAP::Harness have removed the ability to re-use test object attributes. +Also generate t/SMOKE on build now, instead of requiring the user to build it. +Thanks to Jim Jagielski for the spot on the -times=X issue on t/TEST. +[Fred Moyer] + +More or less cosmetical, prevent repeating "adding source lib" info lines +in the output when testing Apache::Test, SizeLimit and similar +[Torsten Foertsch] + +=item 1.35 January 22, 2011 + +Return value on running tests as root should be 0, not 1. Thanks to Michael Schout for the spot. +[Fred Moyer] + +Add support for RFC2253 DN string format to dn_oneline in Apache::TestSSLCA +[Stefan Fritsch] + +Make Apache::Test::sok() compatible with the -withtestmore option +[Torsten Foertsch] + +Make -withtestmore a per-package option (make it behave sane). +[Torsten Foertsch] + +=item 1.34 December 18, 2010 + +Fix build edge case where rpm based mp sources missing Apache2::Build cause +require failure in Apache-TestConfig. Reported by Ryan Gies. +[Fred Moyer] + +When an explicit shared mod_perl lib is not defined, default to the first +shared module found by find_apache_module(). +[Fred Moyer] + +Fix logic error in TOP_LEVEL constant calculation. Remove Apache::test +compatibility from mod_perl 1.27. +[Fred Moyer] + +Remove the custom config feature, and instead use inline directives, +ENV vars, and look for apxs et al in PATH. +[Fred Moyer] + +Prevent reconfiguration when t/TEST is called with -run-tests only. +(rev 1004278) [Torsten Foertsch] + +Make "t/TEST -ping=block" work when LWP is installed. (rev 1004275) +[Torsten Foertsch] + +Don't attempt to run the test suite as root. The workarounds needed +to facilitate root testing cause large maintenance costs, and return +no tangible benefits. +[Fred Moyer] + +=item 1.33 September 14, 2010 + +Propagate APACHE_TEST_NO_STICKY_PREFERENCES to the Apache environment +for mod_perl configurations (Apache::TestConfigPerl), +http://www.gossamer-threads.com/lists/modperl/dev/101929 +[Torsten Foertsch] + +Provide build/test environment for modules bundled with mod_perl like +Apache::Reload and Apache::SizeLimit +[Torsten Foertsch] + +The CN in server certificates generated by Apache::TestSSLCA will now +match the servername passed to t/TEST. +[Joe Orton] + +Add check for automated testing environment variable before prompting +with EU::MM to quit the test suite. Some automated smoke tests were +failed because the EU::MM prompt was timing out. +[Adam Prime, Fred Moyer] + +https://rt.cpan.org/Public/Bug/Display.html?id=32993 +use TAP::Harness for Apache::TestHarnessPHP +[Mark A. Hershberger] + +https://rt.cpan.org/Public/Bug/Display.html?id=54476 +Fix error where non root user gets test failure with httpd suexec and mod_fcgid +[Peter (Stig) Edwards] + +=item 1.32 April 15, 2010 + +Fix issue with recent feature where lack of libapreq resulted in test failure. +[Philippe M. Chiasson] + +Added t_{start,read,finish}_file_watch to Apache::TestUtil [Torsten Foertsch] + +=item 1.31 February 24, 2010 + +Modify need_cgi so that it looks for cgi.c instead of cgi. This is a fix +for the case insensitive filesystem correction listed below. +[Phillipe M. Chiasson] + +t/next_available_port.t doesn't need mod_cgid, use need_cgi instead +of need_module('mod_cgi.c') +[Philippe M. Chiasson] + +PR: 21554 +Load mod_apreq2.so if it is available +[Derek Price, <derek@ximbiot.com>] + +Add conditional to ignore IfVersion directive if mod_version is not built. +[Adam Prime <adam.prime@utoronto.ca>, Fred Moyer <phred@apache.org>] + +PR: 41239 +t/TEST -ping does not return a valid return code to the calling shell +[ozw1z5rd <alessio.palma@staff.dada.net>] + +Prevent infinite loop when no default apxs or httpd is present and repeated +attempts to run the test suite under an automated harness (such as a cpan +smoke test). Issue reported by CORION and ANDK, PR: 12911 +[Fred Moyer <phred@apache.org>] + +Use need_module('mod_cgi.c') and need_module('mod_cgid.c') in +t/next_available_port.t instead of need_cgi. On case insensitive file +systems such as OS X, need_cgi will fulfill the requirement with cgi.pm, +when mod_cgi.c is the desired requirement. +[Fred Moyer <phred@apache.org>] + +Fix overridden get_basic_credentials test when using NTLM authentication +[Rick Frankel <cpan@rickster.com>] + +Work around a bug introduced in libwww-perl in version +5.820 for httpd's credentials +[Gunnar Wolf <gwolf@gwolf.org>, Niko Tyni <ntyni@debian.org>] + +Make Apache::TestConfig::untaint_path tolerate undefined arguments +[Torsten Foertsch <torsten.foertsch@gmx.net] + +Inherit LoadFile directives from the global httpd.conf +[Torsten Foertsch <torsten.foertsch@gmx.net] + +Don't overwrite php.ini if it already exists +PR: 32994 +[MAHEX <MAHEX@cpan.org>] + +=item 1.30 November 26, 2007 + +Added t_write_test_lib for temporary testing packages +[Fred Moyer <fred@redhotpenguin.com>] + +Fix syntax error in generated PHP files t/conf/*.php.in +[Philippe M. Chiasson] + +Add bwshare.so to the list of modules to not inherit b/c +it rate limits requests to less then that of a test suite. +PR: 25548 +[imacat <imacat@mail.imacat.idv.tw>] + +Add EXTRA_CFLAGS to c-module building if defined in the environment +[Geoffrey Young] + +=item 1.29 November 28, 2006 + +Require a minium of Module::Build 0.18 when using Apache::TestMB. +PR: 19513 +[Philip M. Gollucci] + +Teach Apache::TestClient to encode spaces(' ') in query string of URLs +as %20. This is not a full mapping of ASCII to URL encoding. +If you need this, install LWP -- then Apache-Test will use +LWP -- which does this for you. +[Philip M. Gollucci] + +Allow Apache::TestClient which is used when LWP is not installed +to accept mutiple headers of the same name. +[Philip M. Gollucci] + +Add t_start_error_log_watch() and t_finish_error_log_watch() +to the Apache::TestUtil API which are only exported unpon request. +[Torsten Foertsch <torsten.foertsch@gmx.net>] + +Allow version variants of debuggers to be passed as arguments +to -debug. i.e. -debug=gdb65 for systems with multiple +versions of the same debugger. [Philip M. Gollucci] + +On Win32, the Apache executable is called httpd.exe in Apache/2.2, +so let Apache::TestConfig try to find that if Apache.exe isn't +found [Randy Kobes] + +force reconfiguration if existing configuration was generated +by an older version of Apache-Test [Geoffrey Young] + +the -t_pid_file code resulted in confusing and fatal error message +for people using stale 1.27 configurations. so take steps to make +sure things continue to work. [Geoffrey Young] + + +=item 1.28 - February 22, 2006 + +add need_imagemap() and have_imagemap() to check for mod_imap +or mod_imagemap [ Colm MacCárthaigh ] + +shortcuts like need_cgi() and need_php() no longer spit out +bogus skip messages [Geoffrey Young] + +Adjust Apache::TestConfig::untaint_path() to handle relative paths +that don't start with /. [Stas] + +If perlpath is longer than 62 chars, some shells on certain platforms +won't be able to run the shebang line, so when seeing a long perlpath +use the eval workaround [Mike Smith <mike@mailchannels.com>] + +Location of the pid file is now configurable via the command line +-t_pid_file option [Joe Orton] + +remove the mod_perl.pm entry from %INC after Apache::Test finishes +initializing itself. because both mp1 and mp2 share the entry, +leaving it around means that Apache::Test might prevent later modules +from loading the real mod_perl module they're interested in, leading +to bad things [Geoffrey Young] + +use which("cover") to find the cover utility from Devel::Cover and run +it only if found. [Stas] + +Devel::Cover magic is now fully integrated. no more modperl_extra.pl +or extra.conf.in fiddling - 'make testcover' should be all you need +to do now [Geoffrey Young] + +Implemented a magic @NextAvailablePort@ to be used in config files to +automatically allocate the next available port [Stas] + +Adjust Apache::TestConfig::add_inc to add lib/ in separate call to +lib::->import at the very end of @INC manipulation to ensure it'll be +on top of @INC. For some reason lib has changed to add directories in +a different order than it did before. [Stas] + + + +=item 1.27 - October 20, 2005 + +localize ScriptSock directive to always point to t/logs/cgisock +regardless of inherited and custom mod_cgid settings +[Geoffrey Young] + +Prevent the config file from being overwritten +on platforms such as WIN32 under certain conditions. +[Randy Kobes] + +make sure that the TESTS Makefile.PL parameter is properly +recognized ["Christopher H. Laco" <apache-test chrislaco.com>] + +Add the output of ldd(unix/cygwin) and otool -L (darwin) +for httpd to the mp2bug report script. +[Philip M. Gollucci] + +fall back on using httpd-defined HTTPD_ROOT as the base for +httpd.conf if all other options fail. [Geoffrey Young] + + + +=item 1.26 - July 25, 2005 + +some people have their Apache user/group names include spaces, so fix +the autogenerated httpd.conf to quote the two. [Stas] + +make sure mp2 loading doesn't make it impossible to complete +mp1 runs. [Matt Sergeant, Geoffrey Young] + +add Apache::TestConfigParrot and Apache::TestRunParrot to +support mod_parrot server-side testing [Geoffrey Young] + +update -withtestmore action to properly work with newer versions +of Test::Builder [Geoffrey Young] + + + +=item 1.25 - June 17, 2005 + +provide $Apache::TestUtil::DEBUG_OUTPUT as target for t_debug() +statements, defaulting to STDOUT. this allows for changing +t_debug() to STDERR when using functions like t_write_file() +from within handler() server-side tests. [Geoffrey Young] + +adjust need_module()/have_module() to not try to require a module if +it was explicitly passed with a .c extension. in certain cases this +prevents a fatal error (e.g. trying to call +Apache::Test::have_module('mod_alias.c') from the <Perl> +sections. [Stas] + + + +=item 1.24 - May 20, 2005 + +When adding TypesConfig directives (either inherited from the global +httpd.conf or from the locally generated mime.types) make sure to +enclose it in <IfModule mod_mime.c>..</IfModule>, since mod_mime might +be unavailable. [Stas] + + + +=item 1.23 - May 3, 2005 + +Fix Apache::TestRequest::hostport to return the default host:port +string if $Apache::TestRequest::Module is 'default' or undef [Stas] + +Fix Apache::TestRequest::module2url to allow passing '' as a URI +path. [Stas] + +tweaks to Apache::TestClient to better deal with corrupted responses +when LWP is not available. [Stas] + + + +=item 1.22 - April 14, 2005 + + ******************** IMPORTANT ******************** + this version of Apache-Test does not completely + configure mod_perl for mod_perl versions 1.99_21 or + earlier. Please read the below changes carefully. + *************************************************** + +remove Apache::TestConfig::modperl_2_inc_fixup(). Apache-Test +is no longer Apache2.pm aware - it will not configure mod_perl +support to look in Apache2/ automatically. [joes] + +Add support for mp2's Apache:: -> Apache2:: rename [joes] + + + +=item 1.21 - March 23, 2005 + +fix Apache::TestConfig (was missing 'use lib' before using +lib::import) [William McKee <william@knowmad.com>] + +TestConfigPerl will now configure mod_perl last, giving mod_perl +highest priority throughout the httpd lifecycle. [Geoffrey Young] + +Apache::TestConfig::untaint_path needs to remove empty entries in the +PATH list, since -T considers those tainted too. [Stas] + +add Apache::TestHarnessPHP which allows for running client-side +scripts via php instead of perl. [Geoffrey Young] + + + +=item 1.20 - January 22, 2005 + +instead of trying to match various custom server name variations (each +vendor seems to replace "Apache" in 'httpd -v' with their own name), +just try to match the "/x.y" in "Foo-Apache-Bar/x.y.z" to figure out +the server generation (rev). [Stas] + +extend Apache::TestConfig::which() to search under perl's bin +directory (in the case of local perl install many utils get installed +there, but won't be in PATH). [Stas] + +Apache::TestConfig::inherit_load_module handles .dll modules +(previously was only .so) [Stas] + +Apache::TestConfig::should_skip_module now works with regex +patterns. [Stas] + + + +=item 1.19 - January 5, 2005 + +Test for module.c instead of module.so for IfModule in +find_and_load_module [Chia-Liang Kao <chialiang gmail.com>] + +Apache-Test/META.yml is excluded from mp2 distro to make PAUSE indexer +happy, but then perl Makefile.PL complains about a missing META.yml, +so autogenerate it if it wasn't in the distro [Stas] + + + +=item 1.18 - December 23, 2004 + +fix a bug in A-T config generation, when a vhost entry was in +autogenerated httpd.conf (e.g. coming from .pm file) and another from +extra.conf.in. We used to have a ports collision, since extra.conf +wasn't reparsed and the same port was getting assigned to more than +one vhost entry, preventing server startup: + default_ VirtualHost overlap on port 8530, the first has precedence + (98)Address already in use: make_sock: could not bind to address + 0.0.0.0:8530 no listening sockets available, shutting down +could be reproduced with t/TEST -conf followed by t/TEST -maxclients 1 +in the mp2 test suite (or the new Apache-TestMe test suite, which now +includes a special setup for this bug). [Stas] + +new TestConfig wrapper find_and_load_module [Chia-Liang Kao <chialiang +gmail.com>] + +add Apache-TestItSelf and Apache-TestMe sub-projects. [Stas] + +add various straps to aid the new Apache-TestItSelf sub-project, which +is used to test A-T config options [Stas] + +avoid entering endless loops when interactive config is used, by +restarting the test suite with an explicit selected arguments for +-httpd (and optionally -apxs) [Stas] + +META.yml is now locally maintained. we need to tell PAUSE indexer not +to try to index HTTP::Request::Common and warnings packages, which +happen to be used by A-T [Stas] + + + +=item 1.17 - December 11, 2004 + +Apache::TestHandler: need to load Apache::RequestIO for mp2 for puts() +to work [Stas] + +new Apache::TestConfig wrapper untaint_path() [Randy Kobes] + +fix the config thaw() functionality (when top_dir wasn't in @INC the +saved config won't be loaded and tests will blow) [Stas] + +new wrapper Apache::TestRequest::module2url to simplify handling of +vhosts in the client. ["Christopher H. Laco" <apache-test +chrislaco.com>] + +resolve -T taint issues: [Stas] +- untaint $cmd in Apache::TestConfig::open_cmd +- fix the tainting of @INC (by untaintinig top_dir variable) + +require Cwd 2.06 or higher (to solve File::Spec::rel2abs problems +under -T). Enforce the modules version requirements for those who +aren't running under CPAN/CPANPLUS shell) [Stas] + +Apache::TestTrace: don't export by default the 'todo' utility's symbol +since it collides with Test::More [Stas] + +Tweak the handling of mp2 source build case in +Apache::TestConfig::httpd_config(), apparently mp2 source build +doesn't always know where httpd/apxs are, so we need to give a better +error message in this particular case. [Stas] + +Add cookie jar tests ["Christopher H. Laco" <apache-test +chrislaco.com>] + +Don't run interactive prompts when STDIN is closed [Stas] + +Add LockFile directive in the autogenerated httpd.conf, which points +to t/logs, to handle the case where LockFile is hardcoded at compile +time to some other directory on the system. [Stas] + + + +=item 1.16 - November 9, 2004 + +launder the require()d custom config filename to make -T happy +[Torsten Förtsch <torsten.foertsch gmx.net>] + +added Apache::TestRunPHP and Apache::TestConfigPHP classes, +which provide a framework for server-side testing via PHP scripts +[Geoffrey Young] + +fix problem with multiple all.t files where only the final +file was being run through the test harness. [Geoffrey Young] + +Documented that redirection does not work with "POST" requests in +Apache::TestRequest unless LWP is installed. [David Wheeler] + +Separated the setting of the undocumented $RedirectOK package +variable by users of Apache::TestRequest from when it is set +internally by passing the "requests_redirectable" parameter to +the user_agent() method. This allows users to override the +behavior set by the user_agent() method without replacing it. +[David Wheeler] + + + +=item 1.15 - October 22, 2004 + +add need_php4() and have_php4() which will return true when mod_php4 +is available. also, tidy up need_php() and have_php() for PHP4 on +Apache 2.0. [Joe Orton] + +add new test_config make target, equivalent to t/TEST -conf, +and make it a prerequisite for the cmodules make target. now +you can 'make cmodules' to build the things in c-modules/ +without running t/TEST -conf first. [Geoffrey Young] + +add -withtestmore import action, which allows Test::More >= 0.49 +to replace Test.pm as the engine for server-side tests +[Geoffrey Young] + +add automatic core dump backtrace generation in t/REPORT if +Devel::GDB is installed [Gozer] + +add 'testcover' make target for running tests with Devel::Cover +[Geoffrey Young] + + + +=item 1.14 - October 12, 2004 + +improve the same_interpreter framework to handle response failures +while trying to init and later find out the same interpreter. [Stas] + +make sure that 'make distclean' cleans all the autogenerated files +[Stas] + +make sure that if -maxclients option is passed on the command line, +minclients will never be bigger than that value [Stas] + +add -one-process runtime argument, which will start the server +in single-server mode (httpd -X in Apache 1.X or +httpd -D ONE_PROCESS in 2.X) [Geoffrey Young] + +In open_cmd, sanitize PATH instead of clearing it [Gozer] + +Allow / \ and \\ path delimiters in SKIP file [Markus Wichitill +<mawic@gmx.de>] + +Added an apxs query cache for improved test performance [Gozer] + +run_tests make target no longer invokes t/TEST -clean, making it +possible to save a few development cycles when a full cleanup is +not required between runs. [Geoffrey Young] + +Apache::TestSmoke imrovements: [Stas] + o the command line option -iterations=N should always be respected + (previously it was internally overriden for order!='random'). + o since IPC::Run3 broke the Ctrl-C handler, we started to loose any + intermediate results, should the run be aborted. So for now, try to + always store those results in the temp file: + smoke-report...$iter.temp + +fix 'require blib' in scripts to also call 'blib->import', required to +have an effect under perl 5.6.x. [Stas] + +don't allow running an explicit 'perl Makefile.PL', when Apache-Test +is checked out into the modperl-2.0 tree, since it then decides that +it's a part of the modperl-2.0 build and will try to use modperl +httpd/apxs arguments which could be unset or wrong [Stas] + +Fix skip test suite functionality in the interactive configuration +phase [Stas] + +s/die/CORE::die/ after exec() to avoid warnings (and therefore +failures) when someone overrides CORE::die when using Apache-Test +[William McKee, Stas] + +Overrode Module::Build's "testcover" action in Apache::TestMB to +prevent the Apache::Test sticky preference files from being included +in the coverage report. [David] + + + + +=item 1.13 - Aug 20, 2004 + +move the custom config code into Apache::TestConfig, split the config +object creation in 2 parts - first not requiring the knowledge of +httpd location, the second requiring one, refactor the custom config +interactive prompting into the second phase, if failed to find +httpd. Reshuffle the code to run first bits not requiring the +knowledge of httpd location. [Stas] + +fix Apache::TestCommonPost::lwp_do to work with LWP 5.800 +($res->content() doesn't allow CODE refs anymore, instead used +content_ref to avoid huge strings copy) [Stas] + +add @PHP_MODULE@ extra.conf.in substitution variable, which selects +mod_php4 or mod_php5 as appropriate. [Geoffrey Young] + +the have() function was removed entirely - use need() instead. +[Geoffrey Young] + +add need() and need_* variant functions (need_module(), need_apache(), +etc) for use specifically with plan() to decide whether or not a test +should run. have_* variants (have_module(), have_apache(), etc) are +now specifically for use outside of plan(), although they can continue +to be used within plan() without fear of current tests breaking. +[Geoffrey Young] + +add need_php() and have_php() which will return true when either +mod_php4 or mod_php5 are available, providing functionality similar to +need_cgi() and have_cgi(). +[Geoffrey Young] + +Add APACHE_TEST_EXTRA_ARGS make variable to all invocations to t/TEST +to allow passing extra arguments from the command line. [Gozer] + +When APACHE_TEST_NO_STICKY_PREFERENCES=1 is used don't even try to +interactively configure the server, as we don't save any config it was +entering an infinite loop. [Stas] + +If a directory t/lib exists from where the tests are run, adjust +@INC so that this directory is added when running the tests, +both within t/TEST and within t/conf/modperl_inc.pl. +This allows inclusion of modules specific to the tests that +aren't intended to be installed. [Stas, Randy] + +make a special case for threaded mpm configuration, to ensure that +unless maxclients was specified, MaxClients will be exactly twice +bigger than ThreadsPerChild (minclients), since if we don't do that, +Apache will reduce MaxClients to the same value as +ThreadsPerChild. [Stas] + +Renamed generate_test_script() to generate_script() in Apache::TestMB +to match the naming convention used in Apache::TestMM and elsewhere. +[David] + +Apache::TestMB now only prints the "Generating test running script" +message if verbosity is enabled (e.g., by passing --verbose when +executing Build.PL). [David] + +Fixed the "requests_redirectable" parameter to +Apache::TestRequest::user_agent() so that it works as docmented when +passed a negative value. [Boris Zentner] + +Documented support for passing an array reference to the +"requests_redirectable" parameter to Apache::TestRequest::user_agent() +to be passed to LWP::UserAgent if LWP ist installed. [David] + + +=item 1.12 - June 28, 2004 + +Force projects that use Apache::TestReportPerl to implement +report_to() if they use t/REPORT in their projects. [Stas] + +Add redirect tests [David Wheeler <david@kineticode.com>] + +add -no-httpd runtime option to allow tests to run without configuring, +starting, or stopping Apache. this essentially provides a direct +Test::Harness interface through t/TEST, useful for running single tests +that do not depend on Apache. [Geoffrey Young] + +Add support for Module::Build, with a new module: Apache::TestMB (a +"clone" of Apache::TestMM for ExtUtils::MakeMaker). [David Wheeler +<david@kineticode.com>] + +switch the order of arguments in t_cmp() and t_is_equal() so that +the order matches Test::More::is() and other Test::More functions. +the new call is: t_cmp($received, $expected, $comment); support +for $expected as the first argument marked as deprecated and will +be removed in the course of the next few release cycles. +[Geoffrey Young] + +add skip_reason() to Apache::Test, which provides a mechanism for +user-specified skip messages [Geoffrey Young] + +Tweak Apache::TestRun to support test filenames starting with +/(.\\)?t\\/ prefixes, windows style (needed for t/SMOKE) [Steve Hay] + + + +=item 1.11 - May 21, 2004 + +if we fail to match the Apache revision (which is OK at the early +stages, like 'perl Makefile.PL', default to a non-existing revision +0. But provide no more misleading defaults (used to default to +revision 2 and then looking for mod_perl2). [Stas] + +Improve the regex to match the Apache revision out of 'httpd -v' +[Michael A Nachbaur <mike@nachbaur.com>] + +-minclients is now what -maxclients used to be, -maxclients is now +really what it says it is [Stas] + +Fix Apache::TestRequest::lwp_as_string to work with LWP 5.79 [Stas] + + + + +=item 1.10 - April 18, 2004 + +Quote and escape the executables in the shell calls [Ken Coar, Stas] + +Quote and escape filtered args received during 'perl Makefile.PL' +[Geoffrey Young, Ken Coar] + +add :withtestmore import tag to Apache::Test, which will export +all standard Apache::Test symbols except those that collide with +Test::More. [Geoffrey Young] + +Use function prototypes in Apache::TestUtil functions t_cmp() and +t_is_equal() to handle the case when an argument to the function, is a +function call itself which may return undef (previously had to +explicitly force a scalar context to get the undef value). The idea +was borrowed from Test::More. [Stas] + +Fixed a Windows-only segment which would result in a +'use of uninitialised value' error if a hash being traversed +had an entry with a key but an undefined value. [Ken] + +Support continuous configuration line when parsing the inherited +configuration file [Stas] + +Since some of the inherited from the global httpd.conf modules require +mod_perl to be loaded first, arrange for that to happen. [Stas] + +Don't try to set ulimit unlimited for coredumps on Solaris, unless run +as root [Rob Kinyon <Rob.Kinyon@progressive-medical.com>] + +Added '-httpd_conf_extra <filename>' configuration option to +allow a file of server config directives to be inherited +in addition to the server's own httpd.conf file (or the one +specified by -httpd_conf). [Ken and Stas] + +Generated Listen directive now listen on 0.0.0.0 to force using +IPv4 addresses on IPv6 systems until LWP supports IPv6. [Gozer] + +improved docs [David Wheeler <david@kineticode.com>] + +Add a virtual method Apache::TestRun::pre_configure, and fix the +documentation to say that subclasses must not forget to run the +superclass' method. [Stas] + +Apache::TestRunPerl now performs an early check whether it can load +the right mod_perl environment. [William McKee <william@knowmad.com>, +Stas] + +$ENV{APACHE_TEST_NO_STICKY_PREFERENCES}, if true, will both suppress +generation of persistent preferences and ignore any that already exist. +[Geoffrey Young] + +make the project's test suite relocatable, handling the case where +after Apache-Test configuration was created and not cleaned up before +the directory was moved. This is especially important for those cases +where users try to run 'make test' as root from /root, A-T tells them +that they can't do that (because of the perms) and suggests to try +again, afer moving the whole project under /tmp or similar. [Stas] + +When running as 'root' make the client side drop the root permissions +and run with the same permissions as the server side +(e.g. nobody). This is needed in case the client side creates any +files after the initial check (during server side startup and beyond), +so that the server side could read/write them. [Stas] + +t_server_log_error_is_expected t_server_log_warn_is_expected +t_client_log_error_is_expected t_client_log_warn_is_expected +now support an optional argument, suggesting how many entries +to expect [Stas] + + + +=item 1.09 - March 8, 2004 + +remove the dependency on APR::UUID (i.e. mod_perl 2.0) in the +same_interpreter framework (use plain time/rand/$$ concatenation) +[Stas] + +Updated to the new Apache License Version 2.0 [Gozer] + +handle cases on Win32 when supplied paths have spaces in their +names [Stas] + +c-modules build errors are no longer ignored [Stas] + +change -DAPACHE1 (and like defines) to -D APACHE1 to fix Win32 +compatibility issues [Steve Hay] + +fix the custom config use for Apache-Test's own upgrades [Stas] + + + +=item 1.08 - February 24, 2004 + +Instead of hard-coding listen directive to 127.0.0.1, use the server +name. [Gozer] + +added -defines configuration option, providing a way to pass additional +-D names to the server for use in <IfDefine> blocks. [Geoffrey Young] + +Make it possible to run TEST (or another driving script) from any path +(e.g. t/TEST, ./TEST, /full/path/to/t/TEST) [Stas] + +If at least one *conf*.in files is modified since the last +configuration, make sure to regenerate them all, so the right ports +will be assigned. [Stas] + +Make sure that Apache-Test modules are installed into INSTALLSITEARCH +during a standalone build. Because EU::MM does so when A-T is bundled +with mp2, and we want to avoid having A-T installed in two different +places under @INC. [Stas] + +HTTP/0.9 responses no longer croak, provided $ENV{APACHE_TEST_HTTP_09_OK} +is true. [Geoffrey Young] + +Hard-code listen directive to 127.0.0.1, solving problems for people +with IPv4 & IPv6 address until a better solution is found. [Gozer] + +prefix Apache::TestTrace (non-colour mode) messages with the loglevel, +similar to what Apache does. [Stas] + +Instrument A-T with an optional successful (shell-wise) abort of the +test suite, by asking the user whether they want to continue w/o +completing the test suite. Use it in places where we know that the +test suite will certaionly fail (e.g. running from /root as 'root', or +not providing httpd/apxs locations). [Stas] + +In order to make Apache-Test compatible with the rest of Perl testing +frameworks, we no longer chdir into t/, but run from the root of the +project (where t/ resides). A test needing to know where it's running +from (e.g. to read/write files/dirs on the filesystem), should do that +relative to the serverroot, documentroot and other server +configuration variables, available via +Apache::Test::vars('serverroot'), Apache::Test::vars('documentroot'), +etc. [Stas] + +Apache::Test::vars() can now query for config arguments [Stas] + +generate t/conf if it does not already exist, which +it may not if the tests are entirely autoconfigured. +[Geoffrey Young] + +Special to Apache-Test environment variables: +APXS APACHE APACHE_GROUP APACHE_USER APACHE_PORT +are now moved to: +APACHE_TEST_APXS APACHE_TEST_HTTPD APACHE_TEST_GROUP +APACHE_TEST_USER APACHE_TEST_PORT +respectively, for consistency with other APACHE_TEST_ env vars and in +order not to interfere with other projects that may use the same env +vars. [Stas] + +if $self->{reconfigure} is true, make sure to perform a complete +reconfiguration, to solve the bug where conf.in files weren't reparsed +and vhost hostport info was getting lost on subsequent runs when +APACHE env var was set (one of the cases when $self->{reconfigure} is +true). [Stas] + +handle "Include conf/*conf" cases when inheriting httpd.conf in a +cleaner way, don't complain that "*conf" doesn't exist, since it's a +glob pattern. Instead check try to resolve the base directory. [Stas] + +import the Apache::TestMM clean target in Makefile.PL so 'make clean' +will call t/TEST -clean [Stas] + +fix have_apache_version(), have_min_apache_version(), and +have_min_module_version() to use proper numeric version strings +in comparisons. thanks to Rafael Garcia-Suarez for the spot. +[Geoffrey Young] + +fix Apache::TestConfig::which to check that the found file is a plain +file [Stas] + +implementing custom interactive and non-interactive (with the -save +option) reusable configuration for -httpd, -apxs, -user, -group, and +-port [Randy Kobes, Stas] + + + +=item 1.07 - Decemeber 22, 2003 + +allow conditional C module compilation on a more granular level. +#define HTTPD_TEST_REQUIRE_APACHE 2.0.49 is now recognized. +[Geoffrey Young] + +Another attempt at providing a test function that verifies whether +Apache when switching from 'root' to 'nobody' or another user will be +able to access and create files under the t/ directory. This time +using perl's vars $(, $< since POSIX equivalents seem to be broken on +some systems. Also using a better test that actually tries to +write/read/execute in the path under test. [Stas] + +Cleanly exit (and complain) if the default hostname resolution has +failed (usually due to a missing localhost entry in /etc/hosts) [Stas] + +Fix Apache::TestConfigParse to handle quoted Include arguments [Stas] + +Fix Apache::TestServer::wait_till_is_up not to bail out if the server +takes time to start and LWP is not available. [Stas] + +Fix Apache::TestConfigParse to handle glob includes, like Include +conf/*.conf on RedHat [Philippe M. Chiasson] + +Fix Apache::TestConfig::add_config not to append " " at the end of the +config lines. This was a problem with config sections imported from +.pm files, the appended "" made it impossible to have multi-line +directives using \ [Stas] + +Fix a bug in '-port select' which was incorrectly using the same port +twice [Stas] + +added bugreport and file argument options to +Apache::TestRun::generate_script() [Geoffrey Young] + + + +=item 1.06 - November 10, 2003 + +added -startup_timeout and $ENV{APACHE_TEST_STARTUP_TIMEOUT} as places +to specify the maximum number of seconds to wait for the test +server to start. the default is still 60 seconds. [Geoffrey Young] + +use apxs PREFIX to resolve relative httpd.conf directives +ServerRoot is not present [Mike Cramer] + +add support for a new subclass method 'bug_report', which if provided +will be called when 'make test' fails. we use it in mod_perl to print +the pointers on how to proceed when the failure occurs. [Stas] + +sudo and su -u aren't portable, therefore use a simple setuid/setguid +perl program instead, to check whether the root directory of the test +suite is rwx by the user/group apache is going to run under (when +running 'make test' as root). [Stas] + + + +=item 1.05 - October 23, 2003 + +core scanning changes [Stas] +- speedup by not chdir'ing into subdirs +- an optional scanning of only t/ dir (used by TestSmoke) +- don't scan on win32, since it has no core files + +in the autogenerated t/conf/modperl_inc.pl don't add the project/lib +directory, unless a special env var APACHE_TEST_LIVE_DEV is true. This +is because some projects change things in project/blib and pushing +project/lib on top of @INC, breaks the test suite for them [Stas] + +TestRun was using httpd.pid file to ensure that the server is killed +before starting it, if the file existed. This was a problem on win32 +platforms, where a process scheduler tries to re-use the pids that +were just freed, which may have killed a valid process which is not +even Apache.exe. So we try not to rely on that file, and if the server +wasn't properly stopped and still running, users will learn about +that, since the port will be busy, and Apache will fail to +start. Users have to kill it manually. TestSmoke is no longer using an +explicit kill `cat httpd.pid` to stop Apache, but delegates the +stopping procedure to TestRun [Steve Hay, Randy Kobes] + +use IPC::Run3 in Apache::TestSmoke to run t/TEST commands, +so as t/SMOKE can be used on Win32 [Stas, Steve Hay, Randy Kobes] + +place mod_perl-specific directives in <IfModule> containers +within httpd.conf, allowing the default server to start if +mod_perl isn't present. [Geoffrey Young] + +fix t/request.t to get /index.html, instead of / since not everybody +uses mod_dir [Steve Piner <stevep@marketview.co.nz>] + +when testing whether Apache started as root and running under 'nobody' +or alike, will be able to -r/-w/-x in t/ use 'su' instead of 'sudo', +the latter is not available on all unix platforms. [Vivek Khera +<khera@kcilink.com>] + +in the Apache/test.pm nuke code s/PERLRUN/FULLPERL/ as older MakeMaker +doesn't have the PERLRUN target [Stas] + +Apache 1.3 servers now run in standard prefork mode under +normal operation. single server mode (httpd -X) was replaced +with MaxClients set to 1 by default. [Geoffrey Young] + + + +=item 1.04 - September 29, 2003 + +if the server stops reading from the client before it has sent all its +data, Apache::TestClient (which is used when LWP is not available) +would just die without any error message (5.8.1) because no SIGPIPE +handler was setup and the Broken Pipe error was missed. Replacing +'print $s' with $s->send() solves this problem: Apache::TestClient +will just move on without bailing out. [Stas] + +if env var APACHE_TEST_PRETEND_NO_LWP is true, Apache::Test will +pretend that LWP is not available. useful for testing whether the test +suite will survive on a system which doesn't have libwww-perl +installed. [Stas] + +Apache::TestSmoke provides a new mode: -bug_mode, which runs an +equivalent of plain 't/TEST' but generates a lot of useful debug +information, in addition to matching the core files to the tests that +caused them. [Stas] + +Apache::TestSmoke now scans for core files, just like Apache::TestRun +does [Stas] + +Allow the creation of name based virtual hosts by supplying +<VirtualHost servername:module> containers in .conf.in$ files. +[André Malo] + +fix Apache::TestSSLCA to generate a separate index.txt file for each +module, as on certain platforms openssl fails to re-use the same +file. [Stas] + +remove the unused example section from t/conf/extra.conf.in, it made +an assumption that mod_auth is available [Stas] + +in the autogenerated t/conf/httpd.conf include mod_alias and mod_mime +loading, in case they were built as a shared object and wasn't loaded +from the system-wide httpd.conf from which Apache::Test inherits the +config. [Stas] + +added have_apache_mpm() function [Geoffrey Young] + +when moving test-specific config directives from __DATA__ to +httpd.conf don't use hash, or the order of arguments is not +preserved. Thanks to perl-5.8.1 for randomizing the hash seed, which +has exposed the bug by breaking the test suite. [Stas] + +when the tests are run in the 'root' mode, check whether the +DocumentRoot and its parent dirs are rwx before the tests are run and +suggest possible workarounds when the tests are doomed to fail, +because of the permission issues. [Stas] + +UPLOAD is now auto-exported, like the rest [David Wheeler +<david@kineticode.com>] + +Change the way the redirect_ok parameter works so that it affects only +_that call_ to the function. Afterward it should revert to the old +value of $RedirectOK. [David Wheeler <david@kineticode.com>] + +Change user_agent() so that the LWP::UserAgent "requests_redirectable" +parameter actually does something useful vis-à-vis $RedirectOK. [David +Wheeler <david@kineticode.com>] + +Apache::TestRequest API documenation [David Wheeler +<david@kineticode.com>] + +Enable TransferLog in the autogenerated httpd.conf only if +mod_log_config is available [Stas] + + + +=item 1.03 - June 19, 2003 + +Instrumented Makefile.PL to unconditionally remove any old +pre-installed occurrences of Apache/test.pm, which has been renamed to +Apache/testold.pm in mod_perl 1.28 to avoid collisions with +Apache/Test.pm on case-insensitive systems. [Stas] + +Apache::TestClient now handles correctly responses with no body and +its response header() method is no longer case-sensitive [Stas] + +add skip helper shortcuts: have_min_perl_version, +have_min_module_version [Stas] + +pass to 'use lib' only 'lib/' dirs that actually exist in +autogenerated t/TEST t/SMOKE and others. [Stas] + +add the ASF LICENSE file to the distro [Stas] + +get rid of Apache::TestTrace's dependency on Apache::TestConfig as it +creates too many circular use() problems. [Stas] + +wrap blib loading in eval block (added to autogenerated files), to +prevent 'make clean' failures. [Stas] + +add two more variants of each of the tracing functions. If the '_mark' +suffix is appended (e.g., 'error_mark') the trace will start with the +filename and the line number the function was called from. If the +'_sub' suffix is appended (e.g., 'error_info') the trace will start +with the name of the subroutine the function was called from. [Stas] + +add support for a new env var APACHE_TEST_TRACE_LEVEL, used to +override the tracing level. It propogates the overriden (either by env +var APACHE_TEST_TRACE_LEVEL or -trace option) value to the +server-side, so we can use Apache::TestTrace in mod_perl handlers, and +be able enable/disable tracing from the commmand line. This way we +don't have to comment out debug prints. [Stas] + + + +=item 1.02 + +not released + + + +=item 1.01 - May 1, 2003 + +improved support for 3rd party modules test configuration setup: +automatically include 'use blib' in autogenerated t/TEST and add 'use +Apache2' in the startup file for mod_perl 2.0. [Stas] + +new configuration option: -libmodperl [path/to/]mod_perl.so (so one +can build several DSO objects, rename them, so several builds can +co-exist under the same LIBEXECDIR and test them all. Mainly useful +for testing 3rd party modules, with different mod_perl DSO builds. [Stas] + +set $Apache::Test5005compat::VERSION because of the bogus warnings +generated by EU::MM::parse_version() when it sees +$NOT_THIS_MODULE::VERSION [Randal L. Schwartz <merlyn@stonehenge.com>] + +a few fixes in Makefile.PL and t/TEST.PL to work with perl-5.005_03 +[Stas] + +perlpods are found either in the 'pods/' or 'pod/' subdirs [Randal +L. Schwartz <merlyn@stonehenge.com>] + +Autoconfigure Alias /getfiles-* only if the corresponding targets +exist [Stas] + + + +=item 1.00 - Apr 28, 2003 + +when inheriting httpd.conf on some platforms SERVER_CONFIG_FILE is an +absolute path, so try to use that if found. [Haroon Rafique +<haroon.rafique@utoronto.ca>] + +new Apache::Test functions: +have_min_apache_version - to require a minimal Apache version. +have_apache_version - to require a specific Apache version. +[Stas] + +Apache::TestUtil API change: +write_perl_script => t_write_perl_script +write_shell_script => t_write_shell_script +chown => t_chown +All 3 functions are now optionally exported [Geoffrey Young]. + +Provide a new request macro _BODY_ASSERT to replace _BODY in cases +where the client part of the test directly prints to the output, in +order to avoid skipped tests instead of reporting the failure of the +server side. Use it in automatically generated tests. [Stas] + +httpd (1.3 && 2) / winFU have problems when the first path's segment +includes ':' (security precaution which breaks the rfc) so we can't +use /TestFoo::bar as path_info in Apache::Tests. Adjusting all tests +to use /TestFoo__bar. [Stas] + +change Apache::TestConfig::filter_args to accept arguments which +aren't only key/value pairs, but also tokens like 'FOO=1' [Stas] + +In autogenerated t/TEST, make sure not to include 'use Apache2' for +the mod_perl 2.0 build itself [Stas] + +avoid starting httpd with 'Group root' when running the test suite +under root [Stas] + +add support for 'make test TEST_VERBOSE=1 "TEST_FILES=foo bar"' [Stas] + +Apache::Test now can run 'make test' under 'root', without permission +problems (e.g. when files need to be written), it'll chown all the +files under t/ to the user chosen to run the server with, before +running the tests and will restore the permissions at the end. [Stas] + +don't inherit loading of the mod_perl object from the system-wide +config, since Apache::TestRunPerl already configures it [Stas] + +Support two new shortcuts for skip functionality: + - have_threads: checks whether both Apache and Perl support threads + - under_construction: to print a consistent/clear skip reason +[Stas] + +Support <NoAutoConfig> </NoAutoConfig> blocks in .pm files, so we can +have a full manual control over generated config sections. These +sections are fully parsed and variables are substituted, including +vhosts. [Stas] + +Implement a more robust autogenerated client .t test in +Apache::TestConfigPerl. Before this fix if the server side returned +500, the test would get skipped, not good. Now it will die a horrible +death. [Stas] + +Before v1.0 most changes were logged in modperl-2.0/Changes (see +mod_perl <= v1.99_08). + +=back diff --git a/debian/perl-framework/Apache-Test/INSTALL b/debian/perl-framework/Apache-Test/INSTALL new file mode 100644 index 0000000..06d0b5b --- /dev/null +++ b/debian/perl-framework/Apache-Test/INSTALL @@ -0,0 +1,19 @@ +to install this module simply follow the canonical procedure +for installing any perl module + + $ tar zxvf Apache-Test-1.XX.tar.gz + $ cd Apache-Test-1.XX + + $ perl Makefile.PL + $ make + $ sudo make install + +if you want to run the tests contained within the distribution +you can point to a suitable Apache distribution via + + $ perl Makefile.PL -httpd /path/to/your/apache/bin/httpd + $ make + $ make test + $ sudo make install + +for further directions, see the README. diff --git a/debian/perl-framework/Apache-Test/LICENSE b/debian/perl-framework/Apache-Test/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/debian/perl-framework/Apache-Test/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/debian/perl-framework/Apache-Test/MANIFEST b/debian/perl-framework/Apache-Test/MANIFEST new file mode 100644 index 0000000..7aaecc5 --- /dev/null +++ b/debian/perl-framework/Apache-Test/MANIFEST @@ -0,0 +1,72 @@ +Changes +CONTRIBUTORS +LICENSE +MANIFEST +META.yml +Makefile.PL +README +INSTALL +SUPPORT +ToDo +lib/Apache/Test.pm +lib/Apache/Test5005compat.pm +lib/Apache/TestBuild.pm +lib/Apache/TestClient.pm +lib/Apache/TestCommon.pm +lib/Apache/TestCommonPost.pm +lib/Apache/TestConfig.pm +lib/Apache/TestConfigC.pm +lib/Apache/TestConfigParse.pm +lib/Apache/TestConfigParrot.pm +lib/Apache/TestConfigPerl.pm +lib/Apache/TestConfigPHP.pm +lib/Apache/TestHandler.pm +lib/Apache/TestHarness.pm +lib/Apache/TestHarnessPHP.pm +lib/Apache/TestMB.pm +lib/Apache/TestMM.pm +lib/Apache/TestPerlDB.pm +lib/Apache/TestReport.pm +lib/Apache/TestReportPerl.pm +lib/Apache/TestRequest.pm +lib/Apache/TestRun.pm +lib/Apache/TestRunParrot.pm +lib/Apache/TestRunPerl.pm +lib/Apache/TestRunPHP.pm +lib/Apache/TestSSLCA.pm +lib/Apache/TestServer.pm +lib/Apache/TestSmoke.pm +lib/Apache/TestSmokePerl.pm +lib/Apache/TestSort.pm +lib/Apache/TestTrace.pm +lib/Apache/TestUtil.pm +lib/Bundle/ApacheTest.pm +t/alltest/01bang.t +t/alltest/all.t +t/alltest2/01bang.t +t/alltest2/all.t +t/bad_coding.t +t/cgi-bin/cookies.pl.PL +t/cgi-bin/next_available_port.pl.PL +t/conf/extra.conf.in +t/conf/modperl_extra.pl.in +t/cookies.t +t/import.t +t/log_watch.t +t/more/01testpm.t +t/more/02testmore.t +t/more/03testpm.t +t/more/04testmore.t +t/more/all.t +t/next_available_port.t +t/ping.t +t/redirect.t +t/request.t +t/response/TestMore/testmorepm.pm +t/response/TestMore/testpm.pm +t/sok.t +t/TEST.PL + + +META.yml Module meta-data (added by MakeMaker) + diff --git a/debian/perl-framework/Apache-Test/META.yml b/debian/perl-framework/Apache-Test/META.yml new file mode 100644 index 0000000..c56e8a9 --- /dev/null +++ b/debian/perl-framework/Apache-Test/META.yml @@ -0,0 +1,20 @@ +name: Apache-Test +version_from: lib/Apache/Test.pm +installdirs: site + +requires: + Cwd: 2.06 + File::Spec: 0.8 + +distribution_type: module + +license: apache_2_0 + +no_index: + package: + - HTTP::Request::Common + - warnings + - TestMore::testmorepm + - TestMore::testpm + directory: + - Apache-TestItSelf diff --git a/debian/perl-framework/Apache-Test/Makefile.PL b/debian/perl-framework/Apache-Test/Makefile.PL new file mode 100644 index 0000000..2cfec1a --- /dev/null +++ b/debian/perl-framework/Apache-Test/Makefile.PL @@ -0,0 +1,208 @@ +use 5.005; + +use lib qw(lib); +use Apache::Test5005compat; + +use strict; +use warnings; + +# was this file invoked directly via perl, or via the top-level +# (mp2) Makefile.PL? if top-level, this env var will be set +use constant TOP_LEVEL => $ENV{MOD_PERL_2_BUILD}; + +if (!TOP_LEVEL) { + # see if we are building from within mp root, add src lib if we are + eval { require File::Spec }; + unless ($@) { + if ( -e File::Spec->catdir('..', 'lib') ) { + + # building A-T from mp subdirectory, use the mp lib + unshift @INC, File::Spec->catdir('..', 'lib'); + } + } +} + +use ExtUtils::MakeMaker; +use Symbol; +use File::Find qw(finddepth); + +use Apache::TestMM qw(test clean); #enable 'make test and make clean' +use Apache::TestRun; +use Apache::TestTrace; +use Apache::TestReport; +use Apache::TestConfig (); +use Apache::TestRunPerl; + +my $VERSION; +set_version(); + +Apache::TestMM::filter_args(); + +my @scripts = qw(t/TEST); + +finddepth(sub { + return if $_ eq 'Apache-TestItSelf'; + return unless /(.*?\.pl)\.PL$/; + push @scripts, "$File::Find::dir/$1"; +}, '.'); + +for (@scripts) { + Apache::TestMM::generate_script($_); +} +Apache::TestReport->generate_script; + +my @clean_files = + qw(.mypacklist + t/TEST + t/REPORT + Makefile.old + ); + +my %prereq = ( + 'File::Spec' => '0.8', + 'Cwd' => '2.06', +); + +# Apache::TestServer uses Win32::Process on Windows. +if ($^O =~ /MSWin32/i) { + $prereq{'Win32::Process'} = '0' +} + +# Apache-Test/META.yml is excluded from mp2 distro to make PAUSE +# indexer happy, but then perl Makefile.PL complains about a missing +# META.yml, so autogenerate it if it wasn't in the distro +my $no_meta = TOP_LEVEL ? 1 : 0; + +WriteMakefile( + NAME => 'Apache::Test', + VERSION => $VERSION, + PREREQ_PM => \%prereq, + NO_META => $no_meta, + dist => { + COMPRESS => 'gzip -9f', SUFFIX => 'gz', + PREOP => 'find $(DISTVNAME) -type d -print|xargs chmod 0755 && ' . + 'find $(DISTVNAME) -type f -print|xargs chmod 0644', + TO_UNIX => 'find $(DISTVNAME) -type f -print|xargs dos2unix' + }, + clean => { + FILES => "@clean_files", + }, +); + +# after CPAN/CPANPLUS had a chance to satisfy the requirements, +# enforce those (for those who run things manually) +check_prereqs(); + +sub check_prereqs { + my %fail = (); + for (sort keys %prereq) { + unless (chk_version($_, $prereq{$_})) { + $fail{$_} = $prereq{$_}; + } + } + if (%fail) { + error "\nThe following Apache-Test dependencies aren't satisfied:", + map { "\t$_: $fail{$_}" } sort keys %fail; + error "Install those from http://search.cpan.org and try again"; + exit 0; + } +} + +sub chk_version { + my($pkg, $wanted) = @_; + + no strict 'refs'; + local $| = 1; + + print "Checking for $pkg..."; + (my $p = $pkg . ".pm") =~ s#::#/#g; + eval { require $p;}; + print("not ok\n$@"), return if $@; + + my $vstr = ${"${pkg}::VERSION"} ? "found v" . ${"${pkg}::VERSION"} + : "not found"; + my $vnum = eval(${"${pkg}::VERSION"}) || 0; + + print $vnum >= $wanted ? "ok\n" : " " . $vstr . "\n"; + + $vnum >= $wanted; +} + +sub set_version { + $VERSION = $Apache::Test::VERSION; + + my $fh = Symbol::gensym(); + open $fh, 'Changes' or die "Can't open Changes: $!"; + while (<$fh>) { + if(/^=item.*-(dev|rc\d+)/) { + $VERSION .= "-$1"; + last; + } + last if /^=item/; + } + close $fh; +} + +sub add_dep { + my($string, $targ, $add) = @_; + $$string =~ s/($targ\s+::)/$1 $add/; +} + +no warnings 'redefine'; +sub MY::postamble { + my $self = shift; + + my $q = ($^O =~ /MSWin32/i ? '"' : "'"); + + my $string = $self->MM::postamble; + + $string .= <<"EOF"; +tag : + svn copy -m $q\$(VERSION_SYM) tag$q https://svn.apache.org/repos/asf/perl/Apache-Test/trunk https://svn.apache.org/repos/asf/perl/Apache-Test/tags/\$(VERSION_SYM) +EOF + + return $string; +} + + + +sub MY::test { + my $self = shift; + + # run tests normally if non root user + return $self->Apache::TestMM::test(@_) if (($> != 0) # root user + or (Apache::TestConfig::WINFU)); # win users + # or win32 + + return <<EOF +test:: +\t\@echo +\t\@echo Apache::Test tests cannot be run as the root user. +\t\@echo Apache cannot spawn child processes as 'root', therefore +\t\@echo the test suite must be run with a non privileged user. +\t\@echo Please build Apache::Test as a non-privileged user to +\t\@echo run the test suite. +\t\@echo +EOF +} + +sub MY::constants { + my $self = shift; + + my $string = $self->MM::constants; + + # mp2 installs this into INSTALLSITEARCH, so in order to avoid + # problems when users forget 'make install UNINST=1', trick MM into + # installing pure perl modules to the sitearch location, when this is + # not installed as a part of mp2 build + if (!$ENV{MOD_PERL_2_BUILD}) { + $string .= <<'EOI'; + +# install into the same location as mod_perl 2.0 +INSTALLSITELIB = $(INSTALLSITEARCH) +DESTINSTALLSITELIB = $(DESTINSTALLSITEARCH) +EOI + } + + $string; +} diff --git a/debian/perl-framework/Apache-Test/README b/debian/perl-framework/Apache-Test/README new file mode 100644 index 0000000..c4d672e --- /dev/null +++ b/debian/perl-framework/Apache-Test/README @@ -0,0 +1,225 @@ +######### +# About # +######### + +Apache::Test is a test toolkit for testing an Apache server with any +configuration. It works with Apache 1.3 and Apache 2.0/2.2/2.4 and any +of its modules, including mod_perl 1.0 and 2.0. It was originally developed +for testing mod_perl 2.0. + +################# +# Documentation # +################# + +For an extensive documentation see the tutorial: + + http://perl.apache.org/docs/general/testing/testing.html + +and the documentation of the specific Apache::Test modules, which can +be read using 'perldoc', for example: + + % perldoc Apache::TestUtil + +and the 'Testing mod_perl 2.0' article: +http://www.perl.com/pub/a/2003/05/22/testing.html + +################### +# Got a question? # +################### + +Post it to the test-dev <at> httpd.apache.org list. The list is +moderated, so unless you are subscribed to it it may take some time +for your post to make it to the list. + +For more information see: http://perl.apache.org/projects/Apache-Test/index.html + +List Archives: +# www.apachelabs.org + +http://www.apachelabs.org/test-dev/ +# marc.theaimsgroup.com + +http://marc.theaimsgroup.com/?l=apache-modperl-test-dev +# Mbox file + +http://perl.apache.org/mail/test-dev/ + +############## +# Cheat List # +############## + +see Makefile.PL for howto enable 'make test' + +see t/TEST as an example test harness + +see t/*.t for example tests + +if the file t/conf/httpd.conf.in exists, it will be used instead of +the default template (in Apache/TestConfig.pm); + +if the file t/conf/extra.conf.in exists, it will be used to generate +t/conf/extra.conf with @variable@ substitutions + +if the file t/conf/extra.conf exists, it will be included by +httpd.conf + +if the file t/conf/modperl_extra.pl exists, it will be included by +httpd.conf as a mod_perl file (PerlRequire) + + + +################## +# Handy examples # +################## + +some examples of what i find handy: +see TEST -help for more options + +test verbosely +% t/TEST -verbose + +start the server +% t/TEST -start + +run just this test (if server is running, will not be re-started) +% t/TEST t/apr/table + +run just the apr tests +% t/TEST t/apr + +run all tests without start/stop of server (e.g. server was started with -d) +% t/TEST -run + +stop the server +% t/TEST -stop + +ping the server to see whether it runs +% t/TEST -ping + +ping the server and wait until the server starts, report waiting time +% t/TEST -ping=block + +reconfigure the server, do not run tests +% t/TEST -configure + +run as user nobody: +% t/TEST -User nobody + +run on a different port: +% t/TEST -Port 8799 + +let the program pick the next available port (useful when running a +few test sessions on parallel) +% t/TEST -Port select + +run on a different server: +% t/TEST -servername example.com + +configure an httpd other than the default (that apxs figures out) +% t/TEST -httpd ~/ap/httpd-2.0/httpd + +configure a DSO mod_perl object other than the default (that stored in +Apache::BuildConfig) +% t/TEST -libmodperl ~/ap/httpd-2.0/modules/mod_perl-5.8.0.so +or one that can be found relative to LIBEXECDIR +% t/TEST -libmodperl mod_perl-5.6.1.so + +switch to another apxs +% t/TEST -apxs ~/ap/httpd-2.0-prefork/bin/apxs + +turn on tracing +% t/TEST -preamble "PerlTrace all" + +GET url +% t/TEST -get /server-info + +HEAD url +% t/TEST -head /server-info + +HEAD (no url defaults to /) +% t/TEST -head + +GET url with authentication credentials +% t/TEST -get /server-info -username dougm -password foo + +POST url (read content from string) +% t/TEST -post /TestApache::post -content 'name=dougm&company=covalent' + +POST url (read content from stdin) +% t/TEST -post /TestApache::post -content - < foo.txt + +POST url (generate a body of data 1024 bytes in length) +% t/TEST -post /TestApache::post -content x1024 + +POST url (only print headers, e.g. useful to just check Content-length) +% t/TEST -post -head /TestApache::post -content x100000 + +GET url (only print headers, e.g. useful to just check Content-length) +% t/TEST -get -head /foo + +start server under gdb +% t/TEST -debug + +start server under strace (outputs to t/logs/strace.log) +% t/TEST -d strace + +run .t test under the perl debugger +% t/TEST -d perl t/modules/access.t + +run .t test under the perl debugger (nonstop mode, output to t/logs/perldb.out) +% t/TEST -d perl=nostop t/modules/access.t + +control how much noise Apache::Test should produce. to print all the +debug messages: +% t/TEST -trace=debug +to print only warnings and higher trace levels: +% t/TEST -trace=warning +the available modes are: + emerg alert crit error warning notice info debug + +turn on -v and LWP trace (1 is the default) mode in Apache::TestRequest +% t/TEST -d lwp t/modules/access.t + +turn on -v and LWP trace mode (level 2) in Apache::TestRequest +% t/TEST -d lwp=2 t/modules/access.t + +run all tests through mod_ssl +% t/TEST -ssl + +run all tests with HTTP/1.1 (keep alive) requests +% t/TEST -http11 -ssl + +run all tests with HTTP/1.1 (keep alive) requests through mod_ssl +% t/TEST -http11 + +run all tests through mod_proxy +% t/TEST -proxy + + + +################## +# Stress testing # +################## + +run all tests 10 times in a random order (the seed is autogenerated +and reported) +% t/SMOKE -times=10 -order=random + +run all tests 10 times in a random order using the seed obtained from +the previous random run (e.g. 2352211): +% t/SMOKE -times=10 -order=2352211 + +repeat all tests 10 times (a, b, c, a, b, c) +% t/SMOKE -times=10 -order=repeat + +When certain tests fail when running with -times option, you want to +find out the minimal sequence of tests that lead to the +failure. Apache::TestSmoke helps to ease this task, simply run: +% t/SMOKE + +which tries various sequences of tests and at the end reports the +shortest sequences found that lead to the same failure. + +for more options do: +% t/SMOKE -help + diff --git a/debian/perl-framework/Apache-Test/RELEASE b/debian/perl-framework/Apache-Test/RELEASE new file mode 100644 index 0000000..4f8e5e8 --- /dev/null +++ b/debian/perl-framework/Apache-Test/RELEASE @@ -0,0 +1,97 @@ +Instructions for Apache-Test Release Manager + +0. Ask the PMC to verify that you have the appropriate CPAN permissions + on test-dev@. + +1. 'make dist' - to make sure nothing is missing from the manifest, + etc. Now test this generated package (not svn) with as many + configurations as possible on as many platforms as possible. + + a. edit ./Changes: + - change -dev to -rc\d+ starting with -rc1 + - note that you *do not* want to change the version in Apache/Test.pm, + this is a significant difference than other Apache::* modules. + this means that development proceeds with non '-dev' or '-rc1' version + tags, so keep that in mind. + + b. commit Changes + % svn ci -m "1.42 rc1" Changes + + c. nuke any preinstalled Apache-Test libs and run 'make test' + + d. test that you can 'make install' and then run 'make test' again + + e. test whether we are still 100% OK on systems with no LWP: + % APACHE_TEST_PRETEND_NO_LWP=1 make test + +2. once confident that the package is good, commit the release candidate + to https://dist.apache.org/repos/dist/dev/perl and post 24 hour-ish + candidate alert to the various lists. note that you will need to + be subscribed to all of the following lists. + + o test-dev/perl.apache.org + o dev/perl.apache.org + o modperl/perl.apache.org + o dev/httpd.apache.org + + (or maybe longer to give most people a chance to catch up). no need + to tag this package + + Subject: [RELEASE CANDIDATE] Apache-Test-1.42 RC\d+ + + a. if problems are detected during stage 2, repeat stages 1 and 2. + +3. when the package has been reported to be good, prepare a new + package to be released + + a. edit ./Changes: + - remove -rc\d+ + - add release date + + b. rerun: + % perl Makefile.PL + make sure tag looks right + % make -n tag + + c. commit Changes + % svn ci -m "1.42 release" Changes + + d. tag + % make tag + + e. create the final package + % make dist + + f. test the final package again at least once + +4. Upload the package to CPAN + +5. Announce the package + + a. post to the following lists: + + o test-dev/perl.apache.org + o dev/perl.apache.org + o modperl/perl.apache.org + + Subject: [ANNOUNCE] Apache-Test-1.42 + + include: + - MD5 sig (as it comes from CPAN upload announce). + - the latest Changes + +6. Prepare for the next cycle + + a. increment version in lib/Apache/Test.pm + + b. edit ./Changes: + - start a new item with incremented version + '-dev' + + =item 1.43-dev + + c. bump up version numbers in this file to make it easier to do the + next release. + % perl -pi.bak -e 's/(\d+)\.(\d+)/join(".", $1, $2+1)/eg' RELEASE + + d. commit Changes + % svn ci -m "start 1.42-dev cycle" Changes RELEASE lib/Apache/Test.pm diff --git a/debian/perl-framework/Apache-Test/SUPPORT b/debian/perl-framework/Apache-Test/SUPPORT new file mode 100644 index 0000000..ca58caf --- /dev/null +++ b/debian/perl-framework/Apache-Test/SUPPORT @@ -0,0 +1,57 @@ +The Apache-Test project is co-maintained by several developers, who +take turns at making CPAN releases. Therefore you may find several +CPAN directories containing Apache-Test releases. The best way to find +the latest release is to use http://search.cpan.org/. + +If you have a question or you want to submit a bug report or make a +contribution, please do not email individual authors, but send an +email to the test-dev <at> httpd.apache.org mailing list. This list is +moderated, so unless you are subscribed to it, your message will have +to be approved first by a moderator. Therefore please allow some time +(up to a few days) for your post to propagate to the list. + +If 'make test' fails to start, with an error message: + + !!! no test server configured, please specify an httpd or apxs or put + either in your PATH. For example: t/TEST -httpd /path/to/bin/httpd + +or similar, please don't submit a bug report, since this is a user +error, not a bug in Apache-Test. Instead, do what the error message +suggests; Apache-Test needs to know where it can find Apache and other +components. If you have apxs installed you can run the test suite via: + + % t/TEST -apxs /path/to/bin/apxs + +or if you set the APXS environment variable, via make: + + % APXS=/path/to/bin/apxs make test + +If you don't have 'apxs', tell Apache-Test where your httpd can be +found: + + % t/TEST -httpd /path/to/bin/httpd + +or via the APACHE environment variable: + + % APACHE=/path/to/bin/httpd make test + +*** CPAN Testers *** + +CPAN Testers using CPANPLUS and running under 'root' are required to +update their perl installation to have IPC::Run 0.78 or higher. Please +do not post failure reports unless you have this prerequisite +satisfied. It has nothing to do with Apache-Test itself, and needed +for CPANPLUS to flush the STDERR and STDOUT streams at the right time, +allowing you to skip the test suite if the conditions aren't suitable +for its execution. + +*** Apache C modules bug reports *** + +It's now possible to easily create tarballs with self-contained bug +reports for Apache modules in C. Geoff developed and maintains the +skeleton: + + http://perl.apache.org/~geoff/bug-reporting-skeleton-apache.tar.gz + +So next time you want to send a reproducable bug report for some C module, +grab that tarball, put your code in and submit it to the relevant list. diff --git a/debian/perl-framework/Apache-Test/ToDo b/debian/perl-framework/Apache-Test/ToDo new file mode 100644 index 0000000..4066558 --- /dev/null +++ b/debian/perl-framework/Apache-Test/ToDo @@ -0,0 +1,111 @@ +- on linux most symbols are resolved on demand, but this is not the + case with certain other platforms. so testing on linux may not + detect some problems, exposed on other platforms. env var + PERL_DL_NONLAZY=1 tries to resolve all symbols at load time. we + could always enforce that with this patch: + +--- Apache-Test/lib/Apache/TestRun.pm 16 Apr 2004 20:29:23 -0000 1.166 ++++ Apache-Test/lib/Apache/TestRun.pm 6 May 2004 04:43:01 -0000 +@@ -643,7 +643,7 @@ + } + close $sh; + +- $original_command = "ulimit -c unlimited; $original_command"; ++ $original_command = "ulimit -c unlimited; PERL_DL_NONLAZY=1 $original_comma +nd"; + +- general config: adjust Apache/TestConfig.pm not to write irrelevant + httpd.conf sections (e.g. <IfModule prefork.c> for win32, and vice + versa, A-T knows exactly what mpm it needs to write the config for). + Thus reducing the clutter. + +- winnt case: Apache/TestConfig.pm config for <IfModule mpm_winnt.c> + before Apache-2.0.50 ThreadsPerChild had to be at least as big as + the number of Vhosts. This was fixed in 2.0.50. Since A-T knows the + httpd version, it shouldn't start so many threads for httpd >= + 2.0.50, but @MinClients@. Also add BACK_COMPAT_MARKER in the logic + so when no longer support httpd < 2.0.50, this logic could be removed. + +- sometimes the server aborts completely after the test suite has run + some of the tests (e.g. win32's server has crashed and no + replacement is available), but the client part continues to run + tests unaware of that problem. what would be nice to be able to + detect that the server is gone and somehow abort the test suite + +- Custom sticky config: invalidate invalid bits of the saved config, + e.g. if apxs is saved but can't be found on the filesystem. So if + someone installs Apache in one location, runs A-T which saves that + location, and then nukes Apache and reinstalls it into a different + location we should drop the previously saved config since the path + to apxs and/or httpd is now invalid. + +- Apache-Test doesn't run on IPv6 systems, need to change the + autogeneration of httpd.conf to support IPv6. It requires a + replacement of 'Listen 80' with 'Listen servername:80' + Philippe posted patch here: + http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=105514290024419&w=2 + + For now, 127.0.0.1 will be hardcoded in the Listen directive, but a better + method would use this table: + + Apache \ OS | IPV4 | IPV6 + -------------------------------------------- + --enable-v4-mapped | 80 | 80 + --disable-v4-mapped | can't happen | 127.0.0.1:80 + + To more correctly pick the right Listen flavor. + +- Apache-Test assumes that any core file found under t/ was generated + by httpd, (and suggests the gdb invoking command) which is incorrect + in some cases. For example t/TEST -config, which is run by bin/perl, + may dump core as well. + +- consider not using the __DIE__ sighandler, but instead wrap the + potentially failing code in the eval trap blocks. + +- print STDERR is buffered in test handlers, whereas warn() works + normally. select() helps, but STDERR should be unbuffered in first + place. + +- If something goes wrong during the ./t/TEST's phase when all the + configuration files httpd.conf, etc. are generated, + t/conf/apache_test_config.pm now gets written, so t/TEST -clean can work + However if the problem happens during 'make test' for + some reason Makefile doesn't abort on exit from test_clean target, no + matter if I put exit -1, 0 or 1, and proceeds with run_tests target. + probably, since __DIE__ will stop the server. + + to reproduce the problem during configure() apply this patch: + +Index: Apache-Test/lib/Apache/TestConfigPerl.pm +=================================================================== +RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfigPerl.pm,v +retrieving revision 1.38 +diff -u -r1.38 TestConfigPerl.pm +--- Apache-Test/lib/Apache/TestConfigPerl.pm 2001/10/18 04:18:16 1.38 ++++ Apache-Test/lib/Apache/TestConfigPerl.pm 2001/10/19 02:14:56 +@@ -347,6 +347,7 @@ + if (open $fh, $file) { + my $content = <$fh>; + close $fh; ++ require $file; + if ($content =~ /APACHE_TEST_CONFIGURE/m) { + eval { require $file }; + warn $@ if $@; + +- segfaults should be trapped and: + * the test routine should be aborted, since it's possible that some + other test will segfault too and overwrite the core file + + * it'd be cool to automatically generate the backtrace with help of + Devel::CoreStack and save it in the file + + * once we add the backtrace feature, we don't have to abort the rest + of the tests, but to save each bt as "backtrace.$test_path". + => this should be very useful in smoke testing + + * later, it'd be nice to integrate this with build/bugreport.pl, so + the bug report with the backtrace and everything we want to know + from user's machine, including their /etc/shadow (:-) will be + automatically posted to the list. + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/Test.pm b/debian/perl-framework/Apache-Test/lib/Apache/Test.pm new file mode 100644 index 0000000..b3263c6 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/Test.pm @@ -0,0 +1,1214 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::Test; + +use strict; +use warnings FATAL => 'all'; + +use Exporter (); +use Config; +use Apache::TestConfig (); +use Test qw/ok skip/; + +BEGIN { + # Apache::Test loads a bunch of mp2 stuff while getting itself + # together. because we need to choose one of mp1 or mp2 to load + # check first (and we choose mp2) $mod_perl::VERSION == 2.0 + # just because someone loaded Apache::Test. This Is Bad. so, + # let's try to correct for that here by removing mod_perl from + # %INC after the above use() statements settle in. nobody + # should be relying on us loading up mod_perl.pm anyway... + + delete $INC{'mod_perl.pm'}; +} + +use vars qw(@ISA @EXPORT %EXPORT_TAGS $VERSION %SubTests @SkipReasons); + +$VERSION = '1.42'; + +my @need = qw(need_lwp need_http11 need_cgi need_access need_auth + need_module need_apache need_min_apache_version need_min_apache_fix + need_apache_version need_perl need_min_perl_version + need_min_module_version need_threads need_fork need_apache_mpm + need_php need_php4 need_ssl need_imagemap need_cache_disk); + +my @have = map { (my $need = $_) =~ s/need/have/; $need } @need; + +@ISA = qw(Exporter); +@EXPORT = (qw(sok plan skip_reason under_construction need), + @need, @have); + +%SubTests = (); +@SkipReasons = (); + +sub cp { + my @l; + for( my $i=1; (@l=caller $i)[0] eq __PACKAGE__; $i++ ) {}; + return wantarray ? @l : $l[0]; +} + +my $Config; +my %wtm; +sub import { + my $class=$_[0]; + my $wtm=0; + my @base_exp; + my @exp; + my %my_exports; + undef @my_exports{@EXPORT}; + + my ($caller,$f,$l)=cp; + + for( my $i=1; $i<@_; $i++ ) { + if( $_[$i] eq '-withtestmore' ) { + $wtm=1; + } + elsif( $_[$i] eq ':DEFAULT' ) { + push @exp, $_[$i]; + push @base_exp, $_[$i]; + } + elsif( $_[$i] eq '!:DEFAULT' ) { + push @exp, $_[$i]; + push @base_exp, $_[$i]; + } + elsif( $_[$i]=~m@^[:/!]@ ) { + warn("Ignoring import spec $_[$i] ". + "at $f line $l\n") + } + elsif( exists $my_exports{$_[$i]} ) { + push @exp, $_[$i]; + } + else { + push @base_exp, $_[$i]; + } + } + if (!@exp and @base_exp) { + @exp=('!:DEFAULT'); + } + elsif (@exp and !@base_exp) { + @base_exp=('!:DEFAULT'); + } + + $wtm{$caller}=[$wtm,$f,$l] unless exists $wtm{$caller}; + + warn("Ignoring -withtestmore due to a previous call ". + "($wtm{$caller}->[1]:$wtm{$caller}->[2]) without it ". + "at $f line $l\n") + if $wtm{$caller}->[0]==0 and $wtm==1; + + $class->export_to_level(1, $class, @exp); + + push @base_exp, '!plan'; + if( $wtm{$caller}->[0] ) { # -withtestmore + eval <<"EVAL" +package $caller; +#line $l $f +use Test::More import=>\\\@base_exp; +EVAL + } + else { # -withouttestmore + eval <<"EVAL"; +package $caller; +#line $l $f +use Test \@base_exp; +EVAL + } + die $@ if $@; +} + +sub config { + $Config ||= Apache::TestConfig->thaw->httpd_config; +} + +my $Basic_config; + +# config bits which doesn't require httpd to be found +sub basic_config { + $Basic_config ||= Apache::TestConfig->thaw(); +} + +sub vars { + @_ ? @{ config()->{vars} }{ @_ } : config()->{vars}; +} + +sub sok (&;$) { + my $sub = shift; + my $nok = shift || 1; #allow sok to have 'ok' within + + my ($caller,$f,$l)=cp; + + if (exists $wtm{$caller} and $wtm{$caller}->[0]==1) { # -withtestmore + require Test::Builder; + my $tb=Test::Builder->new; + + if (%SubTests and not $SubTests{ 1+$tb->current_test }) { + $tb->skip("skipping this subtest") for (1..$nok); + return; + } + + # trick ok() into reporting the caller filename/line when a + # sub-test fails in sok() + return eval <<EOE; +#line $l $f + Test::More::ok(\$sub->()); +EOE + } + else { + if (%SubTests and not $SubTests{ $Test::ntest }) { + skip("skipping this subtest", 0) for (1..$nok); + return; + } + + # trick ok() into reporting the caller filename/line when a + # sub-test fails in sok() + return eval <<EOE; +#line $l $f + Test::ok(\$sub->()); +EOE + } +} + +#so Perl's Test.pm can be run inside mod_perl +sub test_pm_refresh { + my ($caller,$f,$l)=cp; + + if (exists $wtm{$caller} and $wtm{$caller}->[0]==1) { # -withtestmore + require Test::Builder; + my $builder = Test::Builder->new; + + $builder->reset; + + $builder->output(\*STDOUT); + $builder->todo_output(\*STDOUT); + + # this is STDOUT because Test::More seems to put + # most of the stuff we want on STDERR, so it ends + # up in the error_log instead of where the user can + # see it. consider leaving it alone based on + # later user reports. + $builder->failure_output(\*STDOUT); + } + else { # -withouttestmore + unless (exists $wtm{$caller}) { + warn "You forgot to 'use Apache::Test' in package $caller\n"; + $wtm{$caller}=[0,$f,$l]; + } + if (defined &Test::_reset_globals) { + Test::_reset_globals(); + # Test.pm uses $TESTOUT=*STDOUT{IO}. We cannot do that + # due to the way SetupEnv works. + $Test::TESTOUT = \*STDOUT; + } + else { + $Test::TESTOUT = \*STDOUT; + $Test::planned = 0; + $Test::ntest = 1; + %Test::todo = (); + } + } +} + +sub init_test_pm { + my $r = shift; + + # needed to load Apache2::RequestRec::TIEHANDLE + eval {require Apache2::RequestIO}; + if (defined &Apache2::RequestRec::TIEHANDLE) { + untie *STDOUT; + tie *STDOUT, $r; + require Apache2::RequestRec; # $r->pool + require APR::Pool; + $r->pool->cleanup_register(sub { untie *STDOUT }); + } + else { + $r->send_http_header; #1.xx + } + + $r->content_type('text/plain'); +} + +sub plan { + init_test_pm(shift) if ref $_[0]; + test_pm_refresh(); + + # extending Test::plan's functionality, by using the optional + # single value in @_ coming after a ballanced %hash which + # Test::plan expects + if (@_ % 2) { + my $condition = pop @_; + my $ref = ref $condition; + my $meets_condition = 0; + if ($ref) { + if ($ref eq 'CODE') { + #plan tests $n, \&has_lwp + $meets_condition = $condition->(); + } + elsif ($ref eq 'ARRAY') { + #plan tests $n, [qw(php4 rewrite)]; + $meets_condition = need_module($condition); + } + else { + die "don't know how to handle a condition of type $ref"; + } + } + else { + # we have the verdict already: true/false + $meets_condition = $condition ? 1 : 0; + } + + # trying to emulate a dual variable (ala errno) + unless ($meets_condition) { + my $reason = join ', ', + @SkipReasons ? @SkipReasons : "no reason given"; + print "1..0 # skipped: $reason\n"; + @SkipReasons = (); # reset + exit; #XXX: Apache->exit + } + } + @SkipReasons = (); # reset + + my ($caller,$f,$l)=cp; + + %SubTests=(); + if (my $subtests=$ENV{HTTPD_TEST_SUBTESTS}) { + %SubTests=map { $_, 1 } split /\s+/, $subtests; + } + + if (exists $wtm{$caller} and $wtm{$caller}->[0]==1) { # -withtestmore + Test::More::plan(@_); + } + else { # -withouttestmore + unless (exists $wtm{$caller}) { + warn "You forgot to 'use Apache::Test' in package $caller\n"; + $wtm{$caller}=[0,$f,$l]; + } + Test::plan(@_); + } + + # add to Test.pm verbose output + print "# Using Apache/Test.pm version $VERSION\n"; +} + +sub need_http11 { + require Apache::TestRequest; + if (Apache::TestRequest::install_http11()) { + return 1; + } + else { + push @SkipReasons, + "LWP version 5.60+ required for HTTP/1.1 support"; + return 0; + } +} + +sub need_ssl { + my $vars = vars(); + need_module([$vars->{ssl_module_name}, 'IO::Socket::SSL']); +} + +sub need_lwp { + require Apache::TestRequest; + if (Apache::TestRequest::has_lwp()) { + return 1; + } + else { + push @SkipReasons, "libwww-perl is not installed"; + return 0; + } +} + +sub need { + my $need_all = 1; + for my $cond (@_) { + if (ref $cond eq 'HASH') { + while (my($reason, $value) = each %$cond) { + $value = $value->() if ref $value eq 'CODE'; + next if $value; + push @SkipReasons, $reason; + $need_all = 0; + } + } + elsif ($cond =~ /^(0|1)$/) { + $need_all = 0 if $cond == 0; + } + else { + $need_all = 0 unless need_module($cond); + } + } + return $need_all; + +} + +sub need_module { + my $cfg = config(); + + my @modules = grep defined $_, + ref($_[0]) eq 'ARRAY' ? @{ $_[0] } : @_; + + my @reasons = (); + for (@modules) { + if (/^[a-z0-9_.]+$/) { + my $mod = $_; + $mod .= '.c' unless $mod =~ /\.c$/; + next if $cfg->{modules}->{$mod}; + $mod = 'mod_' . $mod unless $mod =~ /^mod_/; + next if $cfg->{modules}->{$mod}; + if (exists $cfg->{cmodules_disabled}->{$mod}) { + push @reasons, $cfg->{cmodules_disabled}->{$mod}; + next; + } + } + die "bogus module name $_" unless /^[\w:.]+$/; + + # if the module was explicitly passed with a .c extension, + # do not try to eval it as a Perl module + my $not_found = 1; + unless (/\.c$/) { + eval "require $_"; + $not_found = 0 unless $@; + #print $@ if $@; + } + push @reasons, "cannot find module '$_'" if $not_found; + + } + if (@reasons) { + push @SkipReasons, @reasons; + return 0; + } + else { + return 1; + } +} + +sub need_min_perl_version { + my $version = shift; + + return 1 if $] >= $version; + + push @SkipReasons, "perl >= $version is required"; + return 0; +} + +# currently supports only perl modules +sub need_min_module_version { + my($module, $version) = @_; + + # need_module requires the perl module + return 0 unless need_module($module); + + # support dev versions like 0.18_01 + return 1 + if eval { no warnings qw(numeric); $module->VERSION($version) }; + + push @SkipReasons, "$module version $version or higher is required"; + return 0; +} + +sub need_cgi { + return _need_multi(qw(cgi.c cgid.c)); +} + +sub need_cache_disk { + return _need_multi(qw(cache_disk.c disk_cache.c)); +} + + +sub need_php { + return _need_multi(qw(php4 php5 sapi_apache2.c)); +} + +sub need_php4 { + return _need_multi(qw(php4 sapi_apache2.c)); +} + +sub need_access { + return _need_multi(qw(access authz_host)); +} + +sub need_auth { + return _need_multi(qw(auth auth_basic)); +} + +sub need_imagemap { + return need_module("imagemap") || need_module("imap"); +} + +sub _need_multi { + + my @check = @_; + + my $rc = 0; + + { + local @SkipReasons; + + foreach my $module (@check) { + $rc ||= need_module($module); + } + } + + my $reason = join ' or ', @check; + + push @SkipReasons, "cannot find one of $reason" + unless $rc; + + return $rc; +} + +sub need_apache { + my $version = shift; + my $cfg = Apache::Test::config(); + my $rev = $cfg->{server}->{rev}; + + if ($rev == $version) { + return 1; + } + else { + push @SkipReasons, + "apache version $version required, this is version $rev"; + return 0; + } +} + +sub need_min_apache_version { + my $wanted = shift; + my $cfg = Apache::Test::config(); + (my $current) = $cfg->{server}->{version} =~ m:^Apache/(\d\.\d+\.\d+):; + + if (normalize_vstring($current) < normalize_vstring($wanted)) { + push @SkipReasons, + "apache version $wanted or higher is required," . + " this is version $current"; + return 0; + } + else { + return 1; + } +} + +sub need_min_apache_fix { + my @wantlevels = @_; + my $cfg = Apache::Test::config(); + (my $current) = $cfg->{server}->{version} =~ m:^Apache/((\d)\.(\d+)\.(\d+)):; + my $current_major = $2; + my $current_minor = $3; + my $current_micro = $4; + + foreach(@wantlevels) { + if ($_ =~ m/(\d)\.(\d+)\.(\d+)/) { + my $wanted_major = $1; + my $wanted_minor = $2; + my $wanted_micro = $3; + if ($wanted_major eq $current_major && $wanted_minor eq $current_minor) { + if ($wanted_micro > $current_micro) { + push @SkipReasons, + "apache version $_ or higher is required," . + " this is version $current"; + return 0; + } + else { + return 1; + } + } + } + } + + # We didn't match major+minor, run the test and let the author sort it out + return 1; +} + +sub need_apache_version { + my $wanted = shift; + my $cfg = Apache::Test::config(); + (my $current) = $cfg->{server}->{version} =~ m:^Apache/(\d\.\d+\.\d+):; + + if (normalize_vstring($current) != normalize_vstring($wanted)) { + push @SkipReasons, + "apache version $wanted or higher is required," . + " this is version $current"; + return 0; + } + else { + return 1; + } +} + +sub need_apache_mpm { + my $wanted = shift; + my $cfg = Apache::Test::config(); + my $current = $cfg->{server}->{mpm}; + + if ($current ne $wanted) { + push @SkipReasons, + "apache $wanted mpm is required," . + " this is the $current mpm"; + return 0; + } + else { + return 1; + } +} + +sub config_enabled { + my $key = shift; + defined $Config{$key} and $Config{$key} eq 'define'; +} + +sub need_perl_iolayers { + if (my $ext = $Config{extensions}) { + #XXX: better test? might need to test patchlevel + #if support depends bugs fixed in bleedperl + return $ext =~ m:PerlIO/scalar:; + } + 0; +} + +sub need_perl { + my $thing = shift; + #XXX: $thing could be a version + my $config; + + my $have = \&{"need_perl_$thing"}; + if (defined &$have) { + return 1 if $have->(); + } + else { + for my $key ($thing, "use$thing") { + if (exists $Config{$key}) { + $config = $key; + return 1 if config_enabled($key); + } + } + } + + push @SkipReasons, $config ? + "Perl was not built with $config enabled" : + "$thing is not available with this version of Perl"; + + return 0; +} + +sub need_threads { + my $status = 1; + + # check APR support + my $build_config = Apache::TestConfig->modperl_build_config; + + if ($build_config) { + my $apr_config = $build_config->get_apr_config(); + unless ($apr_config->{HAS_THREADS}) { + $status = 0; + push @SkipReasons, "Apache/APR was built without threads support"; + } + } + + # check Perl's useithreads + my $key = 'useithreads'; + unless (exists $Config{$key} and config_enabled($key)) { + $status = 0; + push @SkipReasons, "Perl was not built with 'ithreads' enabled"; + } + + return $status; +} + +sub need_fork { + my $have_fork = $Config{d_fork} || + $Config{d_pseudofork} || + (($^O eq 'MSWin32' || $^O eq 'NetWare') && + $Config{useithreads} && + $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/); + + if (!$have_fork) { + push @SkipReasons, 'The fork function is unimplemented'; + return 0; + } + else { + return 1; + } +} + +sub under_construction { + push @SkipReasons, "This test is under construction"; + return 0; +} + +sub skip_reason { + my $reason = shift || 'no reason specified'; + push @SkipReasons, $reason; + return 0; +} + +# normalize Apache-style version strings (2.0.48, 0.9.4) +# for easy numeric comparison. note that 2.1 and 2.1.0 +# are considered equivalent. +sub normalize_vstring { + + my @digits = shift =~ m/(\d+)\.?(\d*)\.?(\d*)/; + + return join '', map { sprintf("%03d", $_ || 0) } @digits; +} + +# have_ functions are the same as need_ but they don't populate +# @SkipReasons +for my $func (@have) { + no strict 'refs'; + (my $real_func = $func) =~ s/^have_/need_/; + *$func = sub { + # be nice to poor souls calling functions with $_ argument in + # the foreach loop, etc.! + local $_; + local @SkipReasons; + return $real_func->(@_); + }; +} + +package Apache::TestToString; + +Apache::Test->import('!:DEFAULT'); + +sub TIEHANDLE { + my $string = ""; + bless \$string; +} + +sub PRINT { + my $string = shift; + $$string .= join '', @_; +} + +sub start { + tie *STDOUT, __PACKAGE__; + Apache::Test::test_pm_refresh(); +} + +sub finish { + my $s; + { + my $o = tied *STDOUT; + $s = $$o; + } + untie *STDOUT; + $s; +} + +1; +__END__ + + +=head1 NAME + +Apache::Test - Test.pm wrapper with helpers for testing Apache + +=head1 SYNOPSIS + + use Apache::Test; + +=head1 DESCRIPTION + +B<Apache::Test> is a wrapper around the standard C<Test.pm> with +helpers for testing an Apache server. + +=head1 FUNCTIONS + +=over 4 + +=item plan + +This function is a wrapper around C<Test::plan>: + + plan tests => 3; + +just like using Test.pm, plan 3 tests. + +If the first argument is an object, such as an C<Apache::RequestRec> +object, C<STDOUT> will be tied to it. The C<Test.pm> global state will +also be refreshed by calling C<Apache::Test::test_pm_refresh>. For +example: + + plan $r, tests => 7; + +ties STDOUT to the request object C<$r>. + +If there is a last argument that doesn't belong to C<Test::plan> +(which expects a balanced hash), it's used to decide whether to +continue with the test or to skip it all-together. This last argument +can be: + +=over + +=item * a C<SCALAR> + +the test is skipped if the scalar has a false value. For example: + + plan tests => 5, 0; + +But this won't hint the reason for skipping therefore it's better to +use need(): + + plan tests => 5, + need 'LWP', + { "not Win32" => sub { $^O eq 'MSWin32'} }; + +see C<need()> for more info. + +=item * an C<ARRAY> reference + +need_module() is called for each value in this array. The test is +skipped if need_module() returns false (which happens when at least +one C or Perl module from the list cannot be found). + +Watch out for case insensitive file systems or duplicate modules +with the same name. I.E. If you mean mod_env.c + need_module('mod_env.c') +Not + need_module('env') + +=item * a C<CODE> reference + +the tests will be skipped if the function returns a false value. For +example: + + plan tests => 5, need_lwp; + +the test will be skipped if LWP is not available + +=back + +All other arguments are passed through to I<Test::plan> as is. + +=item ok + +Same as I<Test::ok>, see I<Test.pm> documentation. + +=item sok + +Allows to skip a sub-test, controlled from the command line. The +argument to sok() is a CODE reference or a BLOCK whose return value +will be passed to ok(). By default behaves like ok(). If all sub-tests +of the same test are written using sok(), and a test is executed as: + + % ./t/TEST -v skip_subtest 1 3 + +only sub-tests 1 and 3 will be run, the rest will be skipped. + +=item skip + +Same as I<Test::skip>, see I<Test.pm> documentation. + +=item test_pm_refresh + +Normally called by I<Apache::Test::plan>, this function will refresh +the global state maintained by I<Test.pm>, allowing C<plan> and +friends to be called more than once per-process. This function is not +exported. + +=back + +Functions that can be used as a last argument to the extended plan(). +Note that for each C<need_*> function there is a C<have_*> equivalent +that performs the exact same function except that it is designed to +be used outside of C<plan()>. C<need_*> functions have the side effect +of generating skip messages, if the test is skipped. C<have_*> functions +don't have this side effect. In other words, use C<need_apache()> +with C<plan()> to decide whether a test will run, but C<have_apache()> +within test logic to adjust expectations based on older or newer +server versions. + +=over + +=item need_http11 + + plan tests => 5, need_http11; + +Require HTTP/1.1 support. + +=item need_ssl + + plan tests => 5, need_ssl; + +Require SSL support. + +Not exported by default. + +=item need_lwp + + plan tests => 5, need_lwp; + +Require LWP support. + +=item need_cgi + + plan tests => 5, need_cgi; + +Requires mod_cgi or mod_cgid to be installed. + +=item need_cache_disk + + plan tests => 5, need_cache_disk + +Requires mod_cache_disk or mod_disk_cache to be installed. + + +=item need_php + + plan tests => 5, need_php; + +Requires a PHP module to be installed (version 4 or 5). + +=item need_php4 + + plan tests => 5, need_php4; + +Requires a PHP version 4 module to be installed. + +=item need_imagemap + + plan tests => 5, need_imagemap; + +Requires a mod_imagemap or mod_imap be installed + +=item need_apache + + plan tests => 5, need_apache 2; + +Requires Apache 2nd generation httpd-2.x.xx + + plan tests => 5, need_apache 1; + +Requires Apache 1st generation (apache-1.3.xx) + +See also C<need_min_apache_version()>. + +=item need_min_apache_version + +Used to require a minimum version of Apache. + +For example: + + plan tests => 5, need_min_apache_version("2.0.40"); + +requires Apache 2.0.40 or higher. + +=item need_apache_version + +Used to require a specific version of Apache. + +For example: + + plan tests => 5, need_apache_version("2.0.40"); + +requires Apache 2.0.40. + +=item need_min_apache_fix + +Used to require a particular micro version from corresponding minor release + +For example: + + plan tests => 5, need_min_apache_fix("2.0.40", "2.2.30", "2.4.18"); + +requires Apache 2.0.40 or higher. + +=item need_apache_mpm + +Used to require a specific Apache Multi-Processing Module. + +For example: + + plan tests => 5, need_apache_mpm('prefork'); + +requires the prefork MPM. + +=item need_perl + + plan tests => 5, need_perl 'iolayers'; + plan tests => 5, need_perl 'ithreads'; + +Requires a perl extension to be present, or perl compiled with certain +capabilities. + +The first example tests whether C<PerlIO> is available, the second +whether: + + $Config{useithread} eq 'define'; + +=item need_min_perl_version + +Used to require a minimum version of Perl. + +For example: + + plan tests => 5, need_min_perl_version("5.008001"); + +requires Perl 5.8.1 or higher. + +=item need_fork + +Requires the perl built-in function C<fork> to be implemented. + +=item need_module + + plan tests => 5, need_module 'CGI'; + plan tests => 5, need_module qw(CGI Find::File); + plan tests => 5, need_module ['CGI', 'Find::File', 'cgid']; + +Requires Apache C and Perl modules. The function accept a list of +arguments or a reference to a list. + +In case of C modules, depending on how the module name was passed it +may pass through the following completions: + +=over + +=item 1 need_module 'proxy_http.c' + +If there is the I<.c> extension, the module name will be looked up as +is, i.e. I<'proxy_http.c'>. + +=item 2 need_module 'mod_cgi' + +The I<.c> extension will be appended before the lookup, turning it into +I<'mod_cgi.c'>. + +=item 3 need_module 'cgi' + +The I<.c> extension and I<mod_> prefix will be added before the +lookup, turning it into I<'mod_cgi.c'>. + +=back + +=item need_min_module_version + +Used to require a minimum version of a module + +For example: + + plan tests => 5, need_min_module_version(CGI => 2.81); + +requires C<CGI.pm> version 2.81 or higher. + +Currently works only for perl modules. + +=item need + + plan tests => 5, + need 'LWP', + { "perl >= 5.8.0 and w/ithreads is required" => + ($Config{useperlio} && $] >= 5.008) }, + { "not Win32" => sub { $^O eq 'MSWin32' }, + "foo is disabled" => \&is_foo_enabled, + }, + 'cgid'; + +need() is more generic function which can impose multiple requirements +at once. All requirements must be satisfied. + +need()'s argument is a list of things to test. The list can include +scalars, which are passed to need_module(), and hash references. If +hash references are used, the keys, are strings, containing a reason +for a failure to satisfy this particular entry, the values are the +condition, which are satisfaction if they return true. If the value is +0 or 1, it used to decide whether the requirements very satisfied, so +you can mix special C<need_*()> functions that return 0 or 1. For +example: + + plan tests => 1, need 'Compress::Zlib', 'deflate', + need_min_apache_version("2.0.49"); + +If the scalar value is a string, different from 0 or 1, it's passed to +I<need_module()>. If the value is a code reference, it gets executed +at the time of check and its return value is used to check the +condition. If the condition check fails, the provided (in a key) +reason is used to tell user why the test was skipped. + +In the presented example, we require the presence of the C<LWP> Perl +module, C<mod_cgid>, that we run under perl E<gt>= 5.7.3 on Win32. + +It's possible to put more than one requirement into a single hash +reference, but be careful that the keys will be different. + +It's also important to mention to avoid using: + + plan tests => 1, requirement1 && requirement2; + +technique. While test-wise that technique is equivalent to: + + plan tests => 1, need requirement1, requirement2; + +since the test will be skipped, unless all the rules are satisfied, +it's not equivalent for the end users. The second technique, deploying +C<need()> and a list of requirements, always runs all the requirement +checks and reports all the missing requirements. In the case of the +first technique, if the first requirement fails, the second is not +run, and the missing requirement is not reported. So let's say all the +requirements are missing Apache modules, and a user wants to satisfy +all of these and run the test suite again. If all the unsatisfied +requirements are reported at once, she will need to rebuild Apache +once. If only one requirement is reported at a time, she will have to +rebuild Apache as many times as there are elements in the C<&&> +statement. + +Also see plan(). + +=item under_construction + + plan tests => 5, under_construction; + +skip all tests, noting that the tests are under construction + +=item skip_reason + + plan tests => 5, skip_reason('my custom reason'); + +skip all tests. the reason you specify will be given at runtime. +if no reason is given a default reason will be used. + +=back + +=head1 Additional Configuration Variables + +=over 4 + +=item basic_config + + my $basic_cfg = Apache::Test::basic_config(); + $basic_cfg->write_perlscript($file, $content); + +C<basic_config()> is similar to C<config()>, but doesn't contain any +httpd-specific information and should be used for operations that +don't require any httpd-specific knowledge. + +=item config + + my $cfg = Apache::Test::config(); + my $server_rev = $cfg->{server}->{rev}; + ... + +C<config()> gives an access to the configuration object. + +=item vars + + my $serverroot = Apache::Test::vars->{serverroot}; + my $serverroot = Apache::Test::vars('serverroot'); + my($top_dir, $t_dir) = Apache::Test::vars(qw(top_dir t_dir)); + +C<vars()> gives an access to the configuration variables, otherwise +accessible as: + + $vars = Apache::Test::config()->{vars}; + +If no arguments are passed, the reference to the variables hash is +returned. If one or more arguments are passed the corresponding values +are returned. + +=back + +=head1 Test::More Integration + +There are a few caveats if you want to use I<Apache::Test> with +I<Test::More> instead of the default I<Test> backend. The first is +that I<Test::More> requires you to use its own C<plan()> function +and not the one that ships with I<Apache::Test>. I<Test::More> also +defines C<ok()> and C<skip()> functions that are different, and +simply C<use>ing both modules in your test script will lead to redefined +warnings for these subroutines. + +To assist I<Test::More> users we have created a special I<Apache::Test> +import tag, C<:withtestmore>, which will export all of the standard +I<Apache::Test> symbols into your namespace except the ones that collide +with I<Test::More>. + + use Apache::Test qw(:withtestmore); + use Test::More; + + plan tests => 1; # Test::More::plan() + + ok ('yes', 'testing ok'); # Test::More::ok() + +Now, while this works fine for standard client-side tests +(such as C<t/basic.t>), the more advanced features of I<Apache::Test> +require using I<Test::More> as the sole driver behind the scenes. + +Should you choose to use I<Test::More> as the backend for +server-based tests (such as C<t/response/TestMe/basic.pm>) you will +need to use the C<-withtestmore> action tag: + + use Apache::Test qw(-withtestmore); + + sub handler { + + my $r = shift; + + plan $r, tests => 1; # Test::More::plan() with + # Apache::Test features + + ok ('yes', 'testing ok'); # Test::More::ok() + } + +C<-withtestmore> tells I<Apache::Test> to use I<Test::More> +instead of I<Test.pm> behind the scenes. Note that you are not +required to C<use Test::More> yourself with the C<-withtestmore> +option and that the C<use Test::More tests =E<gt> 1> syntax +may have unexpected results. + +Note that I<Test::More> version 0.49, available within the +I<Test::Simple> 0.49 distribution on CPAN, or greater is required +to use this feature. + +Because I<Apache:Test> was initially developed using I<Test> as +the framework driver, complete I<Test::More> integration is +considered experimental at this time - it is supported as best as +possible but is not guaranteed to be as stable as the default I<Test> +interface at this time. + +=head1 Apache::TestToString Class + +The I<Apache::TestToString> class is used to capture I<Test.pm> output +into a string. Example: + + Apache::TestToString->start; + + plan tests => 4; + + ok $data eq 'foo'; + + ... + + # $tests will contain the Test.pm output: 1..4\nok 1\n... + my $tests = Apache::TestToString->finish; + +=head1 SEE ALSO + +The Apache-Test tutorial: +L<http://perl.apache.org/docs/general/testing/testing.html>. + +L<Apache::TestRequest|Apache::TestRequest> subclasses LWP::UserAgent and +exports a number of useful functions for sending request to the Apache test +server. You can then test the results of those requests. + +Use L<Apache::TestMM|Apache::TestMM> in your F<Makefile.PL> to set up your +distribution for testing. + +=head1 AUTHOR + +Doug MacEachern with contributions from Geoffrey Young, Philippe +M. Chiasson, Stas Bekman and others. + +Questions can be asked at the test-dev <at> httpd.apache.org list +For more information see: http://httpd.apache.org/test/. + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/Test5005compat.pm b/debian/perl-framework/Apache-Test/lib/Apache/Test5005compat.pm new file mode 100644 index 0000000..8f59a88 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/Test5005compat.pm @@ -0,0 +1,85 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::Test5005compat; + +use strict; +use Symbol (); +use File::Basename; +use File::Path; + +$Apache::Test5005compat::VERSION = '0.01'; + +my %compat_files = ( + 'lib/warnings.pm' => \&warnings_pm, +); + +sub import { + if ($] >= 5.006) { + #make sure old compat stubs dont wipe out installed versions + unlink for keys %compat_files; + return; + } + + eval { require File::Spec::Functions; } or + die "this is only Perl $], you need to install File-Spec from CPAN"; + + my $min_version = 0.82; + unless ($File::Spec::VERSION >= $min_version) { + die "you need to install File-Spec-$min_version or higher from CPAN"; + } + + while (my($file, $sub) = each %compat_files) { + $sub->($file); + } +} + +sub open_file { + my $file = shift; + + unless (-d 'lib') { + $file = "Apache-Test/$file"; + } + + my $dir = dirname $file; + + unless (-d $dir) { + mkpath([$dir], 0, 0755); + } + + my $fh = Symbol::gensym(); + print "creating $file\n"; + open $fh, ">$file" or die "open $file: $!"; + + return $fh; +} + +sub warnings_pm { + return if eval { require warnings }; + + my $fh = open_file(shift); + + print $fh <<'EOF'; +package warnings; + +sub import {} + +1; +EOF + + close $fh; +} + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm new file mode 100644 index 0000000..f0004e6 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm @@ -0,0 +1,699 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestBuild; + +use strict; +use warnings FATAL => 'all'; + +use subs qw(system chdir + info warning); + +use Config; +use File::Spec::Functions; +use File::Path (); +use Cwd (); + +use constant DRYRUN => 0; + +my @min_modules = qw(access auth log-config env mime setenvif + mime autoindex dir alias); + +my %shared_modules = ( + min => join(' ', @min_modules), +); + +my %configs = ( + all => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20(qw(modules=all proxy)), + }, + most => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20(qw(modules=most)), + }, + min => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20(@min_modules), + }, + exp => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20(qw(example case_filter + case_filter_in cache + echo deflate bucketeer)), + }, +); + +my %builds = ( + default => { + cflags => '-Wall', + config => { + 'apache-1.3' => [], + 'httpd-2.0' => [], + }, + }, + debug => { + cflags => '-g', + config => { + 'apache-1.3' => [], + 'httpd-2.0' => [qw(--enable-maintainer-mode)], + }, + }, + prof => { + cflags => '-pg -DGPROF', + }, + shared => { + config => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20_shared('all'), + }, + }, + mostshared => { + config => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20_shared('most'), + }, + }, + minshared => { + config => { + 'apache-1.3' => [], + 'httpd-2.0' => enable20_shared('min'), + }, + }, + static => { + }, +); + +my %mpms = ( + default => [qw(prefork worker)], + MSWin32 => [qw(winnt)], +); + +my @cvs = qw(httpd-2.0 apache-1.3); + +my @dirs = qw(build tar src install); + +sub enable20 { + [ map { "--enable-$_" } @_ ]; +} + +sub enable20_shared { + my $name = shift; + my $modules = $shared_modules{$name} || $name; + enable20(qq(mods-shared="$modules")); +} + +sub default_mpms { + $mpms{ $^O } || $mpms{'default'}; +} + +sub default_dir { + my($self, $dir) = @_; + $self->{$dir} ||= catdir $self->{prefix}, $dir, +} + +sub new { + my $class = shift; + + #XXX: not generating a BUILD script yet + #this way we can run: + #perl Apache-Test/lib/Apache/TestBuild.pm --cvsroot=anon --foo=... + + require Apache::TestConfig; + require Apache::TestTrace; + Apache::TestTrace->import; + + my $self = bless { + prefix => '/usr/local/apache', + cwd => Cwd::cwd(), + cvsroot => 'cvs.apache.org:/home/cvs', + cvs => \@cvs, + cvstag => "", + ssldir => "", + mpms => default_mpms(), + make => $Config{make}, + builds => {}, + name => "", + extra_config => { + 'httpd-2.0' => [], + }, + @_, + }, $class; + + #XXX + if (my $c = $self->{extra_config}->{'2.0'}) { + $self->{extra_config}->{'httpd-2.0'} = $c; + } + + for my $dir (@dirs) { + $self->default_dir($dir); + } + + if ($self->{ssldir}) { + push @{ $self->{extra_config}->{'httpd-2.0'} }, + '--enable-ssl', "--with-ssl=$self->{ssldir}"; + } + + $self; +} + +sub init { + my $self = shift; + + for my $dir (@dirs) { + mkpath($self->{$dir}); + } +} + +use subs qw(symlink unlink); +use File::Basename; +use File::Find; + +sub symlink_tree { + my $self = shift; + + my $httpd = 'httpd'; + my $install = "$self->{install}/bin/$httpd"; + my $source = "$self->{build}/.libs/$httpd"; + + unlink $install; + symlink $source, $install; + + my %dir = (apr => 'apr', + aprutil => 'apr-util'); + + for my $libname (qw(apr aprutil)) { + my $lib = "lib$libname.so.0.0.0"; + my $install = "$self->{install}/lib/$lib"; + my $source = "$self->{build}/srclib/$dir{$libname}/.libs/$lib"; + + unlink $install; + symlink $source, $install; + } + + $install = "$self->{install}/modules"; + $source = "$self->{build}/modules"; + + for (<$install/*.so>) { + unlink $_; + } + + finddepth(sub { + return unless /\.so$/; + my $file = "$File::Find::dir/$_"; + symlink $file, "$install/$_"; + }, $source); +} + +sub unlink { + my $file = shift; + + if (-e $file) { + print "unlink $file\n"; + } + else { + print "$file does not exist\n"; + } + CORE::unlink($file); +} + +sub symlink { + my($from, $to) = @_; + print "symlink $from => $to\n"; + unless (-e $from) { + print "source $from does not exist\n"; + } + my $base = dirname $to; + unless (-e $base) { + print "target dir $base does not exist\n"; + } + CORE::symlink($from, $to) or die $!; +} + +sub cvs { + my $self = shift; + + my $cmd = "cvs -d $self->{cvsroot} @_"; + + if (DRYRUN) { + info "$cmd"; + } + else { + system $cmd; + } +} + +my %cvs_names = ( + '2.0' => 'httpd-2.0', + '1.3' => 'apache-1.3', +); + +my %cvs_snames = ( + '2.0' => 'httpd', + '1.3' => 'apache', +); + +sub cvs_up { + my($self, $version) = @_; + + my $name = $cvs_names{$version}; + + my $dir = $self->srcdir($version); + + if ($self->{cvsroot} eq 'anon') { + $self->{cvsroot} = ':pserver:anoncvs@cvs.apache.org:/home/cvspublic'; + unless (-d $dir) { + #XXX do something better than doesn't require prompt if + #we already have an entry in ~/.cvspass + #$self->cvs('login'); + + warning "may need to run the following command ", + "(password is 'anoncvs')"; + warning "cvs -d $self->{cvsroot} login"; + } + } + + if (-d $dir) { + chdir $dir; + $self->cvs(up => "-dP $self->{cvstag}"); + return; + } + + my $co = checkout($name); + $self->$co($name, $dir); + + my $post = post_checkout($name); + $self->$post($name, $dir); +} + +sub checkout_httpd_2_0 { + my($self, $name, $dir) = @_; + + my $tag = $self->{cvstag}; + + $self->cvs(co => "-d $dir $tag $name"); + chdir "$dir/srclib"; + $self->cvs(co => "$tag apr apr-util"); +} + +sub checkout_apache_1_3 { + my($self, $name, $dir) = @_; + + $self->cvs(co => "-d $dir $self->{cvstag} $name"); +} + +sub post_checkout_httpd_2_0 { + my($self, $name, $dir) = @_; +} + +sub post_checkout_apache_1_3 { +} + +sub canon { + my $name = shift; + return $name unless $name; + $name =~ s/[.-]/_/g; + $name; +} + +sub checkout { + my $name = canon(shift); + \&{"checkout_$name"}; +} + +sub post_checkout { + my $name = canon(shift); + \&{"post_checkout_$name"}; +} + +sub cvs_update { + my $self = shift; + + my $cvs = shift || $self->{cvs}; + + chdir $self->{src}; + + for my $name (@$cvs) { + $self->cvs_up($name); + } +} + +sub merge_build { + my($self, $version, $builds, $configs) = @_; + + my $b = { + cflags => $builds{default}->{cflags}, + config => [ @{ $builds{default}->{config}->{$version} } ], + }; + + for my $name (@$builds) { + next if $name eq 'default'; #already have this + + if (my $flags = $builds{$name}->{cflags}) { + $b->{cflags} .= " $flags"; + } + if (my $cfg = $builds{$name}->{config}) { + if (my $vcfg = $cfg->{$version}) { + push @{ $b->{config} }, @$vcfg; + } + } + } + + for my $name (@$configs) { + my $cfg = $configs{$name}->{$version}; + next unless $cfg; + push @{ $b->{config} }, @$cfg; + } + + if (my $ex = $self->{extra_config}->{$version}) { + push @{ $b->{config} }, @$ex; + } + + if (my $ex = $self->{extra_cflags}->{$version}) { + $b->{config} .= " $ex"; + } + + $b; +} + +my @srclib_dirs = qw( + apr apr-util apr-util/xml/expat pcre +); + +sub install_name { + my($self, $builds, $configs, $mpm) = @_; + + return $self->{name} if $self->{name}; + + my $name = join '-', $mpm, @$builds, @$configs; + + if (my $tag = $self->cvs_name) { + $name .= "-$tag"; + } + + $name; +} + +#currently the httpd-2.0 build does not properly support static linking +#of ssl libs, force the issue +sub add_ssl_libs { + my $self = shift; + + my $ssldir = $self->{ssldir}; + + return unless $ssldir and -d $ssldir; + + my $name = $self->{current_install_name}; + + my $ssl_mod = "$name/modules/ssl"; + info "editing $ssl_mod/modules.mk"; + + if (DRYRUN) { + return; + } + + my $ssl_mk = "$self->{build}/$ssl_mod/modules.mk"; + + open my $fh, $ssl_mk or die "open $ssl_mk: $!"; + my @lines = <$fh>; + close $fh; + + for (@lines) { + next unless /SH_LINK/; + chomp; + $_ .= " -L$ssldir -lssl -lcrypto\n"; + info 'added ssl libs'; + last; + } + + open $fh, '>', $ssl_mk or die $!; + print $fh join "\n", @lines; + close $fh; +} + +sub cvs_name { + my $self = shift; + + if (my $tag = $self->{cvstag}) { + $tag =~ s/^-[DAr]//; + $tag =~ s/\"//g; + $tag =~ s,[/ :],_,g; #-D"03/29/02 07:00pm" + return $tag; + } + + return ""; +} + +sub srcdir { + my($self, $src) = @_; + + my $prefix = ""; + if ($src =~ s/^(apache|httpd)-//) { + $prefix = $1; + } + else { + $prefix = $cvs_snames{$src}; + } + + if ($src =~ /^\d\.\d$/) { + #release version will be \d\.\d\.\d+ + if (my $tag = $self->cvs_name) { + $src .= "-$tag"; + } + $src .= '-cvs'; + } + + join '-', $prefix, $src; +} + +sub configure_httpd_2_0 { + my($self, $src, $builds, $configs, $mpm) = @_; + + $src = $self->srcdir($src); + + chdir $self->{build}; + + my $name = $self->install_name($builds, $configs, $mpm); + + $self->{current_install_name} = $name; + + $self->{builds}->{$name} = 1; + + if ($self->{fresh}) { + rmtree($name); + } + else { + if (-e "$name/.DONE") { + warning "$name already configured"; + warning "rm $name/.DONE to force"; + return; + } + } + + my $build = $self->merge_build('httpd-2.0', $builds, $configs); + + $ENV{CFLAGS} = $build->{cflags}; + info "CFLAGS=$ENV{CFLAGS}"; + + my $prefix = "$self->{install}/$name"; + + rmtree($prefix) if $self->{fresh}; + + my $source = "$self->{src}/$src"; + + my @args = ("--prefix=$prefix", + "--with-mpm=$mpm", + "--srcdir=$source", + @{ $build->{config} }); + + chdir $source; + system "./buildconf"; + + my $cmd = "$source/configure @args"; + + chdir $self->{build}; + + mkpath($name); + chdir $name; + + for my $dir (@srclib_dirs) { + mkpath("srclib/$dir"); + } + + for my $dir (qw(build docs/conf)) { + mkpath($dir); + } + + system $cmd; + + open FH, ">.DONE" or die "open .DONE: $!"; + print FH scalar localtime; + close FH; + + chdir $self->{prefix}; + + $self->add_ssl_libs; +} + +sub make { + my($self, @cmds) = @_; + + push @cmds, 'all' unless @cmds; + + for my $name (keys %{ $self->{builds} }) { + chdir "$self->{build}/$name"; + for my $cmd (@cmds) { + system "$self->{make} $cmd"; + } + } +} + +sub system { + my $cmd = "@_"; + + info $cmd; + return if DRYRUN; + + unless (CORE::system($cmd) == 0) { + my $status = $? >> 8; + die "system $cmd failed (exit status=$status)"; + } +} + +sub chdir { + my $dir = shift; + info "chdir $dir"; + CORE::chdir $dir; +} + +sub mkpath { + my $dir = shift; + + return if -d $dir; + info "mkpath $dir"; + + return if DRYRUN; + File::Path::mkpath([$dir], 1, 0755); +} + +sub rmtree { + my $dir = shift; + + return unless -d $dir; + info "rmtree $dir"; + + return if DRYRUN; + File::Path::rmtree([$dir], 1, 1); +} + +sub generate_script { + my($class, $file) = @_; + + $file ||= catfile 't', 'BUILD'; + + my $content = join '', <DATA>; + + Apache::Test::basic_config()->write_perlscript($file, $content); +} + +unless (caller) { + $INC{'Apache/TestBuild.pm'} = __FILE__; + eval join '', <DATA>; + die $@ if $@; +} + +1; +__DATA__ +use strict; +use warnings FATAL => 'all'; + +use lib qw(Apache-Test/lib); +use Apache::TestBuild (); +use Getopt::Long qw(GetOptions); +use Cwd (); + +my %options = ( + prefix => "checkout/build/install prefix", + ssldir => "enable ssl with given directory", + cvstag => "checkout with given cvs tag", + cvsroot => "use 'anon' for anonymous cvs", + version => "apache version (e.g. '2.0')", + mpms => "MPMs to build (e.g. 'prefork')", + flavor => "build flavor (e.g. 'debug shared')", + modules => "enable modules (e.g. 'all exp')", + name => "change name of the build/install directory", +); + +my %opts; + +Getopt::Long::Configure(qw(pass_through)); +#XXX: could be smarter here, being lazy for the moment +GetOptions(\%opts, map "$_=s", sort keys %options); + +if (@ARGV) { + print "passing extra args to configure: @ARGV\n"; +} + +my $home = $ENV{HOME}; + +$opts{prefix} ||= join '/', Cwd::cwd(), 'farm'; +#$opts{ssldir} ||= ''; +#$opts{cvstag} ||= ''; +#$opts{cvsroot} ||= ''; +$opts{version} ||= '2.0'; +$opts{mpms} ||= 'prefork'; +$opts{flavor} ||= 'debug-shared'; +$opts{modules} ||= 'all-exp'; + +#my @versions = qw(2.0); + +#my @mpms = qw(prefork worker perchild); + +#my @flavors = ([qw(debug shared)], [qw(prof shared)], +# [qw(debug static)], [qw(prof static)]); + +#my @modules = ([qw(all exp)]); + +my $split = sub { split '-', delete $opts{ $_[0] } }; + +my @versions = $opts{version}; + +my @mpms = $split->('mpms'); + +my @flavors = ([ $split->('flavor') ]); + +my @modules = ([ $split->('modules') ]); + +my $tb = Apache::TestBuild->new(fresh => 1, + %opts, + extra_config => { + $opts{version} => \@ARGV, + }); + +$tb->init; + +for my $version (@versions) { + $tb->cvs_update([ $version ]); + + for my $mpm (@mpms) { + for my $flavor (@flavors) { + for my $mods (@modules) { + $tb->configure_httpd_2_0($version, $flavor, + $mods, $mpm); + $tb->make(qw(all install)); + } + } + } +} diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestClient.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestClient.pm new file mode 100644 index 0000000..bd2d328 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestClient.pm @@ -0,0 +1,203 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestClient; + +#this module provides some fallback for when libwww-perl is not installed +#it is by no means an LWP replacement, just enough for very simple requests + +#this module does not and will never support certain features such as: +#file upload, http/1.1 (byteranges, keepalive, etc.), following redirects, +#authentication, GET body callbacks, SSL, etc. + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest (); + +my $CRLF = "\015\012"; + +sub request { + my($method, $url, @headers) = @_; + + my @real_headers = (); + my $content; + + for (my $i = 0; $i < scalar @headers; $i += 2) { + if ($headers[$i] =~ /^content$/i) { + $content = $headers[$i+1]; + } + else { + push @real_headers, ($headers[$i], $headers[$i+1]); + } + } + + ## XXX: + ## This is not a FULL URL encode mapping + ## space ' '; however is very common, so this + ## is useful to convert + $url =~ s/ /%20/g; + + my $config = Apache::Test::config(); + + $method ||= 'GET'; + $url ||= '/'; + my %headers = (); + + my $hostport = Apache::TestRequest::hostport($config); + $headers{Host} = (split ':', $hostport)[0]; + + my $s = Apache::TestRequest::vhost_socket(); + + unless ($s) { + warn "cannot connect to $hostport: $!"; + return undef; + } + + if ($content) { + $headers{'Content-Length'} ||= length $content; + $headers{'Content-Type'} ||= 'application/x-www-form-urlencoded'; + } + + #for modules/setenvif + $headers{'User-Agent'} ||= 'libwww-perl/0.00'; + + my $request = join $CRLF, + "$method $url HTTP/1.0", + (map { "$_: $headers{$_}" } keys %headers); + + $request .= $CRLF; + + for (my $i = 0; $i < scalar @real_headers; $i += 2) { + $request .= "$real_headers[$i]: $real_headers[$i+1]$CRLF"; + } + + $request .= $CRLF; + + # using send() avoids the need to use SIGPIPE if the server aborts + # the connection + $s->send($request); + $s->send($content) if $content; + + $request =~ s/\015//g; #for as_string + + my $res = { + request => (bless { + headers_as_string => $request, + content => $content || '', + }, 'Apache::TestClientRequest'), + headers_as_string => '', + method => $method, + code => -1, # unknown + }; + + my($response_line, $header_term); + my $eol = "\015?\012"; + + local $_; + + while (<$s>) { + $res->{headers_as_string} .= $_; + if (m:^(HTTP/\d+\.\d+)[ \t]+(\d+)[ \t]*(.*?)$eol:io) { + $res->{protocol} = $1; + $res->{code} = $2; + $res->{message} = $3; + $response_line = 1; + } + elsif (/^([a-zA-Z0-9_\-]+)\s*:\s*(.*?)$eol/o) { + $res->{headers}->{lc $1} = $2; + } + elsif (/^$eol$/o) { + $header_term = 1; + last; + } + } + + unless ($response_line and $header_term) { + warn "malformed response"; + } + + { + local $/; + $res->{content} = <$s>; + } + close $s; + + # an empty body is a valid response + $res->{content} = '' + unless exists $res->{content} and defined $res->{content}; + + $res->{headers_as_string} =~ s/\015//g; #for as_string + + bless $res, 'Apache::TestClientResponse'; +} + +for my $method (qw(GET HEAD POST PUT)) { + no strict 'refs'; + *$method = sub { + my $url = shift; + request($method, $url, @_); + }; +} + +package Apache::TestClientResponse; + +sub header { + my($self, $key) = @_; + $self->{headers}->{lc $key}; +} + +my @headers = qw(Last-Modified Content-Type); + +for my $header (@headers) { + no strict 'refs'; + (my $method = lc $header) =~ s/-/_/g; + *$method = sub { shift->{headers}->{lc $header} }; +} + +sub is_success { + my $code = shift->{code}; + return 0 unless defined $code && $code; + $code >= 200 && $code < 300; +} + +sub status_line { + my $self = shift; + "$self->{code} $self->{message}"; +} + +sub as_string { + my $self = shift; + $self->{headers_as_string} . ($self->{content} || ''); +} + +my @methods = qw( +request protocol code message method +headers_as_string headers content +); + +for my $method (@methods) { + no strict 'refs'; + *$method = sub { + my($self, $val) = @_; + $self->{$method} = $val if $val; + $self->{$method}; + }; +} + +#inherit headers_as_string, as_string, protocol, content, etc. methods +@Apache::TestClientRequest::ISA = qw(Apache::TestClientResponse); + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm new file mode 100644 index 0000000..e65d1d3 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm @@ -0,0 +1,109 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestCommon; + +use strict; +use warnings FATAL => 'all'; + +use File::Basename; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestCommonPost (); + +#this module contains common tests that are called from different .t files + +#t/apache/passbrigade.t +#t/apache/rwrite.t + +sub run_write_test { + my $module = shift; + + #1k..9k, 10k..50k, 100k, 300k, 500k, 2Mb, 4Mb, 6Mb, 10Mb + my @sizes = (1..9, 10..50, 100, 300, 500, 2000, 4000, 6000, 10_000); + my @buff_sizes = (1024, 8192); + + plan tests => @sizes * @buff_sizes, [$module, 'LWP']; + + my $location = "/$module"; + my $ua = Apache::TestRequest::user_agent(); + + for my $buff_size (@buff_sizes) { + for my $size (@sizes) { + my $length = $size * 1024; + my $received = 0; + + $ua->do_request(GET => "$location?$buff_size,$length", + sub { + my($chunk, $res) = @_; + $received += length $chunk; + }); + + ok t_cmp($length, $received, 'bytes in body'); + } + } +} + +sub run_files_test { + my($verify, $skip_other) = @_; + + my $vars = Apache::Test::vars(); + my $perlpod = $vars->{perlpod}; + + my %pod = ( + files => [], + num => 0, + url => '/getfiles-perl-pod', + dir => "", + ); + + if (-d $perlpod) { + my @files = map { basename $_ } <$perlpod/*.pod>; + $pod{files} = \@files; + $pod{num} = scalar @files; + $pod{dir} = $perlpod; + } + else { + push @Apache::Test::SkipReasons, + "dir $vars->{perlpod} does not exist"; + } + + my %other_files = (); + + unless ($skip_other) { #allow to skip the large binary files + %other_files = map { + ("/getfiles-binary-$_", $vars->{$_}) + } qw(httpd perl); + } + + my $tests = $pod{num} + keys(%other_files); + + plan tests => $tests, sub { $pod{num} and have_lwp() }; + + my $ua = Apache::TestRequest::user_agent(); + + for my $file (@{ $pod{files} }) { + $verify->($ua, "$pod{url}/$file", "$pod{dir}/$file"); + } + + for my $url (sort keys %other_files) { + $verify->($ua, $url, $other_files{$url}); + } +} + +1; +__END__ diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestCommonPost.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestCommonPost.pm new file mode 100644 index 0000000..dda2b31 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestCommonPost.pm @@ -0,0 +1,199 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestCommonPost; + +use strict; +use warnings FATAL => 'all'; + +use constant POST_HUGE => $ENV{APACHE_TEST_POST_HUGE} || 0; + +use Apache::TestRequest (); +use Apache::TestUtil qw(t_cmp t_debug); +use Apache::Test qw(sok); + +BEGIN { + my $use_inline = 0; + + eval { + #if Inline.pm and libcurl are available + #we can make this test about 3x faster, + #after the inlined code is compiled that is. + require Inline; + Inline->import(C => 'DATA', LIBS => ['-lcurl'], + #CLEAN_AFTER_BUILD => 0, + PREFIX => 'aptest_post_'); + *request_init = \&curl_init; + *request_do = \&curl_do; + $use_inline = 1; + } if POST_HUGE; + + if (POST_HUGE) { + if ($@) { + t_debug "tests will run faster with Inline and curl installed"; + print $@; + } + else { + t_debug "using Inline and curl client"; + } + } + + unless ($use_inline) { + t_debug "using LWP client"; + #fallback to lwp + *request_init = \&lwp_init; + *request_do = \&lwp_do; + } +} + +sub lwp_init { + use vars qw($UA $Location); + $UA = Apache::TestRequest::user_agent(); + $Location = shift; +} + +sub lwp_do { + my $length = shift; + + my $request = HTTP::Request->new(POST => $Location); + $request->header('Content-length' => $length); + + if (LWP->VERSION >= 5.800) { + $request->content_ref(\('a' x $length)); + } else { + # before LWP 5.800 there was no way to tell HTTP::Message not + # to copy the string, there is a settable content_ref since + # 5.800 + use constant BUF_SIZE => 8192; + + my $remain = $length; + my $content = sub { + my $bytes = $remain < BUF_SIZE ? $remain : BUF_SIZE; + my $buf = 'a' x $bytes; + $remain -= $bytes; + $buf; + }; + + $request->content($content); + } + + + + my $response = $UA->request($request); + + Apache::TestRequest::lwp_trace($response); + + return $response->content; +} + +my @run_post_test_small_sizes = + #1k..9k, 10k..50k, 100k + (1..9, 10..50, 100); + +my @run_post_test_sizes = @run_post_test_small_sizes; + +if (POST_HUGE) { + push @run_post_test_sizes, + #300k, 500k, 2Mb, 4Mb, 6Mb, 10Mb + 300, 500, 2000, 4000, 6000, 10_000; +} + +sub Apache::TestCommon::run_post_test_sizes { @run_post_test_sizes } + +sub Apache::TestCommon::run_post_test { + my $module = shift; + my $sizes = shift || \@run_post_test_sizes; + + my $location = Apache::TestRequest::resolve_url("/$module"); + + request_init($location); + + for my $size (@$sizes) { + sok { + my $length = ($size * 1024); + + my $str = request_do($length); + chomp $str; + + t_cmp($length, $str, "length posted"); + }; + } +} + +1; +__DATA__ + +__C__ + +#include <curl/curl.h> +#include <curl/easy.h> + +static CURL *curl = NULL; +static SV *response = (SV *)NULL; +static long total = 0; + +static size_t my_curl_read(char *buffer, size_t size, + size_t nitems, void *data) +{ + size_t bytes = nitems < total ? nitems : total; + memset(buffer, 'a', bytes); + total -= bytes; + return bytes; +} + +static size_t my_curl_write(char *buffer, size_t size, + size_t nitems, void *data) +{ + sv_catpvn(response, buffer, nitems); + return nitems; +} + +void aptest_post_curl_init(char *url) +{ + char *proto = "HTTP/1.1"; /* curl default */ + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_MUTE, 1); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_curl_read); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_curl_write); + if (!getenv("APACHE_TEST_HTTP11")) { + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + proto = "HTTP/1.0"; + } + fprintf(stdout, "#CURL using protocol %s\n", proto); + fflush(stdout); + response = newSV(0); +} + +SV *aptest_post_curl_do(long len) +{ + sv_setpv(response, ""); + total = len; + curl_easy_setopt(curl, CURLOPT_INFILESIZE, len); + curl_easy_perform(curl); + return SvREFCNT_inc(response); +} + +void aptest_post_END(void) +{ + if (response) { + SvREFCNT_dec(response); + } + if (curl) { + curl_easy_cleanup(curl); + } +} diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm new file mode 100644 index 0000000..85689b0 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm @@ -0,0 +1,2299 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestConfig; + +use strict; +use warnings FATAL => 'all'; + +use constant WIN32 => $^O eq 'MSWin32'; +use constant OSX => $^O eq 'darwin'; +use constant CYGWIN => $^O eq 'cygwin'; +use constant NETWARE => $^O eq 'NetWare'; +use constant SOLARIS => $^O eq 'solaris'; +use constant AIX => $^O eq 'aix'; +use constant WINFU => WIN32 || NETWARE; +use constant COLOR => ($ENV{APACHE_TEST_COLOR} && -t STDOUT) ? 1 : 0; + +use constant DEFAULT_PORT => 8529; + +use constant IS_MOD_PERL_2 => + eval { require mod_perl2 } || 0; + +use constant IS_MOD_PERL_2_BUILD => IS_MOD_PERL_2 && + eval { require Apache2::Build && Apache2::Build::IS_MOD_PERL_BUILD() }; + +use constant IS_APACHE_TEST_BUILD => + grep { -e "$_/lib/Apache/TestConfig.pm" } + qw(Apache-Test . .. ../Apache-Test); + +use lib (); +use File::Copy (); +use File::Find qw(finddepth); +use File::Basename qw(dirname); +use File::Path (); +use File::Spec::Functions qw(catfile abs2rel splitdir canonpath + catdir file_name_is_absolute devnull); +use Cwd qw(fastcwd); +use Socket (); +use Symbol (); + +use Apache::TestConfigPerl (); +use Apache::TestConfigParse (); +use Apache::TestTrace; +use Apache::TestServer (); +use Apache::TestRun (); + +use vars qw(%Usage); + +%Usage = ( + top_dir => 'top-level directory (default is $PWD)', + t_dir => 'the t/ test directory (default is $top_dir/t)', + t_conf => 'the conf/ test directory (default is $t_dir/conf)', + t_logs => 'the logs/ test directory (default is $t_dir/logs)', + t_state => 'the state/ test directory (default is $t_dir/state)', + t_pid_file => 'location of the pid file (default is $t_logs/httpd.pid)', + t_conf_file => 'test httpd.conf file (default is $t_conf/httpd.conf)', + src_dir => 'source directory to look for mod_foos.so', + serverroot => 'ServerRoot (default is $t_dir)', + documentroot => 'DocumentRoot (default is $ServerRoot/htdocs', + port => 'Port [port_number|select] (default ' . DEFAULT_PORT . ')', + servername => 'ServerName (default is localhost)', + user => 'User to run test server as (default is $USER)', + group => 'Group to run test server as (default is $GROUP)', + bindir => 'Apache bin/ dir (default is apxs -q BINDIR)', + sbindir => 'Apache sbin/ dir (default is apxs -q SBINDIR)', + httpd => 'server to use for testing (default is $bindir/httpd)', + target => 'name of server binary (default is apxs -q TARGET)', + apxs => 'location of apxs (default is from Apache2::BuildConfig)', + startup_timeout => 'seconds to wait for the server to start (default is 60)', + httpd_conf => 'inherit config from this file (default is apxs derived)', + httpd_conf_extra=> 'inherit additional config from this file', + minclients => 'minimum number of concurrent clients (default is 1)', + maxclients => 'maximum number of concurrent clients (default is minclients+1)', + threadsperchild => 'number of threads per child when using threaded MPMs (default is 10)', + perlpod => 'location of perl pod documents (for testing downloads)', + proxyssl_url => 'url for testing ProxyPass / https (default is localhost)', + sslca => 'location of SSL CA (default is $t_conf/ssl/ca)', + sslcaorg => 'SSL CA organization to use for tests (default is asf)', + sslproto => 'SSL/TLS protocol version(s) to test', + libmodperl => 'path to mod_perl\'s .so (full or relative to LIBEXECDIR)', + defines => 'values to add as -D defines (for example, "VAR1 VAR2")', + (map { $_ . '_module_name', "$_ module name"} qw(cgi ssl thread access auth php)), +); + +my %filepath_conf_opts = map { $_ => 1 } + qw(top_dir t_dir t_conf t_logs t_state t_pid_file t_conf_file src_dir serverroot + documentroot bindir sbindir httpd apxs httpd_conf httpd_conf_extra + perlpod sslca libmodperl); + +sub conf_opt_is_a_filepath { + my $opt = shift; + $opt && exists $filepath_conf_opts{$opt}; +} + +sub usage { + for my $hash (\%Usage) { + for (sort keys %$hash){ + printf " -%-18s %s\n", $_, $hash->{$_}; + } + } +} + +sub filter_args { + my($args, $wanted_args) = @_; + my(@pass, %keep); + + my @filter = @$args; + + if (ref($filter[0])) { + push @pass, shift @filter; + } + + while (@filter) { + my $key = shift @filter; + # optinal - or -- prefix + if (defined $key && $key =~ /^-?-?(.+)/ && exists $wanted_args->{$1}) { + if (@filter) { + $keep{$1} = shift @filter; + } + else { + die "key $1 requires a matching value"; + } + } + else { + push @pass, $key; + } + } + + return (\@pass, \%keep); +} + +my %passenv = map { $_,1 } qw{ + APACHE_TEST_APXS + APACHE_TEST_HTTPD + APACHE_TEST_GROUP + APACHE_TEST_USER + APACHE_TEST_PORT +}; + +sub passenv { + \%passenv; +} + +sub passenv_makestr { + my @vars; + + for (sort keys %passenv) { + push @vars, "$_=\$($_)"; + } + + "@vars"; +} + +sub server { shift->{server} } + +sub modperl_build_config { + + my $self = shift; + + my $server = ref $self ? $self->server : new_test_server(); + + # we can't do this if we're using httpd 1.3.X + # even if mod_perl2 is installed on the box + # similarly, we shouldn't be loading mp2 if we're not + # absolutely certain we're in a 2.X environment yet + # (such as mod_perl's own build or runtime environment) + if (($server->{rev} && $server->{rev} == 2) || + IS_MOD_PERL_2_BUILD || $ENV{MOD_PERL_API_VERSION}) { + eval { + require Apache2::Build; + } or return; + + return Apache2::Build->build_config; + } + + return; +} + +sub new_test_server { + my($self, $args) = @_; + Apache::TestServer->new($args || $self) +} + +# setup httpd-independent components +# for httpd-specific call $self->httpd_config() +sub new { + my $class = shift; + + my $args; + + $args = shift if $_[0] and ref $_[0]; + + $args = $args ? {%$args} : {@_}; #copy + + #see Apache::TestMM::{filter_args,generate_script} + #we do this so 'perl Makefile.PL' can be passed options such as apxs + #without forcing regeneration of configuration and recompilation of c-modules + #as 't/TEST apxs /path/to/apache/bin/apxs' would do + while (my($key, $val) = each %Apache::TestConfig::Argv) { + $args->{$key} = $val; + } + + my $top_dir = fastcwd; + $top_dir = pop_dir($top_dir, 't'); + # untaint as we are going to use it a lot later on in -T sensitive + # operations (.e.g @INC) + $top_dir = $1 if $top_dir =~ /(.*)/; + + # make sure that t/conf/apache_test_config.pm is found + # (unfortunately sometimes we get thrown into / by Apache so we + # can't just rely on $top_dir + lib->import($top_dir); + + my $thaw = {}; + #thaw current config + for (qw(conf t/conf)) { + last if eval { + require "$_/apache_test_config.pm"; + $thaw = 'apache_test_config'->new; + delete $thaw->{save}; + #incase class that generated the config was + #something else, which we can't be sure how to load + bless $thaw, 'Apache::TestConfig'; + }; + } + + if ($args->{thaw} and ref($thaw) ne 'HASH') { + #dont generate any new config + $thaw->{vars}->{$_} = $args->{$_} for keys %$args; + $thaw->{server} = $thaw->new_test_server; + $thaw->add_inc; + return $thaw; + } + + #regenerating config, so forget old + if ($args->{save}) { + for (qw(vhosts inherit_config modules inc cmodules)) { + delete $thaw->{$_} if exists $thaw->{$_}; + } + } + + my $self = bless { + clean => {}, + vhosts => {}, + inherit_config => {}, + modules => {}, + inc => [], + %$thaw, + mpm => "", + httpd_defines => {}, + vars => $args, + postamble => [], + preamble => [], + postamble_hooks => [], + preamble_hooks => [], + }, ref($class) || $class; + + my $vars = $self->{vars}; #things that can be overridden + + for (qw(save verbose)) { + next unless exists $args->{$_}; + $self->{$_} = delete $args->{$_}; + } + + $vars->{top_dir} ||= $top_dir; + + $self->add_inc; + + #help to find libmodperl.so + unless ($vars->{src_dir}) { + my $src_dir = catfile $vars->{top_dir}, qw(.. src modules perl); + + if (-d $src_dir) { + $vars->{src_dir} = $src_dir; + } else { + $src_dir = catfile $vars->{top_dir}, qw(src modules perl); + $vars->{src_dir} = $src_dir if -d $src_dir; + } + } + + $vars->{t_dir} ||= catfile $vars->{top_dir}, 't'; + $vars->{serverroot} ||= $vars->{t_dir}; + $vars->{documentroot} ||= catfile $vars->{serverroot}, 'htdocs'; + $vars->{perlpod} ||= $self->find_in_inc('pods') || + $self->find_in_inc('pod'); + $vars->{perl} ||= $^X; + $vars->{t_conf} ||= catfile $vars->{serverroot}, 'conf'; + $vars->{sslca} ||= catfile $vars->{t_conf}, 'ssl', 'ca'; + $vars->{sslcaorg} ||= 'asf'; + + if (!defined($vars->{sslproto}) and eval { require Apache::TestSSLCA; 1; }) { + $vars->{sslproto} = Apache::TestSSLCA::sslproto(); + } + else { + $vars->{sslproto} ||= 'all'; + } + + $vars->{t_logs} ||= catfile $vars->{serverroot}, 'logs'; + $vars->{t_state} ||= catfile $vars->{serverroot}, 'state'; + $vars->{t_conf_file} ||= catfile $vars->{t_conf}, 'httpd.conf'; + $vars->{t_pid_file} ||= catfile $vars->{t_logs}, 'httpd.pid'; + + if (WINFU) { + for (keys %$vars) { + $vars->{$_} =~ s|\\|\/|g if defined $vars->{$_}; + } + } + + $vars->{scheme} ||= 'http'; + $vars->{servername} ||= $self->default_servername; + $vars->{port} = $self->select_first_port; + $vars->{remote_addr} ||= $self->our_remote_addr; + + $vars->{user} ||= $self->default_user; + $vars->{group} ||= $self->default_group; + $vars->{serveradmin} ||= $self->default_serveradmin; + + $vars->{threadsperchild} ||= 10; + $vars->{minclients} ||= 1; + $vars->{maxclients_preset} = $vars->{maxclients} || 0; + # if maxclients wasn't explicitly passed try to + # prevent 'server reached MaxClients setting' errors + $vars->{maxclients} ||= $vars->{minclients} + 1; + + # if a preset maxclients valus is smaller than minclients, + # maxclients overrides minclients + if ($vars->{maxclients_preset} && + $vars->{maxclients_preset} < $vars->{minclients}) { + $vars->{minclients} = $vars->{maxclients_preset}; + } + if ($vars->{minclients} < 2) { + $vars->{maxspare} = 2; + } else { + $vars->{maxspare} = $vars->{minclients}; + } + if ($vars->{maxclients} < $vars->{maxspare} + 1) { + $vars->{maxclients} = $vars->{maxspare} + 1; + } + + # for threaded mpms MinClients and MaxClients must be a + # multiple of ThreadsPerChild + { + use integer; + $vars->{minclientsthreadedmpm} = ($vars->{minclients} + $vars->{threadsperchild} - 1) / + $vars->{threadsperchild} * $vars->{threadsperchild}; + $vars->{maxclientsthreadedmpm} = ($vars->{maxclients} + $vars->{threadsperchild} - 1) / + $vars->{threadsperchild} * $vars->{threadsperchild}; + $vars->{maxsparethreadedmpm} = ($vars->{maxspare} + $vars->{threadsperchild} - 1) / + $vars->{threadsperchild} * $vars->{threadsperchild}; + $vars->{startserversthreadedmpm} = $vars->{minclientsthreadedmpm} / $vars->{threadsperchild}; + } + if ($vars->{maxsparethreadedmpm} < 2 * $vars->{threadsperchild}) { + $vars->{maxsparethreadedmpm} = 2 * $vars->{threadsperchild}; + } + if ($vars->{maxclientsthreadedmpm} < $vars->{maxsparethreadedmpm} + $vars->{threadsperchild}) { + $vars->{maxclientsthreadedmpm} = $vars->{maxsparethreadedmpm} + $vars->{threadsperchild}; + } + + $vars->{proxy} ||= 'off'; + $vars->{proxyssl_url} ||= ''; + $vars->{defines} ||= ''; + + $self->{hostport} = $self->hostport; + $self->{server} = $self->new_test_server; + + return $self; + +} + +# figure out where httpd is and run extra config hooks which require +# knowledge of where httpd is +sub httpd_config { + my $self = shift; + + $self->configure_apxs; + $self->configure_httpd; + + my $vars = $self->{vars}; + unless ($vars->{httpd} or $vars->{apxs}) { + + # mod_perl 2.0 build (almost) always knows the right httpd + + # location (and optionally apxs). if we get here we can't + # continue because the interactive config can't work with + # mod_perl 2.0 build (by design) + if (IS_MOD_PERL_2_BUILD){ + my $mp2_build = $self->modperl_build_config(); + # if mod_perl 2 was built against the httpd source it + # doesn't know where to find apxs/httpd, so in this case + # fall back to interactive config + unless ($mp2_build->{MP_APXS}) { + die "mod_perl 2 was built against Apache sources, we " . + "don't know where httpd/apxs executables are, therefore " . + "skipping the test suite execution" + } + + # not sure what else could go wrong but we can't continue + die "something is wrong, mod_perl 2.0 build should have " . + "supplied all the needed information to run the tests. " . + "Please post lib/Apache2/BuildConfig.pm along with the " . + "bug report"; + } + + $self->clean(1); + + error "You must explicitly specify -httpd and/or -apxs options, " . + "or set \$ENV{APACHE_TEST_HTTPD} and \$ENV{APACHE_TEST_APXS}, " . + "or set your \$PATH to include the httpd and apxs binaries."; + Apache::TestRun::exit_perl(1); + + } + else { + debug "Using httpd: $vars->{httpd}"; + } + + $self->inherit_config; #see TestConfigParse.pm + $self->configure_httpd_eapi; #must come after inherit_config + + $self->default_module(cgi => [qw(mod_cgi mod_cgid)]); + $self->default_module(thread => [qw(worker threaded)]); + $self->default_module(ssl => [qw(mod_ssl)]); + $self->default_module(access => [qw(mod_access mod_authz_host)]); + $self->default_module(auth => [qw(mod_auth mod_auth_basic)]); + $self->default_module(php => [qw(sapi_apache2 mod_php4 mod_php5)]); + + $self->{server}->post_config; + + return $self; +} + +sub default_module { + my($self, $name, $choices) = @_; + + my $mname = $name . '_module_name'; + + unless ($self->{vars}->{$mname}) { + ($self->{vars}->{$mname}) = grep { + $self->{modules}->{"$_.c"}; + } @$choices; + + $self->{vars}->{$mname} ||= $choices->[0]; + } + + $self->{vars}->{$name . '_module'} = + $self->{vars}->{$mname} . '.c' +} + +sub configure_apxs { + my $self = shift; + + $self->{APXS} = $self->default_apxs; + + return unless $self->{APXS}; + + $self->{APXS} =~ s{/}{\\}g if WIN32; + + my $vars = $self->{vars}; + + $vars->{bindir} ||= $self->apxs('BINDIR', 1); + $vars->{sbindir} ||= $self->apxs('SBINDIR'); + $vars->{target} ||= $self->apxs('TARGET'); + $vars->{conf_dir} ||= $self->apxs('SYSCONFDIR'); + + if ($vars->{conf_dir}) { + $vars->{httpd_conf} ||= catfile $vars->{conf_dir}, 'httpd.conf'; + } +} + +sub configure_httpd { + my $self = shift; + my $vars = $self->{vars}; + + debug "configuring httpd"; + + $vars->{target} ||= (WIN32 ? 'Apache.EXE' : 'httpd'); + + unless ($vars->{httpd}) { + #sbindir should be bin/ with the default layout + #but its eaiser to workaround apxs than fix apxs + for my $dir (map { $vars->{$_} } qw(sbindir bindir)) { + next unless defined $dir; + my $httpd = catfile $dir, $vars->{target}; + next unless -x $httpd; + $vars->{httpd} = $httpd; + last; + } + + $vars->{httpd} ||= $self->default_httpd; + } + + if ($vars->{httpd}) { + my @chunks = splitdir $vars->{httpd}; + #handle both $prefix/bin/httpd and $prefix/Apache.exe + for (1,2) { + pop @chunks; + last unless @chunks; + $self->{httpd_basedir} = catfile @chunks; + last if -d "$self->{httpd_basedir}/bin"; + } + } + + #cleanup httpd droppings + my $sem = catfile $vars->{t_logs}, 'apache_runtime_status.sem'; + unless (-e $sem) { + $self->clean_add_file($sem); + } +} + +sub configure_httpd_eapi { + my $self = shift; + my $vars = $self->{vars}; + + #deal with EAPI_MM_CORE_PATH if defined. + if (defined($self->{httpd_defines}->{EAPI_MM_CORE_PATH})) { + my $path = $self->{httpd_defines}->{EAPI_MM_CORE_PATH}; + + #ensure the directory exists + my @chunks = splitdir $path; + pop @chunks; #the file component of the path + $path = catdir @chunks; + unless (file_name_is_absolute $path) { + $path = catdir $vars->{serverroot}, $path; + } + $self->gendir($path); + } +} + +sub configure_proxy { + my $self = shift; + my $vars = $self->{vars}; + + #if we proxy to ourselves, must bump the maxclients + if ($vars->{proxy} =~ /^on$/i) { + unless ($vars->{maxclients_preset}) { + $vars->{minclients}++; + $vars->{maxclients}++; + $vars->{maxspare}++; + $vars->{startserversthreadedmpm} ++; + $vars->{minclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxsparethreadedmpm} += $vars->{threadsperchild}; + #In addition allow for some backend processes + #in keep-alive state. For threaded MPMs we + #already should be fine. + $vars->{maxclients} += 3; + } + $vars->{proxy} = $self->{vhosts}->{'mod_proxy'}->{hostport}; + return $vars->{proxy}; + } + + return undef; +} + +# adds the config to the head of the group instead of the tail +# XXX: would be even better to add to a different sub-group +# (e.g. preamble_first) of only those that want to be first and then, +# make sure that they are dumped to the config file first in the same +# group (e.g. preamble) +sub add_config_first { + my $self = shift; + my $where = shift; + unshift @{ $self->{$where} }, $self->massage_config_args(@_); +} + +sub add_config_last { + my $self = shift; + my $where = shift; + push @{ $self->{$where} }, $self->massage_config_args(@_); +} + +sub massage_config_args { + my $self = shift; + my($directive, $arg, $data) = @_; + my $args = ""; + + if ($data) { + $args = "<$directive $arg>\n"; + if (ref($data) eq 'HASH') { + while (my($k,$v) = each %$data) { + $args .= " $k $v\n"; + } + } + elsif (ref($data) eq 'ARRAY') { + # balanced (key=>val) list + my $pairs = @$data / 2; + for my $i (0..($pairs-1)) { + $args .= sprintf " %s %s\n", $data->[$i*2], $data->[$i*2+1]; + } + } + else { + $data=~s/\n(?!\z)/\n /g; + $args .= " $data"; + } + $args .= "</$directive>\n"; + } + elsif (ref($directive) eq 'ARRAY') { + $args = join "\n", @$directive; + } + else { + $args = join " ", grep length($_), $directive, + (ref($arg) && (ref($arg) eq 'ARRAY') ? "@$arg" : $arg || ""); + } + + return $args; +} + +sub postamble_first { + shift->add_config_first(postamble => @_); +} + +sub postamble { + shift->add_config_last(postamble => @_); +} + +sub preamble_first { + shift->add_config_first(preamble => @_); +} + +sub preamble { + shift->add_config_last(preamble => @_); +} + +sub postamble_register { + push @{ shift->{postamble_hooks} }, @_; +} + +sub preamble_register { + push @{ shift->{preamble_hooks} }, @_; +} + +sub add_config_hooks_run { + my($self, $where, $out) = @_; + + for (@{ $self->{"${where}_hooks"} }) { + if ((ref($_) and ref($_) eq 'CODE') or $self->can($_)) { + $self->$_(); + } + else { + error "cannot run configure hook: `$_'"; + } + } + + for (@{ $self->{$where} }) { + $self->replace; + s/\n?$/\n/; + print $out "$_"; + } +} + +sub postamble_run { + shift->add_config_hooks_run(postamble => @_); +} + +sub preamble_run { + shift->add_config_hooks_run(preamble => @_); +} + +sub default_group { + return if WINFU; + + my $gid = $); + + #use only first value if $) contains more than one + $gid =~ s/^(\d+).*$/$1/; + + my $group = $ENV{APACHE_TEST_GROUP} || (getgrgid($gid) || "#$gid"); + + if ($group eq 'root') { + # similar to default_user, we want to avoid perms problems, + # when the server is started with group 'root'. When running + # under group root it may fail to create dirs and files, + # writable only by user + my $user = default_user(); + my $gid = $user ? (getpwnam($user))[3] : ''; + $group = (getgrgid($gid) || "#$gid") if $gid; + } + + $group; +} + +sub default_user { + return if WINFU; + + my $uid = $>; + + my $user = $ENV{APACHE_TEST_USER} || (getpwuid($uid) || "#$uid"); + + if ($user eq 'root') { + my $other = (getpwnam('nobody'))[0]; + if ($other) { + $user = $other; + } + else { + die "cannot run tests as User root"; + #XXX: prompt for another username + } + } + + return $user; +} + +sub default_serveradmin { + my $vars = shift->{vars}; + join '@', ($vars->{user} || 'unknown'), $vars->{servername}; +} + +sub default_apxs { + my $self = shift; + + return $self->{vars}->{apxs} if $self->{vars}->{apxs}; + + if (my $build_config = $self->modperl_build_config()) { + return $build_config->{MP_APXS}; + } + + if ($ENV{APACHE_TEST_APXS}) { + return $ENV{APACHE_TEST_APXS}; + } + + # look in PATH as a last resort + if (my $apxs = which('apxs')) { + return $apxs; + } elsif ($apxs = which('apxs2')) { + return $apxs; + } + + return; +} + +sub default_httpd { + my $self = shift; + + my $vars = $self->{vars}; + + if (my $build_config = $self->modperl_build_config()) { + if (my $p = $build_config->{MP_AP_PREFIX}) { + for my $bindir (qw(bin sbin)) { + my $httpd = catfile $p, $bindir, $vars->{target}; + return $httpd if -e $httpd; + # The executable on Win32 in Apache/2.2 is httpd.exe, + # so try that if Apache.exe doesn't exist + if (WIN32) { + $httpd = catfile $p, $bindir, 'httpd.EXE'; + if (-e $httpd) { + $vars->{target} = 'httpd.EXE'; + return $httpd; + } + } + } + } + } + + if ($ENV{APACHE_TEST_HTTPD}) { + return $ENV{APACHE_TEST_HTTPD}; + } + + # look in PATH as a last resort + if (my $httpd = which('httpd')) { + return $httpd; + } elsif ($httpd = which('httpd2')) { + return $httpd; + } elsif ($httpd = which('apache')) { + return $httpd; + } elsif ($httpd = which('apache2')) { + return $httpd; + } + + return; +} + +my $localhost; + +sub default_localhost { + my $localhost_addr = pack('C4', 127, 0, 0, 1); + gethostbyaddr($localhost_addr, Socket::AF_INET()) || 'localhost'; +} + +sub default_servername { + my $self = shift; + $localhost ||= $self->default_localhost; + die "Can't figure out the default localhost's server name" + unless $localhost; +} + +# memoize the selected value (so we make sure that the same port is used +# via select). The problem is that select_first_port() is called 3 times after +# -clean, and it's possible that a lower port will get released +# between calls, leading to various places in the test suite getting a +# different base port selection. +# +# XXX: There is still a problem if two t/TEST's configure at the same +# time, so they both see the same port free, but only the first one to +# bind() will actually get the port. So there is a need in another +# check and reconfiguration just before the server starts. +# +my $port_memoized; +sub select_first_port { + my $self = shift; + + my $port ||= $port_memoized || $ENV{APACHE_TEST_PORT} + || $self->{vars}{port} || DEFAULT_PORT; + + # memoize + $port_memoized = $port; + + return $port unless $port eq 'select'; + + # port select mode: try to find another available port, take into + # account that each instance of the test suite may use more than + # one port for virtual hosts, therefore try to check ports in big + # steps (20?). + my $step = 20; + my $tries = 20; + $port = DEFAULT_PORT; + until (Apache::TestServer->port_available($port)) { + unless (--$tries) { + error "no ports available"; + error "tried ports @{[DEFAULT_PORT]} - $port in $step increments"; + return 0; + } + $port += $step; + } + + info "the default base port is used, using base port $port instead" + unless $port == DEFAULT_PORT; + + # memoize + $port_memoized = $port; + + return $port; +} + +my $remote_addr; + +sub our_remote_addr { + my $self = shift; + my $name = $self->default_servername; + my $iaddr = (gethostbyname($name))[-1]; + unless (defined $iaddr) { + error "Can't resolve host: '$name' (check /etc/hosts)"; + exit 1; + } + $remote_addr ||= Socket::inet_ntoa($iaddr); +} + +sub default_loopback { + '127.0.0.1'; +} + +sub port { + my($self, $module) = @_; + + unless ($module) { + my $vars = $self->{vars}; + return $self->select_first_port() unless $vars->{scheme} eq 'https'; + $module = $vars->{ssl_module_name}; + } + return $self->{vhosts}->{$module}->{port}; +} + +sub hostport { + my $self = shift; + my $vars = shift || $self->{vars}; + my $module = shift || ''; + + my $name = $vars->{servername}; + + join ':', $name , $self->port($module || ''); +} + +#look for mod_foo.so +sub find_apache_module { + my($self, $module) = @_; + + die "find_apache_module: module name argument is required" + unless $module; + + my $vars = $self->{vars}; + my $sroot = $vars->{serverroot}; + + my @trys = grep { $_ } + ($vars->{src_dir}, + $self->apxs('LIBEXECDIR'), + catfile($sroot, 'modules'), + catfile($sroot, 'libexec')); + + for (@trys) { + my $file = catfile $_, $module; + if (-e $file) { + debug "found $module => $file"; + return $file; + } + } + + # if the module wasn't found try to lookup in the list of modules + # inherited from the system-wide httpd.conf + my $name = $module; + $name =~ s/\.s[ol]$/.c/; #mod_info.so => mod_info.c + $name =~ s/^lib/mod_/; #libphp4.so => mod_php4.c + return $self->{modules}->{$name} if $self->{modules}->{$name}; + +} + +#generate files and directories + +my %warn_style = ( + html => sub { "<!-- @_ -->" }, + c => sub { "/* @_ */" }, + php => sub { "<?php /* \n@_ \n*/ ?>" }, + default => sub { join '', grep {s/^/\# /gm} @_ }, +); + +my %file_ext = ( + map({$_ => 'html'} qw(htm html)), + map({$_ => 'c' } qw(c h)), + map({$_ => 'php' } qw(php)), +); + +# return the passed file's extension or '' if there is no one +# note: that '/foo/bar.conf.in' returns an extension: 'conf.in'; +# note: a hidden file .foo will be recognized as an extension 'foo' +sub filename_ext { + my ($self, $filename) = @_; + my $ext = (File::Basename::fileparse($filename, '\..*'))[2] || ''; + $ext =~ s/^\.(.*)/lc $1/e; + $ext; +} + +sub warn_style_sub_ref { + my ($self, $filename) = @_; + my $ext = $self->filename_ext($filename); + return $warn_style{ $file_ext{$ext} || 'default' }; +} + +sub genwarning { + my($self, $filename, $from_filename) = @_; + return unless $filename; + my $time = scalar localtime; + my $warning = "WARNING: this file is generated"; + $warning .= " (from $from_filename)" if defined $from_filename; + $warning .= ", do not edit\n"; + $warning .= "generated on $time\n"; + $warning .= calls_trace(); + return $self->warn_style_sub_ref($filename)->($warning); +} + +sub calls_trace { + my $frame = 1; + my $trace = ''; + + while (1) { + my($package, $filename, $line) = caller($frame); + last unless $filename; + $trace .= sprintf "%02d: %s:%d\n", $frame, $filename, $line; + $frame++; + } + + return $trace; +} + +sub clean_add_file { + my($self, $file) = @_; + + $self->{clean}->{files}->{ rel2abs($file) } = 1; +} + +sub clean_add_path { + my($self, $path) = @_; + + $path = rel2abs($path); + + # remember which dirs were created and should be cleaned up + while (1) { + $self->{clean}->{dirs}->{$path} = 1; + $path = dirname $path; + last if -e $path; + } +} + +sub genfile_trace { + my($self, $file, $from_file) = @_; + my $name = abs2rel $file, $self->{vars}->{t_dir}; + my $msg = "generating $name"; + $msg .= " from $from_file" if defined $from_file; + debug $msg; +} + +sub genfile_warning { + my($self, $file, $from_file, $fh) = @_; + + if (my $msg = $self->genwarning($file, $from_file)) { + print $fh $msg, "\n"; + } +} + +# $from_file == undef if there was no templates used +sub genfile { + my($self, $file, $from_file, $nowarning) = @_; + + # create the parent dir if it doesn't exist yet + my $dir = dirname $file; + $self->makepath($dir); + + $self->genfile_trace($file, $from_file); + + my $fh = Symbol::gensym(); + open $fh, ">$file" or die "open $file: $!"; + + $self->genfile_warning($file, $from_file, $fh) unless $nowarning; + + $self->clean_add_file($file); + + return $fh; +} + +# gen + write file +sub writefile { + my($self, $file, $content, $nowarning) = @_; + + my $fh = $self->genfile($file, undef, $nowarning); + + print $fh $content if $content; + + close $fh; +} + +sub perlscript_header { + + require FindBin; + + my @dirs = (); + + # mp2 needs its modper-2.0/lib before blib was created + if (IS_MOD_PERL_2_BUILD || $ENV{APACHE_TEST_LIVE_DEV}) { + # the live 'lib/' dir of the distro + # (e.g. modperl-2.0/ModPerl-Registry/lib) + my $dir = canonpath catdir $FindBin::Bin, "lib"; + push @dirs, $dir if -d $dir; + + # the live dir of the top dir if any (e.g. modperl-2.0/lib) + if (-e catfile($FindBin::Bin, "..", "Makefile.PL")) { + my $dir = canonpath catdir $FindBin::Bin, "..", "lib"; + push @dirs, $dir if -d $dir; + } + } + + for (qw(. ..)) { + my $dir = canonpath catdir $FindBin::Bin, $_ , "Apache-Test", "lib"; + if (-d $dir) { + push @dirs, $dir; + last; + } + } + + { + my $dir = canonpath catdir $FindBin::Bin, "t", "lib"; + push @dirs, $dir if -d $dir; + } + + push @dirs, canonpath $FindBin::Bin; + + my $dirs = join("\n ", '', @dirs) . "\n";; + + return <<"EOF"; + +use strict; +use warnings FATAL => 'all'; + +use lib qw($dirs); + +EOF +} + +# gen + write executable perl script file +sub write_perlscript { + my($self, $file, $content) = @_; + + my $fh = $self->genfile($file, undef, 1); + + my $shebang = make_shebang(); + print $fh $shebang; + + $self->genfile_warning($file, undef, $fh); + + print $fh $content if $content; + + close $fh; + chmod 0755, $file; +} + +sub make_shebang { + # if perlpath is longer than 62 chars, some shells on certain + # platforms won't be able to run the shebang line, so when seeing + # a long perlpath use the eval workaround. + # see: http://en.wikipedia.org/wiki/Shebang + # http://homepages.cwi.nl/~aeb/std/shebang/ + my $shebang = length $Config{perlpath} < 62 + ? "#!$Config{perlpath}\n" + : <<EOI; +$Config{'startperl'} + eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}' + if \$running_under_some_shell; +EOI + + return $shebang; +} + +sub cpfile { + my($self, $from, $to) = @_; + File::Copy::copy($from, $to); + $self->clean_add_file($to); +} + +sub symlink { + my($self, $from, $to) = @_; + CORE::symlink($from, $to); + $self->clean_add_file($to); +} + +sub gendir { + my($self, $dir) = @_; + $self->makepath($dir); +} + +# returns a list of dirs successfully created +sub makepath { + my($self, $path) = @_; + + return if !defined($path) || -e $path; + + $self->clean_add_path($path); + + return File::Path::mkpath($path, 0, 0755); +} + +sub open_cmd { + my($self, $cmd) = @_; + # untaint some %ENV fields + local @ENV{ qw(IFS CDPATH ENV BASH_ENV) }; + local $ENV{PATH} = untaint_path($ENV{PATH}); + + # launder for -T + $cmd = $1 if $cmd =~ /(.*)/; + + my $handle = Symbol::gensym(); + open $handle, "$cmd|" or die "$cmd failed: $!"; + + return $handle; +} + +sub clean { + my $self = shift; + $self->{clean_level} = shift || 2; #2 == really clean, 1 == reconfigure + + $self->new_test_server->clean; + $self->cmodules_clean; + $self->sslca_clean; + + for (sort keys %{ $self->{clean}->{files} }) { + if (-e $_) { + debug "unlink $_"; + unlink $_; + } + else { + debug "unlink $_: $!"; + } + } + + # if /foo comes before /foo/bar, /foo will never be removed + # hence ensure that sub-dirs are always treated before a parent dir + for (reverse sort keys %{ $self->{clean}->{dirs} }) { + if (-d $_) { + my $dh = Symbol::gensym(); + opendir($dh, $_); + my $notempty = grep { ! /^\.{1,2}$/ } readdir $dh; + closedir $dh; + next if $notempty; + debug "rmdir $_"; + rmdir $_; + } + } +} + +my %special_tokens = ( + nextavailableport => sub { shift->server->select_next_port } +); + +sub replace { + my $self = shift; + my $file = $Apache::TestConfig::File + ? "in file $Apache::TestConfig::File" : ''; + + s[@(\w+)@] + [ my $key = lc $1; + if (my $callback = $special_tokens{$key}) { + $self->$callback; + } + elsif (exists $self->{vars}->{$key}) { + $self->{vars}->{$key}; + } + else { + die "invalid token: \@$1\@ $file\n"; + } + ]ge; +} + +#need to configure the vhost port for redirects and $ENV{SERVER_PORT} +#to have the correct values +my %servername_config = ( + 0 => sub { + my($name, $port) = @_; + [ServerName => ''], [Port => 0]; + }, + 1 => sub { + my($name, $port) = @_; + [ServerName => $name], [Port => $port]; + }, + 2 => sub { + my($name, $port) = @_; + [ServerName => "$name:$port"]; + }, +); + +sub servername_config { + my $self = shift; + $self->server->version_of(\%servername_config)->(@_); +} + +sub parse_vhost { + my($self, $line) = @_; + + my($indent, $module, $namebased); + if ($line =~ /^(\s*)<VirtualHost\s+(?:_default_:|([^:]+):(?!:))?(.*?)\s*>\s*$/) { + $indent = $1 || ""; + $namebased = $2 || ""; + $module = $3; + } + else { + return undef; + } + + my $vars = $self->{vars}; + my $mods = $self->{modules}; + my $have_module = "$module.c"; + my $ssl_module = $vars->{ssl_module}; + + #if module ends with _ssl and it is not the module that implements ssl, + #then assume this module is a vhost with SSLEngine On (or similar) + #see mod_echo in extra.conf.in for example + if ($module =~ /^(mod_\w+)_ssl$/ and $have_module ne $ssl_module) { + $have_module = "$1.c"; #e.g. s/mod_echo_ssl.c/mod_echo.c/ + return undef unless $mods->{$ssl_module}; + } + + #don't allocate a port if this module is not configured + #assumes the configuration is inside an <IfModule $have_module> + if ($module =~ /^mod_/ and not $mods->{$have_module}) { + return undef; + } + + #allocate a port and configure this module into $self->{vhosts} + my $port = $self->new_vhost($module, $namebased); + + #extra config that should go *inside* the <VirtualHost ...> + my @in_config = $self->servername_config($namebased + ? $namebased + : $vars->{servername}, + $port); + + my @out_config = (); + if ($self->{vhosts}->{$module}->{namebased} < 2) { + #extra config that should go *outside* the <VirtualHost ...> + @out_config = ([Listen => '0.0.0.0:' . $port]); + + if ($self->{vhosts}->{$module}->{namebased}) { + push @out_config => ["<IfVersion < 2.3.11>\n". + "${indent}${indent}NameVirtualHost" + => "*:$port\n${indent}</IfVersion>"]; + } + } + + $self->{vars}->{$module . '_port'} = $port; + + #there are two ways of building a vhost + #first is when we parse test .pm and .c files + #second is when we scan *.conf.in + my $form_postamble = sub { + my $indent = shift; + for my $pair (@_) { + $self->postamble("$indent@$pair"); + } + }; + + my $form_string = sub { + my $indent = shift; + join "\n", map { "$indent@$_\n" } @_; + }; + + my $double_indent = $indent ? $indent x 2 : ' ' x 4; + return { + port => $port, + #used when parsing .pm and .c test modules + in_postamble => sub { $form_postamble->($double_indent, @in_config) }, + out_postamble => sub { $form_postamble->($indent, @out_config) }, + #used when parsing *.conf.in files + in_string => $form_string->($double_indent, @in_config), + out_string => $form_string->($indent, @out_config), + line => "$indent<VirtualHost " . ($namebased ? '*' : '_default_') . + ":$port>", + }; +} + +sub find_and_load_module { + my ($self, $name) = @_; + my $mod_path = $self->find_apache_module($name) or return; + my ($sym) = $name =~ m/mod_(\w+)\./; + + if ($mod_path && -e $mod_path) { + $self->preamble(IfModule => "!mod_$sym.c", + qq{LoadModule ${sym}_module "$mod_path"\n}); + } + return 1; +} + +sub replace_vhost_modules { + my $self = shift; + + if (my $cfg = $self->parse_vhost($_)) { + $_ = ''; + for my $key (qw(out_string line in_string)) { + next unless $cfg->{$key}; + $_ .= "$cfg->{$key}\n"; + } + } +} + +sub replace_vars { + my($self, $in, $out) = @_; + + local $_; + while (<$in>) { + $self->replace; + $self->replace_vhost_modules; + print $out $_; + } +} + +sub index_html_template { + my $self = shift; + return "welcome to $self->{server}->{name}\n"; +} + +sub generate_index_html { + my $self = shift; + my $dir = $self->{vars}->{documentroot}; + $self->gendir($dir); + my $file = catfile $dir, 'index.html'; + return if -e $file; + my $fh = $self->genfile($file); + print $fh $self->index_html_template; +} + +sub types_config_template { + return <<EOF; +text/html html htm +image/gif gif +image/jpeg jpeg jpg jpe +image/png png +text/plain asc txt +EOF +} + +sub generate_types_config { + my $self = shift; + + # handle the case when mod_mime is built as a shared object + # but wasn't included in the system-wide httpd.conf + $self->find_and_load_module('mod_mime.so'); + + unless ($self->{inherit_config}->{TypesConfig}) { + my $types = catfile $self->{vars}->{t_conf}, 'mime.types'; + unless (-e $types) { + my $fh = $self->genfile($types); + print $fh $self->types_config_template; + close $fh; + } + $self->postamble(<<EOI); +<IfModule mod_mime.c> + TypesConfig "$types" +</IfModule> +EOI + } +} + +# various dup bugs in older perl and perlio in perl < 5.8.4 need a +# workaround to explicitly rewind the dupped DATA fh before using it +my $DATA_pos = tell DATA; +sub httpd_conf_template { + my($self, $try) = @_; + + my $in = Symbol::gensym(); + if (open $in, $try) { + return $in; + } + else { + my $dup = Symbol::gensym(); + open $dup, "<&DATA" or die "Can't dup DATA: $!"; + seek $dup, $DATA_pos, 0; # rewind to the beginning + return $dup; # so we don't close DATA + } +} + +#certain variables may not be available until certain config files +#are generated. for example, we don't know the ssl port until ssl.conf.in +#is parsed. ssl port is needed for proxyssl testing + +sub check_vars { + my $self = shift; + my $vars = $self->{vars}; + + unless ($vars->{proxyssl_url}) { + my $ssl = $self->{vhosts}->{ $vars->{ssl_module_name} }; + if ($ssl) { + $vars->{proxyssl_url} ||= $ssl->{hostport}; + } + + if ($vars->{proxyssl_url}) { + unless ($vars->{maxclients_preset}) { + $vars->{minclients}++; + $vars->{maxclients}++; + $vars->{maxspare}++; + $vars->{startserversthreadedmpm} ++; + $vars->{minclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxsparethreadedmpm} += $vars->{threadsperchild}; + #In addition allow for some backend processes + #in keep-alive state. For threaded MPMs we + #already should be fine. + $vars->{maxclients} += 3; + } + } + } +} + +sub extra_conf_files_needing_update { + my $self = shift; + + my @need_update = (); + finddepth(sub { + return unless /\.in$/; + (my $generated = $File::Find::name) =~ s/\.in$//; + push @need_update, $generated + unless -e $generated && -M $generated < -M $File::Find::name; + }, $self->{vars}->{t_conf}); + + return @need_update; +} + +sub generate_extra_conf { + my $self = shift; + + my(@extra_conf, @conf_in, @conf_files); + + finddepth(sub { + return unless /\.in$/; + push @conf_in, catdir $File::Find::dir, $_; + }, $self->{vars}->{t_conf}); + + #make ssl port always be 8530 when available + for my $file (@conf_in) { + if (basename($file) =~ /^ssl/) { + unshift @conf_files, $file; + } + else { + push @conf_files, $file; + } + } + + for my $file (@conf_files) { + (my $generated = $file) =~ s/\.in$//; + debug "Will 'Include' $generated config file"; + push @extra_conf, $generated; + } + + # regenerate .conf files + for my $file (@conf_files) { + local $Apache::TestConfig::File = $file; + + my $in = Symbol::gensym(); + open($in, $file) or next; + + (my $generated = $file) =~ s/\.in$//; + my $out = $self->genfile($generated, $file); + $self->replace_vars($in, $out); + + close $in; + close $out; + + $self->check_vars; + } + + #we changed order to give ssl the first port after DEFAULT_PORT + #but we want extra.conf Included first so vhosts inherit base config + #such as LimitRequest* + return [ sort @extra_conf ]; +} + +sub sslca_can { + my($self, $check) = @_; + + my $vars = $self->{vars}; + return 0 unless $self->{modules}->{ $vars->{ssl_module} }; + return 0 unless -d "$vars->{t_conf}/ssl"; + + require Apache::TestSSLCA; + + if ($check) { + my $openssl = Apache::TestSSLCA::openssl(); + if (which($openssl)) { + return 1; + } + + error "cannot locate '$openssl' program required to generate SSL CA"; + exit(1); + } + + return 1; +} + +sub sslca_generate { + my $self = shift; + + my $ca = $self->{vars}->{sslca}; + return if $ca and -d $ca; #t/conf/ssl/ca + + return unless $self->sslca_can(1); + + Apache::TestSSLCA::generate($self); +} + +sub sslca_clean { + my $self = shift; + + # XXX: httpd config is required, for now just skip ssl clean if + # there is none. should probably add some flag which will tell us + # when httpd_config was already run + return unless $self->{vars}->{httpd} && $self->{vars}->{ssl_module}; + + return unless $self->sslca_can; + + Apache::TestSSLCA::clean($self); +} + +#XXX: just a quick hack to support t/TEST -ssl +#outside of httpd-test/perl-framework +sub generate_ssl_conf { + my $self = shift; + my $vars = $self->{vars}; + my $conf = "$vars->{t_conf}/ssl"; + my $httpd_test_ssl = "../httpd-test/perl-framework/t/conf/ssl"; + my $ssl_conf = "$vars->{top_dir}/$httpd_test_ssl"; + + if (-d $ssl_conf and not -d $conf) { + $self->gendir($conf); + for (qw(ssl.conf.in)) { + $self->cpfile("$ssl_conf/$_", "$conf/$_"); + } + for (qw(certs keys crl)) { + $self->symlink("$ssl_conf/$_", "$conf/$_"); + } + } +} + +sub find_in_inc { + my($self, $dir) = @_; + for my $path (@INC) { + my $location = "$path/$dir"; + return $location if -d $location; + } + return ""; +} + +sub prepare_t_conf { + my $self = shift; + $self->gendir($self->{vars}->{t_conf}); +} + +my %aliases = ( + "perl-pod" => "perlpod", + "binary-httpd" => "httpd", + "binary-perl" => "perl", +); +sub generate_httpd_conf { + my $self = shift; + my $vars = $self->{vars}; + + #generated httpd.conf depends on these things to exist + $self->generate_types_config; + $self->generate_index_html; + + $self->gendir($vars->{t_logs}); + $self->gendir($vars->{t_state}); + $self->gendir($vars->{t_conf}); + + my @very_last_postamble = (); + if (my $extra_conf = $self->generate_extra_conf) { + for my $file (@$extra_conf) { + my $entry; + if ($file =~ /\.conf$/) { + next if $file =~ m|/httpd\.conf$|; + $entry = qq(Include "$file"); + } + elsif ($file =~ /\.pl$/) { + $entry = qq(<IfModule mod_perl.c>\n PerlRequire "$file"\n</IfModule>\n); + } + else { + next; + } + + # put the .last includes very last + if ($file =~ /\.last\.(conf|pl)$/) { + push @very_last_postamble, $entry; + } + else { + $self->postamble($entry); + } + + } + } + + $self->configure_proxy; + + my $conf_file = $vars->{t_conf_file}; + my $conf_file_in = join '.', $conf_file, 'in'; + + my $in = $self->httpd_conf_template($conf_file_in); + + my $out = $self->genfile($conf_file); + + $self->find_and_load_module('mod_alias.so'); + + $self->preamble_run($out); + + for my $name (qw(user group)) { #win32 + if ($vars->{$name}) { + print $out qq[\u$name "$vars->{$name}"\n]; + } + } + + #2.0: ServerName $ServerName:$Port + #1.3: ServerName $ServerName + # Port $Port + my @name_cfg = $self->servername_config($vars->{servername}, + $vars->{port}); + for my $pair (@name_cfg) { + print $out "@$pair\n"; + } + + $self->replace_vars($in, $out); + + # handle the case when mod_alias is built as a shared object + # but wasn't included in the system-wide httpd.conf + + print $out "<IfModule mod_alias.c>\n"; + for (sort keys %aliases) { + next unless $vars->{$aliases{$_}}; + print $out " Alias /getfiles-$_ $vars->{$aliases{$_}}\n"; + } + print $out "</IfModule>\n"; + + print $out "\n"; + + $self->postamble_run($out); + + print $out join "\n", @very_last_postamble; + + close $in; + close $out or die "close $conf_file: $!"; +} + +sub need_reconfiguration { + my($self, $conf_opts) = @_; + my @reasons = (); + my $vars = $self->{vars}; + + # if '-port select' we need to check from scratch which ports are + # available + if (my $port = $conf_opts->{port} || $Apache::TestConfig::Argv{port}) { + if ($port eq 'select') { + push @reasons, "'-port $port' requires reconfiguration"; + } + } + + my $exe = $vars->{apxs} || $vars->{httpd} || ''; + # if httpd.conf is older than executable + push @reasons, + "$exe is newer than $vars->{t_conf_file}" + if -e $exe && + -e $vars->{t_conf_file} && + -M $exe < -M $vars->{t_conf_file}; + + # any .in files are newer than their derived versions? + if (my @files = $self->extra_conf_files_needing_update) { + # invalidate the vhosts cache, since a different port could be + # assigned on reparse + $self->{vhosts} = {}; + for my $file (@files) { + push @reasons, "$file.in is newer than $file"; + } + } + + # if special env variables are used (since they can change any time) + # XXX: may be we could check whether they have changed since the + # last run and thus avoid the reconfiguration? + { + my $passenv = passenv(); + if (my @env_vars = sort grep { $ENV{$_} } keys %$passenv) { + push @reasons, "environment variables (@env_vars) are set"; + } + } + + # if the generated config was created with a version of Apache-Test + # less than the current version + { + my $current = Apache::Test->VERSION; + my $config = $self->{apache_test_version}; + + if (! $config || $config < $current) { + push @reasons, "configuration generated with old Apache-Test"; + } + } + + return @reasons; +} + +sub error_log { + my($self, $rel) = @_; + my $file = catfile $self->{vars}->{t_logs}, 'error_log'; + my $rfile = abs2rel $file, $self->{vars}->{top_dir}; + return wantarray ? ($file, $rfile) : + $rel ? $rfile : $file; +} + +#utils + +#For Win32 systems, stores the extensions used for executable files +#They may be . prefixed, so we will strip the leading periods. + +my @path_ext = (); + +if (WIN32) { + if ($ENV{PATHEXT}) { + push @path_ext, split ';', $ENV{PATHEXT}; + for my $ext (@path_ext) { + $ext =~ s/^\.*(.+)$/$1/; + } + } + else { + #Win9X: doesn't have PATHEXT + push @path_ext, qw(com exe bat); + } +} + +sub which { + my $program = shift; + + return undef unless $program; + + my @dirs = File::Spec->path(); + + require Config; + my $perl_bin = $Config::Config{bin} || ''; + push @dirs, $perl_bin if $perl_bin and -d $perl_bin; + + for my $base (map { catfile $_, $program } @dirs) { + if ($ENV{HOME} and not WIN32) { + # only works on Unix, but that's normal: + # on Win32 the shell doesn't have special treatment of '~' + $base =~ s/~/$ENV{HOME}/o; + } + + return $base if -x $base && -f _; + + if (WIN32) { + for my $ext (@path_ext) { + return "$base.$ext" if -x "$base.$ext" && -f _; + } + } + } +} + +sub apxs { + my($self, $q, $ok_fail) = @_; + return unless $self->{APXS}; + my $val; + unless (exists $self->{_apxs}{$q}) { + local @ENV{ qw(IFS CDPATH ENV BASH_ENV) }; + local $ENV{PATH} = untaint_path($ENV{PATH}); + my $devnull = devnull(); + my $apxs = shell_ready($self->{APXS}); + $val = qx($apxs -q $q 2>$devnull); + chomp $val if defined $val; # apxs post-2.0.40 adds a new line + if ($val) { + $self->{_apxs}{$q} = $val; + } + unless ($val) { + if ($ok_fail) { + return ""; + } + else { + warn "APXS ($self->{APXS}) query for $q failed\n"; + return $val; + } + } + } + $self->{_apxs}{$q}; +} + +# return an untainted PATH +sub untaint_path { + my $path = shift; + return '' unless defined $path; + ($path) = ( $path =~ /(.*)/ ); + # win32 uses ';' for a path separator, assume others use ':' + my $sep = WIN32 ? ';' : ':'; + # -T disallows relative and empty directories in the PATH + return join $sep, grep File::Spec->file_name_is_absolute($_), + grep length($_), split /$sep/, $path; +} + +sub pop_dir { + my $dir = shift; + + my @chunks = splitdir $dir; + while (my $remove = shift) { + pop @chunks if $chunks[-1] eq $remove; + } + + catfile @chunks; +} + +sub add_inc { + my $self = shift; + return if $ENV{MOD_PERL}; #already setup by mod_perl + require lib; + # make sure that Apache-Test/lib will be first in @INC, + # followed by modperl-2.0/lib (or some other project's lib/), + # followed by blib/ and finally system-wide libs. + my $top_dir = $self->{vars}->{top_dir}; + my @dirs = map { catdir $top_dir, "blib", $_ } qw(lib arch); + + my $apache_test_dir = catdir $top_dir, "Apache-Test"; + unshift @dirs, $apache_test_dir if -d $apache_test_dir; + + lib::->import(@dirs); + + if ($ENV{APACHE_TEST_LIVE_DEV}) { + # add lib/ in a separate call to ensure that it'll end up on + # top of @INC + my $lib_dir = catdir $top_dir, "lib"; + lib::->import($lib_dir) if -d $lib_dir; + } + + #print join "\n", "add_inc", @INC, ""; +} + +#freeze/thaw so other processes can access config + +sub thaw { + my $class = shift; + $class->new({thaw => 1, @_}); +} + +sub freeze { + require Data::Dumper; + local $Data::Dumper::Terse = 1; + my $data = Data::Dumper::Dumper(shift); + chomp $data; + $data; +} + +sub sync_vars { + my $self = shift; + + return if $self->{save}; #this is not a cached config + + my $changed = 0; + my $thaw = $self->thaw; + my $tvars = $thaw->{vars}; + my $svars = $self->{vars}; + + for my $key (@_) { + for my $v ($tvars, $svars) { + if (exists $v->{$key} and not defined $v->{$key}) { + $v->{$key} = ''; #rid undef + } + } + next if exists $tvars->{$key} and exists $svars->{$key} and + $tvars->{$key} eq $svars->{$key}; + $tvars->{$key} = $svars->{$key}; + $changed = 1; + } + + return unless $changed; + + $thaw->{save} = 1; + $thaw->save; +} + +sub save { + my($self) = @_; + + return unless $self->{save}; + + # add in the Apache-Test version for later comparisions + $self->{apache_test_version} = Apache::Test->VERSION; + + my $name = 'apache_test_config'; + my $file = catfile $self->{vars}->{t_conf}, "$name.pm"; + my $fh = $self->genfile($file); + + debug "saving config data to $name.pm"; + + (my $obj = $self->freeze) =~ s/^/ /; + + print $fh <<EOF; +package $name; + +sub new { +$obj; +} + +1; +EOF + + close $fh or die "failed to write $file: $!"; +} + +sub as_string { + my $cfg = ''; + my $command = ''; + + # httpd opts + my $test_config = Apache::TestConfig->new({thaw=>1}); + # XXX: need to run httpd config to get the value of httpd + if (my $httpd = $test_config->{vars}->{httpd}) { + $httpd = shell_ready($httpd); + $command = "$httpd -V"; + $cfg .= "\n*** $command\n"; + $cfg .= qx{$command}; + + $cfg .= ldd_as_string($httpd); + } + else { + $cfg .= "\n\n*** The httpd binary was not found\n"; + } + + # perl opts + my $perl = shell_ready($^X); + $command = "$perl -V"; + $cfg .= "\n\n*** $command\n"; + $cfg .= qx{$command}; + + return $cfg; +} + +sub ldd_as_string { + my $httpd = shift; + + my $command; + if (OSX) { + my $otool = which('otool'); + $command = "$otool -L $httpd" if $otool; + } + elsif (!WIN32) { + my $ldd = which('ldd'); + $command = "$ldd $httpd" if $ldd; + } + + my $cfg = ''; + if ($command) { + $cfg .= "\n*** $command\n"; + $cfg .= qx{$command}; + } + + return $cfg; +} + +# make a string suitable for feed to shell calls (wrap in quotes and +# escape quotes) +sub shell_ready { + my $arg = shift; + $arg =~ s!\\?"!\\"!g; + return qq["$arg"]; +} + + +1; + +=head1 NAME + +Apache::TestConfig -- Test Configuration setup module + +=head1 SYNOPSIS + + use Apache::TestConfig; + + my $cfg = Apache::TestConfig->new(%args) + my $fh = $cfg->genfile($file); + $cfg->writefile($file, $content); + $cfg->gendir($dir); + ... + +=head1 DESCRIPTION + +C<Apache::TestConfig> is used in creating the C<Apache::Test> +configuration files. + +=head1 FUNCTIONS + +=over + +=item genwarning() + + my $warn = $cfg->genwarning($filename) + +genwarning() returns a warning string as a comment, saying that the +file was autogenerated and that it's not a good idea to modify this +file. After the warning a perl trace of calls to this this function is +appended. This trace is useful for finding what code has created the +file. + + my $warn = $cfg->genwarning($filename, $from_filename) + +If C<$from_filename> is specified it'll be used in the warning to tell +which file it was generated from. + +genwarning() automatically recognizes the comment type based on the +file extension. If the extension is not recognized, the default C<#> +style is used. + +Currently it support C<E<lt>!-- --E<gt>>, C</* ... */> and C<#> +styles. + +=item genfile() + + my $fh = $cfg->genfile($file); + +genfile() creates a new file C<$file> for writing and returns a file +handle. + +If parent directories of C<$file> don't exist they will be +automagically created. + +The file C<$file> and any created parent directories (if found empty) +will be automatically removed on cleanup. + +A comment with a warning and calls trace is added to the top of this +file. See genwarning() for more info about this comment. + + my $fh = $cfg->genfile($file, $from_file); + +If C<$from_filename> is specified it'll be used in the warning to tell +which file it was generated from. + + my $fh = $cfg->genfile($file, $from_file, $nowarning); + +If C<$nowarning> is true, the warning won't be added. If using this +optional argument and there is no C<$from_file> you must pass undef as +in: + + my $fh = $cfg->genfile($file, undef, $nowarning); + + +=item writefile() + + $cfg->writefile($file, $content, [$nowarning]); + +writefile() creates a new file C<$file> with the content of +C<$content>. + +A comment with a warning and calls trace is added to the top of this +file unless C<$nowarnings> is passed and set to a true value. See +genwarning() for more info about this comment. + +If parent directories of C<$file> don't exist they will be +automagically created. + +The file C<$file> and any created parent directories (if found empty) +will be automatically removed on cleanup. + +=item write_perlscript() + + $cfg->write_perlscript($filename, @lines); + +Similar to writefile() but creates an executable Perl script with +correctly set shebang line. + +=item gendir() + + $cfg->gendir($dir); + +gendir() creates a new directory C<$dir>. + +If parent directories of C<$dir> don't exist they will be +automagically created. + +The directory C<$dir> and any created parent directories will be +automatically removed on cleanup if found empty. + +=back + +=head1 Environment Variables + +The following environment variables affect the configuration and the +run-time of the C<Apache::Test> framework: + +=head2 APACHE_TEST_COLOR + +To aid visual control over the configuration process and the run-time +phase, C<Apache::Test> uses coloured fonts when the environment +variable C<APACHE_TEST_COLOR> is set to a true value. + +=head2 APACHE_TEST_LIVE_DEV + +When using C<Apache::Test> during the project development phase, it's +often convenient to have the I<project/lib> (live) directory appearing +first in C<@INC> so any changes to the Perl modules, residing in it, +immediately affect the server, without a need to rerun C<make> to +update I<blib/lib>. When the environment variable +C<APACHE_TEST_LIVE_DEV> is set to a true value during the +configuration phase (C<t/TEST -config>, C<Apache::Test> will +automatically unshift the I<project/lib> directory into C<@INC>, via +the autogenerated I<t/conf/modperl_inc.pl> file. + + +=head1 Special Placeholders + +When generating configuration files from the I<*.in> templates, +special placeholder variables get substituted. To embed a placeholder +use the C<@foo@> syntax. For example in I<extra.conf.in> you can +write: + + Include @ServerRoot@/conf/myconfig.conf + +When I<extra.conf> is generated, C<@ServerRoot@> will get replaced +with the location of the server root. + +Placeholders are case-insensitive. + +Available placeholders: + +=head2 Configuration Options + +All configuration variables that can be passed to C<t/TEST>, such as +C<MaxClients>, C<DocumentRoot>, C<ServerRoot>, etc. To see the +complete list run: + + % t/TEST --help + +and you will find them in the C<configuration options> sections. + +=head2 NextAvailablePort + +Every time this placeholder is encountered it'll be replaced with the +next available port. This is very useful if you need to allocate a +special port, but not hardcode it. Later when running: + + % t/TEST -port=select + +it's possible to run several concurrent test suites on the same +machine, w/o having port collisions. + +=head1 AUTHOR + +=head1 SEE ALSO + +perl(1), Apache::Test(3) + +=cut + + +__DATA__ +Listen 0.0.0.0:@Port@ + +ServerRoot "@ServerRoot@" +DocumentRoot "@DocumentRoot@" + +PidFile @t_pid_file@ +ErrorLog @t_logs@/error_log +LogLevel debug + +<IfModule mod_version.c> +<IfVersion > 2.4.1> + DefaultRunTimeDir "@t_logs@" + LogLevel trace8 +</IfVersion> +<IfVersion > 2.4.34> +<IfDirective DefaultStateDir> + DefaultStateDir "@t_state@" +</IfDirective> +</IfVersion> +</IfModule> + +<IfModule mod_log_config.c> + TransferLog @t_logs@/access_log +</IfModule> + +<IfModule mod_cgid.c> + ScriptSock @t_logs@/cgisock +</IfModule> + +ServerAdmin @ServerAdmin@ + +#needed for http/1.1 testing +KeepAlive On + +HostnameLookups Off + +<Directory /> + Options FollowSymLinks + AllowOverride None +</Directory> + +<IfModule @THREAD_MODULE@> +<IfModule mod_version.c> +<IfVersion < 2.3.4> + LockFile @t_logs@/accept.lock +</IfVersion> +</IfModule> + StartServers @StartServersThreadedMPM@ + MinSpareThreads @ThreadsPerChild@ + MaxSpareThreads @MaxSpareThreadedMPM@ + ThreadsPerChild @ThreadsPerChild@ + MaxClients @MaxClientsThreadedMPM@ + MaxRequestsPerChild 0 +</IfModule> + +<IfModule perchild.c> +<IfModule mod_version.c> +<IfVersion < 2.3.4> + LockFile @t_logs@/accept.lock +</IfVersion> +</IfModule> + NumServers 1 + StartThreads @MinClients@ + MinSpareThreads 1 + MaxSpareThreads @MaxSpare@ + MaxThreadsPerChild @MaxClients@ + MaxRequestsPerChild 0 +</IfModule> + +<IfModule prefork.c> +<IfModule mod_version.c> +<IfVersion < 2.3.4> + LockFile @t_logs@/accept.lock +</IfVersion> +</IfModule> + StartServers @MinClients@ + MinSpareServers 1 + MaxSpareServers @MaxSpare@ + MaxClients @MaxClients@ + MaxRequestsPerChild 0 +</IfModule> + +<IfDefine APACHE1> + LockFile @t_logs@/accept.lock + StartServers @MinClients@ + MinSpareServers 1 + MaxSpareServers @MaxSpare@ + MaxClients @MaxClients@ + MaxRequestsPerChild 0 +</IfDefine> + +<IfModule mpm_winnt.c> + ThreadsPerChild 50 + MaxRequestsPerChild 0 +</IfModule> + +<Location /server-info> + SetHandler server-info +</Location> + +<Location /server-status> + SetHandler server-status +</Location> + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigC.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigC.pm new file mode 100644 index 0000000..c9d8fd1 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigC.pm @@ -0,0 +1,492 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestConfig; #not TestConfigC on purpose + +use strict; +use warnings FATAL => 'all'; + +use Config; +use Apache::TestConfig (); +use Apache::TestConfigPerl (); +use Apache::TestTrace; +use File::Find qw(finddepth); + +sub cmodule_find { + my($self, $mod) = @_; + + return unless $mod =~ /^mod_(\w+)\.c$/; + my $sym = $1; + + my $dir = $File::Find::dir; + my $file = catfile $dir, $mod; + + unless ($self->{APXS}) { + $self->{cmodules_disabled}->{$mod} = "no apxs configured"; + return; + } + + my $fh = Symbol::gensym(); + open $fh, $file or die "open $file: $!"; + my $v = <$fh>; + if ($v =~ /^\#define\s+HTTPD_TEST_REQUIRE_APACHE\s+(\d+)\s*$/) { + #define HTTPD_TEST_REQUIRE_APACHE 1 + unless ($self->{server}->{rev} == $1) { + my $reason = "requires Apache version $1"; + $self->{cmodules_disabled}->{$mod} = $reason; + notice "$mod $reason, skipping."; + return; + } + } + elsif ($v =~ /^\#define\s+HTTPD_TEST_REQUIRE_APACHE\s+(\d\.\d+(\.\d+)?)/) { + #define HTTPD_TEST_REQUIRE_APACHE 2.1 + my $wanted = $1; + (my $current) = $self->{server}->{version} =~ m:^Apache/(\d\.\d+\.\d+):; + + if (Apache::Test::normalize_vstring($current) < + Apache::Test::normalize_vstring($wanted)) { + my $reason = "requires Apache version $wanted"; + $self->{cmodules_disabled}->{$mod} = $reason; + notice "$mod $reason, skipping."; + return; + } + } + close $fh; + + push @{ $self->{cmodules} }, { + name => "mod_$sym", + sym => "${sym}_module", + dir => $dir, + subdir => basename $dir, + }; +} + +sub cmodules_configure { + my($self, $dir) = @_; + + $self->{cmodules_disabled} = {}; #for have_module to check + + $dir ||= catfile $self->{vars}->{top_dir}, 'c-modules'; + + unless (-d $dir) { + return; + } + + $self->{cmodules_dir} = $dir; + + finddepth(sub { cmodule_find($self, $_) }, $dir); + + unless ($self->{APXS}) { + warning "cannot build c-modules without apxs"; + return; + } + + $self->cmodules_generate_include; + $self->cmodules_write_makefiles; + $self->cmodules_compile; + $self->cmodules_httpd_conf; +} + +sub cmodules_makefile_vars { + return <<EOF; +MAKE = $Config{make} +EOF +} + +my %lib_dir = Apache::TestConfig::WIN32 + ? (1 => "", 2 => "") + : (1 => "", 2 => ".libs/"); + +sub cmodules_build_so { + my($self, $name) = @_; + $name = "mod_$name" unless $name =~ /^mod_/; + my $libdir = $self->server->version_of(\%lib_dir); + my $lib = "$libdir$name.so"; +} + +sub cmodules_write_makefiles { + my $self = shift; + + my $modules = $self->{cmodules}; + + for (@$modules) { + $self->cmodules_write_makefile($_); + } + + my $file = catfile $self->{cmodules_dir}, 'Makefile'; + my $fh = $self->genfile($file); + + print $fh $self->cmodules_makefile_vars; + + my @dirs = map { $_->{subdir} } @$modules; + + my @targets = qw(clean); + my @libs; + + for my $dir (@dirs) { + for my $targ (@targets) { + print $fh "$dir-$targ:\n\tcd $dir && \$(MAKE) $targ\n\n"; + } + + my $lib = $self->cmodules_build_so($dir); + my $cfile = "$dir/mod_$dir.c"; + push @libs, "$dir/$lib"; + print $fh "$libs[-1]: $cfile\n\tcd $dir && \$(MAKE) $lib\n\n"; + } + + for my $targ (@targets) { + print $fh "$targ: ", (map { "$_-$targ " } @dirs), "\n\n"; + } + + print $fh "all: @libs\n\n"; + + close $fh or die "close $file: $!"; +} + +sub cmodules_write_makefile { + my ($self, $mod) = @_; + my $write = \&{"cmodules_write_makefile_$^O"}; + $write = \&cmodules_write_makefile_default unless defined &$write; + $write->($self, $mod); +} + +sub cmodules_write_makefile_default { + my($self, $mod) = @_; + + my $dversion = $self->server->dversion; + my $name = $mod->{name}; + my $makefile = catfile $mod->{dir}, 'Makefile'; + + my $extra = $ENV{EXTRA_CFLAGS} || ''; + + debug "writing $makefile"; + + my $lib = $self->cmodules_build_so($name); + + my $fh = $self->genfile($makefile); + + print $fh <<EOF; +APXS=$self->{APXS} +all: $lib + +$lib: $name.c + \$(APXS) $dversion $extra -I$self->{cmodules_dir} -c $name.c + +clean: + -rm -rf $name.o $name.lo $name.slo $name.la $name.i $name.s $name.gcno .libs +EOF + + close $fh or die "close $makefile: $!"; +} + +sub cmodules_write_makefile_aix { + my($self, $mod) = @_; + + my $dversion = $self->server->dversion; + my $name = $mod->{name}; + my $makefile = catfile $mod->{dir}, 'Makefile'; + my $apxsflags = ''; + + # + # Only do this for Apache 1.* + # + if ($self->server->{rev} == 1) { + $apxsflags = "-Wl,-bE:$name.exp"; + my $expfile = catfile $mod->{dir}, "$name.exp"; + if (! -f $expfile) { + my $fh = Symbol::gensym(); + $name =~ /^mod_(\w+)(?:\.c)?$/; + my $sym = $1 . '_module'; + open $fh, ">$expfile" or die "open $expfile: $!"; + print $fh "$sym\n"; + close $fh; + } + } + + my $extra = $ENV{EXTRA_CFLAGS} || ''; + + debug "writing $makefile"; + + my $lib = $self->cmodules_build_so($name); + + my $fh = Symbol::gensym(); + open $fh, ">$makefile" or die "open $makefile: $!"; + + print $fh <<EOF; +APXS=$self->{APXS} +APXSFLAGS=$apxsflags +all: $lib + +$lib: $name.c + \$(APXS) $dversion $extra -I$self->{cmodules_dir} \$(APXSFLAGS) -c $name.c + +clean: + -rm -rf $name.o $name.lo $name.slo $name.la .libs +EOF + + close $fh or die "close $makefile: $!"; +} + +sub cmodules_write_makefile_MSWin32 { + my($self, $mod) = @_; + + my $dversion = $self->server->dversion; + my $name = $mod->{name}; + my $makefile = "$mod->{dir}/Makefile"; + debug "writing $makefile"; + my $extras = ''; + + my $lib = $self->cmodules_build_so($name); + $extras = ' -llibhttpd -p ' if ($self->server->{rev} != 1); + my $goners = join ' ', (map {$name . '.' . $_} qw(exp lib so lo)); + + my $fh = Symbol::gensym(); + open $fh, ">$makefile" or die "open $makefile: $!"; + + my $extra = $ENV{EXTRA_CFLAGS} || ''; + + debug "writing $makefile"; + + print $fh <<EOF; +APXS=$self->{APXS} +all: $lib + +$lib: $name.c + \$(APXS) $dversion $extra -I$self->{cmodules_dir} $extras -c $name.c + +clean: + -erase $goners +EOF + + close $fh or die "close $makefile: $!"; +} + +sub cmodules_make { + my $self = shift; + my $targ = shift || 'all'; + + my $cmd = "cd $self->{cmodules_dir} && $Config{make} $targ"; + debug $cmd; + system $cmd; + if ($?) { + die "Failed to build c-modules"; + } +} + +sub cmodules_compile { + shift->cmodules_make('all'); +} + +sub cmodules_httpd_conf { + my $self = shift; + + my @args; + + for my $mod (@{ $self->{cmodules} }) { + my $dir = $mod->{dir}; + my $lib = $self->cmodules_build_so($mod->{name}); + my $so = "$dir/$lib"; + + next unless -e $so; + + $self->preamble(LoadModule => "$mod->{sym} $so"); + + my $cname = "$mod->{name}.c"; + my $cfile = "$dir/$cname"; + $self->{modules}->{$cname} = 1; + + $self->add_module_config($cfile, \@args); + } + + $self->postamble(\@args) if @args; +} + +sub cmodules_clean { + my $self = shift; + + my $dir = $self->{cmodules_dir}; + return unless $dir and -e "$dir/Makefile"; + + unless ($self->{clean_level} > 1) { + #skip t/TEST -conf + warning "skipping rebuild of c-modules; run t/TEST -clean to force"; + return; + } + + $self->cmodules_make('clean'); + + for my $mod (@{ $self->{cmodules} }) { + my $makefile = "$mod->{dir}/Makefile"; + debug "unlink $makefile"; + unlink $makefile; + } + + unlink "$dir/Makefile"; +} + +#try making it easier for test modules to compile with both 1.x and 2.x +sub cmodule_define_name { + my $name = shift; + $name eq 'NULL' ? $name : "APACHE_HTTPD_TEST_\U$name"; +} + +sub cmodule_define { + my $hook = cmodule_define_name(@_); + "#ifndef $hook\n#define $hook NULL\n#endif\n"; +} + +my @cmodule_config_names = qw(per_dir_create per_dir_merge + per_srv_create per_srv_merge + commands); + +my @cmodule_config_defines = map { + cmodule_define($_); +} @cmodule_config_names; + +my $cmodule_config_extra = + "#ifndef APACHE_HTTPD_TEST_EXTRA_HOOKS\n". + "#define APACHE_HTTPD_TEST_EXTRA_HOOKS(p) do { } while (0)\n". + "#endif\n"; + +my $cmodule_config_hooks = join ",\n ", map { + cmodule_define_name($_); +} @cmodule_config_names; + +my @cmodule_phases = qw(post_read_request translate_name header_parser + access_checker check_user_id auth_checker + type_checker fixups handler log_transaction + child_init); + +my $cmodule_hooks_1 = join ",\n ", map { + cmodule_define_name($_); +} qw(translate_name check_user_id auth_checker access_checker + type_checker fixups log_transaction header_parser + child_init NULL post_read_request); + +my $cmodule_template_1 = <<"EOF", +static const handler_rec name ## _handlers[] = +{ + {#name, APACHE_HTTPD_TEST_HANDLER}, /* ok if handler is NULL */ + {NULL} +}; + +module MODULE_VAR_EXPORT name ## _module = +{ + STANDARD_MODULE_STUFF, + NULL, /* initializer */ + $cmodule_config_hooks, + name ## _handlers, /* handlers */ + $cmodule_hooks_1 +} +EOF + +my @cmodule_hooks = map { + my $hook = cmodule_define_name($_); + <<EOF; + if ($hook != NULL) + ap_hook_$_($hook, + NULL, NULL, + APACHE_HTTPD_TEST_HOOK_ORDER); +EOF +} @cmodule_phases; + +my @cmodule_hook_defines = map { + cmodule_define($_); +} @cmodule_phases; + +my $cmodule_template_2 = <<"EOF"; +static void name ## _register_hooks(apr_pool_t *p) +{ +@cmodule_hooks + APACHE_HTTPD_TEST_EXTRA_HOOKS(p); +} + +module AP_MODULE_DECLARE_DATA name ## _module = { + STANDARD20_MODULE_STUFF, + $cmodule_config_hooks, + name ## _register_hooks, /* register hooks */ +} +EOF + +my %cmodule_templates = (1 => $cmodule_template_1, 2 => $cmodule_template_2); + +sub cmodules_module_template { + my $self = shift; + my $template = $self->server->version_of(\%cmodule_templates); + chomp $template; + + $template =~ s,$, \\,mg; + $template =~ s, \\$,,s; + + local $" = ', '; + + return <<EOF; +#define APACHE_HTTPD_TEST_MODULE(name) \\ + $template +EOF +} + +sub cmodules_generate_include { + my $self = shift; + + my $file = "$self->{cmodules_dir}/apache_httpd_test.h"; + my $fh = $self->genfile($file); + + while (read Apache::TestConfigC::DATA, my $buf, 1024) { + print $fh $buf; + } + + print $fh @cmodule_hook_defines, @cmodule_config_defines; + + print $fh $cmodule_config_extra; + + print $fh $self->cmodules_module_template; + + close $fh; +} + +package Apache::TestConfigC; #Apache/TestConfig.pm also has __DATA__ +1; +__DATA__ +#ifndef APACHE_HTTPD_TEST_H +#define APACHE_HTTPD_TEST_H + +/* headers present in both 1.x and 2.x */ +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "http_main.h" +#include "http_core.h" +#include "ap_config.h" + +#ifdef APACHE1 +#define AP_METHOD_BIT 1 +typedef size_t apr_size_t; +typedef array_header apr_array_header_t; +#define APR_OFF_T_FMT "ld" +#define APR_SIZE_T_FMT "lu" +#endif /* APACHE1 */ + +#ifdef APACHE2 +#ifndef APACHE_HTTPD_TEST_HOOK_ORDER +#define APACHE_HTTPD_TEST_HOOK_ORDER APR_HOOK_MIDDLE +#endif +#include "ap_compat.h" +#endif /* APACHE2 */ + +#endif /* APACHE_HTTPD_TEST_H */ + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigPHP.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigPHP.pm new file mode 100644 index 0000000..1c79865 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigPHP.pm @@ -0,0 +1,781 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestConfigPHP; + +#things specific to php + +use strict; +use warnings FATAL => 'all'; +use File::Spec::Functions qw(catfile splitdir abs2rel); +use File::Find qw(finddepth); +use Apache::TestTrace; +use Apache::TestRequest; +use Apache::TestConfig; +use Apache::TestConfigPerl; +use Config; + +@Apache::TestConfigPHP::ISA = qw(Apache::TestConfig); + +my ($php_ini, $test_more); + +{ + # __DATA__ contains both php.ini and test-more.php + + local $/ = "END_OF_FILE\n"; + + $php_ini = <DATA>; + chomp $php_ini; + + $test_more = <DATA>; + chomp $test_more; +} + +sub new { + return shift->SUPER::new(@_); +} + +my %warn_style = ( + html => sub { "<!-- @_ -->" }, + c => sub { "/* @_ */" }, + ini => sub { join '', grep {s/^/; /gm} @_ }, + php => sub { join '', "<?php\n", grep {s/^/# /gm} @_ }, + default => sub { join '', grep {s/^/\# /gm} @_ }, +); + +my %file_ext = ( + map({$_ => 'html'} qw(htm html)), + map({$_ => 'c' } qw(c h)), + map({$_ => 'ini' } qw(ini)), + map({$_ => 'php' } qw(php)), +); + +sub warn_style_sub_ref { + my ($self, $filename) = @_; + my $ext = $self->filename_ext($filename); + return $warn_style{ $file_ext{$ext} || 'default' }; +} + +sub configure_php_tests_pick { + my($self, $entries) = @_; + + for my $subdir (qw(Response)) { + my $dir = catfile $self->{vars}->{t_dir}, lc $subdir; + next unless -d $dir; + + finddepth(sub { + return unless /\.php$/; + + my $file = catfile $File::Find::dir, $_; + my $module = abs2rel $file, $dir; + my $status = $self->run_apache_test_config_scan($file); + push @$entries, [$file, $module, $subdir, $status]; + }, $dir); + } +} + +sub write_php_test { + my($self, $location, $test) = @_; + + (my $path = $location) =~ s/test//i; + (my $file = $test) =~ s/php$/t/i; + + my $dir = catfile $self->{vars}->{t_dir}, lc $path; + my $t = catfile $dir, $file; + my $php_t = catfile $dir, $test; + return if -e $t; + + # don't write out foo.t if foo.php already exists + return if -e $php_t; + + $self->gendir($dir); + my $fh = $self->genfile($t); + + print $fh <<EOF; +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/$location/$test"; +EOF + + close $fh or die "close $t: $!"; + + # write out an all.t file for the directory + # that will skip running all PHP test unless have_php + + my $all = catfile $dir, 'all.t'; + + unless (-e $all) { + my $fh = $self->genfile($all); + + print $fh <<EOF; +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +# skip all tests in this directory unless a php module is enabled +plan tests => 1, need_php; + +ok 1; +EOF + } +} + +sub configure_php_inc { + my $self = shift; + + my $serverroot = $self->{vars}->{serverroot}; + + my $path = catfile $serverroot, 'conf'; + + # make sure that require() or include() calls can find + # the generated test-more.php without using absolute paths + my $cfg = { php_value => "include_path $path", }; + $self->postamble(IfModule => $self->{vars}->{php_module}, $cfg); + + # give test-more.php access to the ServerRoot directive + $self->postamble("SetEnv SERVER_ROOT $serverroot\n"); +} + +sub configure_php_functions { + my $self = shift; + + my $dir = catfile $self->{vars}->{serverroot}, 'conf'; + my $file = catfile $dir, 'test-more.php'; + + $self->gendir($dir); + my $fh = $self->genfile($file); + + print $fh $test_more; + + close $fh or die "close $file: $!"; + + $self->clean_add_file($file); +} + +sub configure_php_ini { + my $self = shift; + + my $dir = catfile $self->{vars}->{serverroot}, 'conf'; + my $file = catfile $dir, 'php.ini'; + + return if -e $file; + + my $log = catfile $self->{vars}->{t_logs}, 'error_log'; + + $self->gendir($dir); + my $fh = $self->genfile($file); + + $php_ini =~ s/\@error_log\@/error_log $log/; + print $fh $php_ini; + + close $fh or die "close $file: $!"; + + $self->clean_add_file($file); +} + +sub configure_php_tests { + my $self = shift; + + my @entries = (); + $self->configure_php_tests_pick(\@entries); + $self->configure_pm_tests_sort(\@entries); + + my %seen = (); + + for my $entry (@entries) { + my ($file, $module, $subdir, $status) = @$entry; + + my @args = (); + + my $directives = $self->add_module_config($file, \@args); + + my @parts = splitdir $file; + my $test = pop @parts; + my $location = $parts[-1]; + + debug "configuring PHP test file $file"; + + if ($directives->{noautoconfig}) { + $self->postamble(""); # which adds "\n" + } + else { + unless ($seen{$location}++) { + $self->postamble(Alias => [ catfile('', $parts[-1]), catfile(@parts) ]); + + my @args = (AddType => 'application/x-httpd-php .php'); + + $self->postamble(Location => "/$location", \@args); + } + } + + $self->write_php_test($location, $test); + } +} + +1; + +__DATA__ +; This is php.ini-recommended from php 5.0.2, +; used in place of your locally installed php.ini file +; as part of the pristine environment Apache-Test creates +; for you +; [NOTE]: cat php.ini-recommended | grep -v '^;' | sed -e '/^$/d' +; +; exceptions to php.ini-recommended are as follows: +display_startup_errors = On +html_errors = Off +@error_log@ +output_buffering = Off + +; the rest of php.ini-recommended, unaltered, save for +; some tidying like the removal of comments and blank lines + +[PHP] +engine = On +zend.ze1_compatibility_mode = Off +short_open_tag = Off +asp_tags = Off +precision = 14 +y2k_compliance = On +zlib.output_compression = Off +implicit_flush = Off +unserialize_callback_func= +serialize_precision = 100 +allow_call_time_pass_reference = Off +safe_mode = Off +safe_mode_gid = Off +safe_mode_include_dir = +safe_mode_exec_dir = +safe_mode_allowed_env_vars = PHP_ +safe_mode_protected_env_vars = LD_LIBRARY_PATH +disable_functions = +disable_classes = +expose_php = On +max_execution_time = 30 ; Maximum execution time of each script, in seconds +max_input_time = 60 ; Maximum amount of time each script may spend parsing request data +memory_limit = 128M ; Maximum amount of memory a script may consume (128MB) +error_reporting = E_ALL +display_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +track_errors = Off +variables_order = "GPCS" +register_globals = Off +register_long_arrays = Off +register_argc_argv = Off +auto_globals_jit = On +post_max_size = 8M +magic_quotes_gpc = Off +magic_quotes_runtime = Off +magic_quotes_sybase = Off +auto_prepend_file = +auto_append_file = +default_mimetype = "text/html" +doc_root = +user_dir = +enable_dl = On +file_uploads = On +upload_max_filesize = 2M +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 +[Date] +[filter] +[iconv] +[sqlite] +[xmlrpc] +[Pcre] +[Syslog] +define_syslog_variables = Off +[mail function] +SMTP = localhost +smtp_port = 25 +[SQL] +sql.safe_mode = Off +[ODBC] +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 +[MySQL] +mysql.allow_persistent = On +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 60 +mysql.trace_mode = Off +[MySQLi] +mysqli.max_links = -1 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off +[mSQL] +msql.allow_persistent = On +msql.max_persistent = -1 +msql.max_links = -1 +[OCI8] +[PostgresSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 +[Sybase] +sybase.allow_persistent = On +sybase.max_persistent = -1 +sybase.max_links = -1 +sybase.min_error_severity = 10 +sybase.min_message_severity = 10 +sybase.compatability_mode = Off +[Sybase-CT] +sybct.allow_persistent = On +sybct.max_persistent = -1 +sybct.max_links = -1 +sybct.min_server_severity = 10 +sybct.min_client_severity = 10 +[bcmath] +bcmath.scale = 0 +[browscap] +[Informix] +ifx.default_host = +ifx.default_user = +ifx.default_password = +ifx.allow_persistent = On +ifx.max_persistent = -1 +ifx.max_links = -1 +ifx.textasvarchar = 0 +ifx.byteasvarchar = 0 +ifx.charasvarchar = 0 +ifx.blobinfile = 0 +ifx.nullformat = 0 +[Session] +session.save_handler = files +session.use_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 +session.cookie_lifetime = 0 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = +session.serialize_handler = php +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.bug_compat_42 = 0 +session.bug_compat_warn = 1 +session.referer_check = +session.entropy_length = 0 +session.entropy_file = +session.cache_limiter = nocache +session.cache_expire = 180 +session.use_trans_sid = 0 +session.hash_function = 0 +session.hash_bits_per_character = 5 +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" +[MSSQL] +mssql.allow_persistent = On +mssql.max_persistent = -1 +mssql.max_links = -1 +mssql.min_error_severity = 10 +mssql.min_message_severity = 10 +mssql.compatability_mode = Off +mssql.secure_connection = Off +[Assertion] +[COM] +[mbstring] +[FrontBase] +[gd] +[exif] +[Tidy] +tidy.clean_output = Off +[soap] +soap.wsdl_cache_enabled=1 +soap.wsdl_cache_dir="/tmp" +soap.wsdl_cache_ttl=86400 +END_OF_FILE +/*******************************************************************\ +* PROJECT INFORMATION * +* * +* Project: Apache-Test * +* URL: http://perl.apache.org/Apache-Test/ * +* Notice: Copyright (c) 2006 The Apache Software Foundation * +* * +********************************************************************* +* LICENSE INFORMATION * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the * +* License. You may obtain a copy of the License at: * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, * +* software distributed under the License is distributed on an "AS * +* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * +* express or implied. See the License for the specific language * +* governing permissions and limitations under the License. * +* * +********************************************************************* +* MODULE INFORMATION * +* * +* This is a PHP implementation of Test::More: * +* * +* http://search.cpan.org/dist/Test-Simple/lib/Test/More.pm * +* * +********************************************************************* +* CREDITS * +* * +* Originally inspired by work from Andy Lester. Written and * +* maintained by Chris Shiflett. For contact information, see: * +* * +* http://shiflett.org/ * +* * +\*******************************************************************/ + +header('Content-Type: text/plain'); +register_shutdown_function('_test_end'); + +$_no_plan = FALSE; +$_num_failures = 0; +$_num_skips = 0; +$_test_num = 0; + +function plan($plan) +{ + /* + plan('no_plan'); + plan('skip_all'); + plan(array('skip_all' => 'My reason is...')); + plan(23); + */ + + global $_no_plan; + global $_skip_all; + global $_skip_reason; + + switch ($plan) + { + case 'no_plan': + $_no_plan = TRUE; + break; + + case 'skip_all': + echo "1..0\n"; + break; + + default: + if (is_array($plan)) + { + echo "1..0 # Skip {$plan['skip_all']}\n"; + exit; + } + + echo "1..$plan\n"; + break; + } +} + +function ok($pass, $test_name = '') +{ + global $_test_num; + global $_num_failures; + global $_num_skips; + + $_test_num++; + + if ($_num_skips) + { + $_num_skips--; + return TRUE; + } + + if (!empty($test_name) && $test_name[0] != '#') + { + $test_name = "- $test_name"; + } + + if ($pass) + { + echo "ok $_test_num $test_name\n"; + } + else + { + echo "not ok $_test_num $test_name\n"; + + $_num_failures++; + $caller = debug_backtrace(); + + if (strstr($caller['0']['file'], $_SERVER['PHP_SELF'])) + { + $file = $caller['0']['file']; + $line = $caller['0']['line']; + } + else + { + $file = $caller['1']['file']; + $line = $caller['1']['line']; + } + + $file = str_replace($_SERVER['SERVER_ROOT'], 't', $file); + + diag(" Failed test ($file at line $line)"); + } + + return $pass; +} + +function is($this, $that, $test_name = '') +{ + $pass = ($this == $that); + + ok($pass, $test_name); + + if (!$pass) + { + diag(" got: '$this'"); + diag(" expected: '$that'"); + } + + return $pass; +} + +function isnt($this, $that, $test_name = '') +{ + $pass = ($this != $that); + + ok($pass, $test_name); + + if (!$pass) + { + diag(" '$this'"); + diag(' !='); + diag(" '$that'"); + } + + return $pass; +} + +function like($string, $pattern, $test_name = '') +{ + $pass = preg_match($pattern, $string); + + ok($pass, $test_name); + + if (!$pass) + { + diag(" '$string'"); + diag(" doesn't match '$pattern'"); + } + + return $pass; +} + +function unlike($string, $pattern, $test_name = '') +{ + $pass = !preg_match($pattern, $string); + + ok($pass, $test_name); + + if (!$pass) + { + diag(" '$string'"); + diag(" matches '$pattern'"); + } + + return $pass; +} + +function cmp_ok($this, $operator, $that, $test_name = '') +{ + eval("\$pass = (\$this $operator \$that);"); + + ok($pass, $test_name); + + if (!$pass) + { + diag(" got: '$this'"); + diag(" expected: '$that'"); + } + + return $pass; +} + +function can_ok($object, $methods) +{ + $pass = TRUE; + $errors = array(); + + foreach ($methods as $method) + { + if (!method_exists($object, $method)) + { + $pass = FALSE; + $errors[] = " method_exists(\$object, $method) failed"; + } + } + + if ($pass) + { + ok(TRUE, "method_exists(\$object, ...)"); + } + else + { + ok(FALSE, "method_exists(\$object, ...)"); + diag($errors); + } + + return $pass; +} + +function isa_ok($object, $expected_class, $object_name = 'The object') +{ + $got_class = get_class($object); + + if (version_compare(php_version(), '5', '>=')) + { + $pass = ($got_class == $expected_class); + } + else + { + $pass = ($got_class == strtolower($expected_class)); + } + + if ($pass) + { + ok(TRUE, "$object_name isa $expected_class"); + } + else + { + ok(FALSE, "$object_name isn't a '$expected_class' it's a '$got_class'"); + } + + return $pass; +} + +function pass($test_name = '') +{ + return ok(TRUE, $test_name); +} + +function fail($test_name = '') +{ + return ok(FALSE, $test_name); +} + +function diag($message) +{ + if (is_array($message)) + { + foreach($message as $current) + { + echo "# $current\n"; + } + } + else + { + echo "# $message\n"; + } +} + +function include_ok($module) +{ + $pass = ((include $module) == 'OK'); + return ok($pass); +} + +function require_ok($module) +{ + $pass = ((require $module) == 'OK'); + return ok($pass); +} + +function skip($message, $num) +{ + global $_num_skips; + + if ($num < 0) + { + $num = 0; + } + + for ($i = 0; $i < $num; $i++) + { + pass("# SKIP $message"); + } + + $_num_skips = $num; +} + +/* + +TODO: + +function todo() +{ +} + +function todo_skip() +{ +} + +function is_deeply() +{ +} + +function eq_array() +{ +} + +function eq_hash() +{ +} + +function eq_set() +{ +} + +*/ + +function _test_end() +{ + global $_no_plan; + global $_num_failures; + global $_test_num; + + if ($_no_plan) + { + echo "1..$_test_num\n"; + } + + if ($_num_failures) + { + diag("Looks like you failed $_num_failures tests of $_test_num."); + } +} + +?> diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParrot.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParrot.pm new file mode 100644 index 0000000..e13a7dc --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParrot.pm @@ -0,0 +1,92 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestConfigParrot; + +#things specific to mod_parrot + +use strict; +use warnings FATAL => 'all'; +use File::Spec::Functions qw(catfile splitdir abs2rel); +use File::Find qw(finddepth); +use Apache::TestTrace; +use Apache::TestRequest; +use Apache::TestConfig; +use Apache::TestConfigPerl; +use Config; + +@Apache::TestConfigParrot::ISA = qw(Apache::TestConfig); + +sub new { + return shift->SUPER::new(@_); +} + +sub configure_parrot_tests_pick { + my($self, $entries) = @_; + + for my $subdir (qw(Response)) { + my $dir = catfile $self->{vars}->{t_dir}, lc $subdir; + next unless -d $dir; + + finddepth(sub { + return unless /\.pir$/; + + my $file = catfile $File::Find::dir, $_; + my $module = abs2rel $file, $dir; + my $status = $self->run_apache_test_config_scan($file); + push @$entries, [$file, $module, $subdir, $status]; + }, $dir); + } +} + +sub configure_parrot_tests { + my $self = shift; + + my @entries = (); + $self->configure_parrot_tests_pick(\@entries); + $self->configure_pm_tests_sort(\@entries); + + my %seen = (); + + for my $entry (@entries) { + my ($file, $module, $subdir, $status) = @$entry; + + my @args = (); + + my $directives = $self->add_module_config($file, \@args); + + $module =~ s,\.pir$,,; + $module =~ s/^[a-z]://i; #strip drive if any + $module = join '::', splitdir $module; + + my @base = map { s/^test//i; $_ } split '::', $module; + + my $sub = pop @base; + + debug "configuring mod_parrot test file $file"; + + push @args, SetHandler => 'parrot-code'; + push @args, ParrotHandler => $module; + + $self->postamble(ParrotLoad => $file); + $self->postamble($self->location_container($module), \@args); + + $self->write_pm_test($module, lc $sub, map { lc } @base); + } +} + +1; + +__DATA__ diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm new file mode 100644 index 0000000..60e12e3 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm @@ -0,0 +1,558 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestConfig; #not TestConfigParse on purpose + +#dont really want/need a full-blown parser +#but do want something somewhat generic + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestTrace; + +use File::Spec::Functions qw(rel2abs splitdir file_name_is_absolute); +use File::Basename qw(dirname basename); + +sub strip_quotes { + local $_ = shift || $_; + s/^\"//; s/\"$//; $_; +} + +my %wanted_config = ( + TAKE1 => {map { $_, 1 } qw(ServerRoot ServerAdmin TypesConfig DocumentRoot)}, + TAKE2 => {map { $_, 1 } qw(LoadModule LoadFile)}, +); + +my %spec_init = ( + TAKE1 => sub { shift->{+shift} = "" }, + TAKE2 => sub { shift->{+shift} = [] }, +); + +my %spec_apply = ( + TypesConfig => \&inherit_server_file, + ServerRoot => sub {}, #dont override $self->{vars}->{serverroot} + DocumentRoot => \&inherit_directive_var, + LoadModule => \&inherit_load_module, + LoadFile => \&inherit_load_file, +); + +#where to add config, default is preamble +my %spec_postamble = map { $_, 'postamble' } qw(TypesConfig); + +# need to enclose the following directives into <IfModule +# mod_foo.c>..</IfModule>, since mod_foo might be unavailable +my %ifmodule = ( + TypesConfig => 'mod_mime.c', +); + +sub spec_add_config { + my($self, $directive, $val) = @_; + + my $where = $spec_postamble{$directive} || 'preamble'; + + if (my $ifmodule = $ifmodule{TypesConfig}) { + $self->postamble(<<EOI); +<IfModule $ifmodule> + $directive $val +</IfModule> +EOI + } + else { + $self->$where($directive => $val); + } +} + +# resolve relative files like Apache->server_root_relative +# this function doesn't test whether the resolved file exists +sub server_file_rel2abs { + my($self, $file, $base) = @_; + + my ($serverroot, $result) = (); + + # order search sequence + my @tries = ([ $base, + 'user-supplied $base' ], + [ $self->{inherit_config}->{ServerRoot}, + 'httpd.conf inherited ServerRoot' ], + [ $self->apxs('PREFIX', 1), + 'apxs-derived ServerRoot' ]); + + # remove surrounding quotes if any + # e.g. Include "/tmp/foo.html" + $file =~ s/^\s*["']?//; + $file =~ s/["']?\s*$//; + + if (file_name_is_absolute($file)) { + debug "$file is already absolute"; + $result = $file; + } + else { + foreach my $try (@tries) { + next unless defined $try->[0]; + + if (-d $try->[0]) { + $serverroot = $try->[0]; + debug "using $try->[1] to resolve $file"; + last; + } + } + + if ($serverroot) { + $result = rel2abs $file, $serverroot; + } + else { + warning "unable to resolve $file - cannot find a suitable ServerRoot"; + warning "please specify a ServerRoot in your httpd.conf or use apxs"; + + # return early, skipping file test below + return $file; + } + } + + my $dir = dirname $result; + # $file might not exist (e.g. if it's a glob pattern like + # "conf/*.conf" but what we care about here is to check whether + # the base dir was successfully resolved. we don't check whether + # the file exists at all. it's the responsibility of the caller to + # do this check + if (defined $dir && -e $dir && -d _) { + if (-e $result) { + debug "$file successfully resolved to existing file $result"; + } + else { + debug "base dir of '$file' successfully resolved to $dir"; + } + + } + else { + $dir ||= ''; + warning "dir '$dir' does not exist (while resolving '$file')"; + + # old behavior was to return the resolved but non-existent + # file. preserve that behavior and return $result anyway. + } + + return $result; +} + +sub server_file { + my $f = shift->server_file_rel2abs(@_); + return qq("$f"); +} + +sub inherit_directive_var { + my($self, $c, $directive) = @_; + + $self->{vars}->{"inherit_\L$directive"} = $c->{$directive}; +} + +sub inherit_server_file { + my($self, $c, $directive) = @_; + + $self->spec_add_config($directive, + $self->server_file($c->{$directive})); +} + +#so we have the same names if these modules are linked static or shared +my %modname_alias = ( + 'mod_pop.c' => 'pop_core.c', + 'mod_proxy_ajp.c' => 'proxy_ajp.c', + 'mod_proxy_http.c' => 'proxy_http.c', + 'mod_proxy_ftp.c' => 'proxy_ftp.c', + 'mod_proxy_balancer.c' => 'proxy_balancer.c', + 'mod_proxy_connect.c' => 'proxy_connect.c', + 'mod_modperl.c' => 'mod_perl.c', +); + +# Block modules which inhibit testing: +# - mod_jk requires JkWorkerFile or JkWorker to be configured +# skip it for now, tomcat has its own test suite anyhow. +# - mod_casp2 requires other settings in addition to LoadModule +# - mod_bwshare and mod_evasive20 block fast requests that tests are doing +# - mod_fcgid causes https://rt.cpan.org/Public/Bug/Display.html?id=54476 +# - mod_modnss.c and mod_rev.c require further configuration +my @autoconfig_skip_module = qw(mod_jk.c mod_casp2.c mod_bwshare.c + mod_fcgid.c mod_evasive20.c mod_modnss.c mod_rev.c); + +# add modules to be not inherited from the existing config. +# e.g. prevent from LoadModule perl_module to be included twice, when +# mod_perl already configures LoadModule and it's certainly found in +# the existing httpd.conf installed system-wide. +sub autoconfig_skip_module_add { + push @autoconfig_skip_module, @_; +} + +sub should_skip_module { + my($self, $name) = @_; + + for (@autoconfig_skip_module) { + if (UNIVERSAL::isa($_, 'Regexp')) { + return 1 if $name =~ /$_/; + } + else { + return 1 if $name eq $_; + } + } + return 0; +} + +#inherit LoadModule +sub inherit_load_module { + my($self, $c, $directive) = @_; + + for my $args (@{ $c->{$directive} }) { + my $modname = $args->[0]; + my $file = $self->server_file_rel2abs($args->[1]); + + unless (-e $file) { + debug "$file does not exist, skipping LoadModule"; + next; + } + + my $name = basename $args->[1]; + $name =~ s/\.(s[ol]|dll)$/.c/; #mod_info.so => mod_info.c + $name =~ s/^lib/mod_/; #libphp4.so => mod_php4.c + + $name = $modname_alias{$name} if $modname_alias{$name}; + + # remember all found modules + $self->{modules}->{$name} = $file; + debug "Found: $modname => $name"; + + if ($self->should_skip_module($name)) { + debug "Skipping LoadModule of $name"; + next; + } + + debug "LoadModule $modname $name"; + + # sometimes people have broken system-wide httpd.conf files, + # which include LoadModule of modules, which are built-in, but + # won't be skipped above if they are found in the modules/ + # directory. this usually happens when httpd is built once + # with its modules built as shared objects and then again with + # static ones: the old httpd.conf still has the LoadModule + # directives, even though the modules are now built-in + # so we try to workaround this problem using <IfModule> + $self->preamble(IfModule => "!$name", + qq{LoadModule $modname "$file"\n}); + } +} + +#inherit LoadFile +sub inherit_load_file { + my($self, $c, $directive) = @_; + + for my $args (@{ $c->{$directive} }) { + my $file = $self->server_file_rel2abs($args->[0]); + + unless (-e $file) { + debug "$file does not exist, skipping LoadFile"; + next; + } + + if ($self->should_skip_module($args->[0])) { + debug "Skipping LoadFile of $args->[0]"; + next; + } + + # remember all found modules + push @{$self->{load_file}}, $file; + + debug "LoadFile $file"; + + $self->preamble_first(qq{LoadFile "$file"\n}); + } +} + +sub parse_take1 { + my($self, $c, $directive) = @_; + $c->{$directive} = strip_quotes; +} + +sub parse_take2 { + my($self, $c, $directive) = @_; + push @{ $c->{$directive} }, [map { strip_quotes } split]; +} + +sub apply_take1 { + my($self, $c, $directive) = @_; + + if (exists $self->{vars}->{lc $directive}) { + #override replacement @Variables@ + $self->{vars}->{lc $directive} = $c->{$directive}; + } + else { + $self->spec_add_config($directive, qq("$c->{$directive}")); + } +} + +sub apply_take2 { + my($self, $c, $directive) = @_; + + for my $args (@{ $c->{$directive} }) { + $self->spec_add_config($directive => [map { qq("$_") } @$args]); + } +} + +sub inherit_config_file_or_directory { + my ($self, $item) = @_; + + if (-d $item) { + my $dir = $item; + debug "descending config directory: $dir"; + + for my $entry (glob "$dir/*") { + $self->inherit_config_file_or_directory($entry); + } + return; + } + + my $file = $item; + debug "inheriting config file: $file"; + + my $fh = Symbol::gensym(); + open($fh, $file) or return; + + my $c = $self->{inherit_config}; + while (<$fh>) { + s/^\s*//; s/\s*$//; s/^\#.*//; + next if /^$/; + + # support continuous config lines (which use \ to break the line) + while (s/\\$//) { + my $cont = <$fh>; + $cont =~ s/^\s*//; + $cont =~ s/\s*$//; + $_ .= $cont; + } + + (my $directive, $_) = split /\s+/, $_, 2; + + if ($directive eq "Include" or $directive eq "IncludeOptional") { + foreach my $include (glob($self->server_file_rel2abs($_))) { + $self->inherit_config_file_or_directory($include); + } + } + + #parse what we want + while (my($spec, $wanted) = each %wanted_config) { + next unless $wanted->{$directive}; + my $method = "parse_\L$spec"; + $self->$method($c, $directive); + } + } + + close $fh; +} + +sub inherit_config { + my $self = shift; + + $self->get_httpd_static_modules; + $self->get_httpd_defines; + + #may change after parsing httpd.conf + $self->{vars}->{inherit_documentroot} = + catfile $self->{httpd_basedir}, 'htdocs'; + + my $file = $self->{vars}->{httpd_conf}; + my $extra_file = $self->{vars}->{httpd_conf_extra}; + + unless ($file and -e $file) { + if (my $base = $self->{httpd_basedir}) { + my $default_conf = $self->{httpd_defines}->{SERVER_CONFIG_FILE}; + $default_conf ||= catfile qw(conf httpd.conf); + $file = catfile $base, $default_conf; + + # SERVER_CONFIG_FILE might be an absolute path + unless (-e $file) { + if (-e $default_conf) { + $file = $default_conf; + } + else { + # try a little harder + if (my $root = $self->{httpd_defines}->{HTTPD_ROOT}) { + debug "using HTTPD_ROOT to resolve $default_conf"; + $file = catfile $root, $default_conf; + } + } + } + } + } + + unless ($extra_file and -e $extra_file) { + if ($extra_file and my $base = $self->{httpd_basedir}) { + my $default_conf = catfile qw(conf $extra_file); + $extra_file = catfile $base, $default_conf; + # SERVER_CONFIG_FILE might be an absolute path + $extra_file = $default_conf if !-e $extra_file and -e $default_conf; + } + } + + return unless $file or $extra_file; + + my $c = $self->{inherit_config}; + + #initialize array refs and such + while (my($spec, $wanted) = each %wanted_config) { + for my $directive (keys %$wanted) { + $spec_init{$spec}->($c, $directive); + } + } + + $self->inherit_config_file_or_directory($file) if $file; + $self->inherit_config_file_or_directory($extra_file) if $extra_file; + + #apply what we parsed + while (my($spec, $wanted) = each %wanted_config) { + for my $directive (keys %$wanted) { + next unless $c->{$directive}; + my $cv = $spec_apply{$directive} || + $self->can("apply_\L$directive") || + $self->can("apply_\L$spec"); + $cv->($self, $c, $directive); + } + } +} + +sub get_httpd_static_modules { + my $self = shift; + + my $httpd = $self->{vars}->{httpd}; + return unless $httpd; + + $httpd = shell_ready($httpd); + my $cmd = "$httpd -l"; + my $list = $self->open_cmd($cmd); + + while (<$list>) { + s/\s+$//; + next unless /\.c$/; + chomp; + s/^\s+//; + $self->{modules}->{$_} = 1; + } + + close $list; +} + +sub get_httpd_defines { + my $self = shift; + + my $httpd = $self->{vars}->{httpd}; + return unless $httpd; + + $httpd = shell_ready($httpd); + my $cmd = "$httpd -V"; + + my $httpdconf = $self->{vars}->{httpd_conf}; + $cmd .= " -f $httpdconf" if $httpdconf; + + my $serverroot = $self->{vars}->{serverroot}; + $cmd .= " -d $serverroot" if $serverroot; + + my $proc = $self->open_cmd($cmd); + + while (<$proc>) { + chomp; + if( s/^\s*-D\s*//) { + s/\s+$//; + my($key, $val) = split '=', $_, 2; + $self->{httpd_defines}->{$key} = $val ? strip_quotes($val) : 1; + debug "isolated httpd_defines $key = " . $self->{httpd_defines}->{$key}; + } + elsif (/(version|built|module magic number|server mpm):\s+(.*)/i) { + my $val = $2; + (my $key = uc $1) =~ s/\s/_/g; + $self->{httpd_info}->{$key} = $val; + debug "isolated httpd_info $key = " . $val; + } + } + + close $proc; + + if (my $mmn = $self->{httpd_info}->{MODULE_MAGIC_NUMBER}) { + @{ $self->{httpd_info} } + {qw(MODULE_MAGIC_NUMBER_MAJOR + MODULE_MAGIC_NUMBER_MINOR)} = split ':', $mmn; + } + + # get the mpm information where available + # lowercase for consistency across the two extraction methods + # XXX or maybe consider making have_apache_mpm() case-insensitive? + if (my $mpm = $self->{httpd_info}->{SERVER_MPM}) { + # 2.1 + $self->{mpm} = lc $mpm; + } + elsif (my $mpm_dir = $self->{httpd_defines}->{APACHE_MPM_DIR}) { + # 2.0 + $self->{mpm} = lc basename $mpm_dir; + } + else { + # Apache 1.3 - no mpm to speak of + $self->{mpm} = ''; + } + + my $version = $self->{httpd_info}->{VERSION} || ''; + + if ($version =~ qr,Apache/2,) { + # PHP 4.x on httpd-2.x needs a special modname alias: + $modname_alias{'mod_php4.c'} = 'sapi_apache2.c'; + } + + unless ($version =~ qr,Apache/(2.0|1.3),) { + # for 2.1 and later, mod_proxy_* are really called mod_proxy_* + delete @modname_alias{grep {/^mod_proxy_/} keys %modname_alias}; + } +} + +sub httpd_version { + my $self = shift; + + my $httpd = $self->{vars}->{httpd}; + return unless $httpd; + + my $version; + $httpd = shell_ready($httpd); + my $cmd = "$httpd -v"; + + my $v = $self->open_cmd($cmd); + + local $_; + while (<$v>) { + next unless s/^Server\s+version:\s*//i; + chomp; + my @parts = split; + foreach (@parts) { + next unless /^Apache\//; + $version = $_; + last; + } + $version ||= $parts[0]; + last; + } + + close $v; + + return $version; +} + +sub httpd_mpm { + return shift->{mpm}; +} + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigPerl.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigPerl.pm new file mode 100644 index 0000000..152ef58 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigPerl.pm @@ -0,0 +1,654 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestConfig; #not TestConfigPerl on purpose + +#things specific to mod_perl + +use strict; +use warnings FATAL => 'all'; +use File::Spec::Functions qw(catfile splitdir abs2rel file_name_is_absolute); +use File::Find qw(finddepth); +use Apache::TestTrace; +use Apache::TestRequest; +use Config; + +my %libmodperl = (1 => 'libperl.so', 2 => 'mod_perl.so'); + +sub configure_libmodperl { + my $self = shift; + + my $server = $self->{server}; + my $libname = $server->version_of(\%libmodperl); + my $vars = $self->{vars}; + + if ($vars->{libmodperl}) { + # if set, libmodperl was specified from the command line and + # should be used instead of the one that is looked up + + # resolve a non-absolute path + $vars->{libmodperl} = $self->find_apache_module($vars->{libmodperl}) + unless file_name_is_absolute($vars->{libmodperl}); + } + # $server->{rev} could be set to 2 as a fallback, even when + # the wanted version is 1. So check that we use mod_perl 2 + elsif ($server->{rev} >= 2 && IS_MOD_PERL_2) { + + if (my $build_config = $self->modperl_build_config()) { + if ($build_config->{MODPERL_LIB_SHARED}) { + $libname = $build_config->{MODPERL_LIB_SHARED}; + $vars->{libmodperl} ||= $self->find_apache_module($libname); + } else { + $vars->{libmodperl} ||= $self->find_apache_module('mod_perl.so'); + } + # XXX: we have a problem with several perl trees pointing + # to the same httpd tree. So it's possible that we + # configure the test suite to run with mod_perl.so built + # against perl which it wasn't built with. Should we use + # something like ldd to check the match? + # + # For now, we'll default to the first mod_perl.so found. + } + else { + # XXX: can we test whether mod_perl was linked statically + # so we don't need to preload it + # if (!linked statically) { + # die "can't find mod_perl built for perl version $]" + # } + error "can't find mod_perl.so built for perl version $]"; + } + # don't use find_apache_module or we may end up with the wrong + # shared object, built against different perl + } + else { + # mod_perl 1.0 + $vars->{libmodperl} ||= $self->find_apache_module($libname); + # XXX: how do we find out whether we have a static or dynamic + # mod_perl build? die if its dynamic and can't find the module + } + + my $cfg = ''; + + if ($vars->{libmodperl} && -e $vars->{libmodperl}) { + if (Apache::TestConfig::WIN32) { + my $lib = "$Config{installbin}\\$Config{libperl}"; + $lib =~ s/lib$/dll/; + $cfg = 'LoadFile ' . qq("$lib"\n) if -e $lib; + } + # add the module we found to the cached modules list + # otherwise have_module('mod_perl') doesn't work unless + # we have a LoadModule in our base config + $self->{modules}->{'mod_perl.c'} = $vars->{libmodperl}; + + $cfg .= 'LoadModule ' . qq(perl_module "$vars->{libmodperl}"\n); + } + else { + my $msg = "unable to locate $libname (could be a static build)\n"; + $cfg = "#$msg"; + debug $msg; + } + + $self->preamble(IfModule => '!mod_perl.c', $cfg); + +} + +sub configure_inc { + my $self = shift; + + my $top = $self->{vars}->{top_dir}; + + my $inc = $self->{inc}; + + for (catdir($top, qw(blib lib)), catdir($top, qw(blib arch))) { + if (-d $_) { + push @$inc, $_; + } + } + + # try ../blib as well for Apache::Reload & Co + for (catdir($top, qw(.. blib lib)), catdir($top, qw(.. blib arch))) { + push @$inc, $_ if -d $_; + } + + # spec: If PERL5LIB is defined, PERLLIB is not used. + for (qw(PERL5LIB PERLLIB)) { + next unless exists $ENV{$_}; + push @$inc, split /$Config{path_sep}/, $ENV{$_}; + last; + } + + # enable live testing of the Apache-Test dev modules if they are + # located at the project's root dir + my $apache_test_dev_dir = catfile($top, 'Apache-Test', 'lib'); + unshift @$inc, $apache_test_dev_dir if -d $apache_test_dev_dir; +} + +sub write_pm_test { + my($self, $module, $sub, @base) = @_; + + my $dir = catfile $self->{vars}->{t_dir}, @base; + my $t = catfile $dir, "$sub.t"; + return if -e $t; + + $self->gendir($dir); + my $fh = $self->genfile($t); + + my $path = Apache::TestRequest::module2path($module); + + print $fh <<EOF; +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/$path"; +EOF + + close $fh or die "close $t: $!"; +} + +# propogate PerlPassEnv settings to the server +sub configure_env { + my $self = shift; + $self->preamble(IfModule => 'mod_perl.c', + [ qw(PerlPassEnv APACHE_TEST_TRACE_LEVEL + PerlPassEnv HARNESS_PERL_SWITCHES + PerlPassEnv APACHE_TEST_NO_STICKY_PREFERENCES) + ]); +} + +sub startup_pl_code { + my $self = shift; + my $serverroot = $self->{vars}->{serverroot}; + + my $cover = <<'EOF'; + if (($ENV{HARNESS_PERL_SWITCHES}||'') =~ m/Devel::Cover/) { + eval { + # 0.48 is the first version of Devel::Cover that can + # really generate mod_perl coverage statistics + require Devel::Cover; + Devel::Cover->VERSION(0.48); + + # this ignores coverage data for some generated files + Devel::Cover->import('+inc' => 't/response/',); + + 1; + } or die "Devel::Cover error: $@"; + } +EOF + + return <<"EOF"; +BEGIN { + use lib '$serverroot'; + for my \$file (qw(modperl_inc.pl modperl_extra.pl)) { + eval { require "conf/\$file" } or + die if grep { -e "\$_/conf/\$file" } \@INC; + } + +$cover +} + +1; +EOF +} + +sub configure_startup_pl { + my $self = shift; + + #for 2.0 we could just use PerlSwitches -Mlib=... + #but this will work for both 2.0 and 1.xx + if (my $inc = $self->{inc}) { + my $include_pl = catfile $self->{vars}->{t_conf}, 'modperl_inc.pl'; + my $fh = $self->genfile($include_pl); + for (reverse @$inc) { + next unless $_; + print $fh "use lib '$_';\n"; + } + my $tlib = catdir $self->{vars}->{t_dir}, 'lib'; + if (-d $tlib) { + print $fh "use lib '$tlib';\n"; + } + + # directory for temp packages which can change during testing + # we use require here since a circular dependency exists + # between Apache::TestUtil and Apache::TestConfigPerl, so + # use does not work here + eval { require Apache::TestUtil; }; + if ($@) { + die "could not require Apache::TestUtil: $@"; + } else { + print $fh "use lib '" . Apache::TestUtil::_temp_package_dir() . "';\n"; + } + + # if Apache::Test is used to develop a project, we want the + # project/lib directory to be first in @INC (loaded last) + if ($ENV{APACHE_TEST_LIVE_DEV}) { + my $dev_lib = catdir $self->{vars}->{top_dir}, "lib"; + print $fh "use lib '$dev_lib';\n" if -d $dev_lib; + } + + print $fh "1;\n"; + } + + if ($self->server->{rev} >= 2) { + $self->postamble(IfModule => 'mod_perl.c', + "PerlSwitches -Mlib=$self->{vars}->{serverroot}\n"); + } + + my $startup_pl = catfile $self->{vars}->{t_conf}, 'modperl_startup.pl'; + + unless (-e $startup_pl) { + my $fh = $self->genfile($startup_pl); + print $fh $self->startup_pl_code; + close $fh; + } + + $self->postamble(IfModule => 'mod_perl.c', + "PerlRequire $startup_pl\n"); +} + +my %sethandler_modperl = (1 => 'perl-script', 2 => 'modperl'); + +sub set_handler { + my($self, $module, $args) = @_; + return if grep { $_ eq 'SetHandler' } @$args; + + push @$args, + SetHandler => + $self->server->version_of(\%sethandler_modperl); +} + +sub set_connection_handler { + my($self, $module, $args) = @_; + my $port = $self->new_vhost($module); + my $vars = $self->{vars}; + $self->postamble(Listen => '0.0.0.0:' . $port); +} + +my %add_hook_config = ( + Response => \&set_handler, + ProcessConnection => \&set_connection_handler, + PreConnection => \&set_connection_handler, +); + +my %container_config = ( + ProcessConnection => \&vhost_container, + PreConnection => \&vhost_container, +); + +sub location_container { + my($self, $module) = @_; + my $path = Apache::TestRequest::module2path($module); + Location => "/$path"; +} + +sub vhost_container { + my($self, $module) = @_; + my $port = $self->{vhosts}->{$module}->{port}; + my $namebased = $self->{vhosts}->{$module}->{namebased}; + + VirtualHost => ($namebased ? '*' : '_default_') . ":$port"; +} + +sub new_vhost { + my($self, $module, $namebased) = @_; + my($port, $servername, $vhost); + + unless ($namebased and exists $self->{vhosts}->{$module}) { + $port = $self->server->select_next_port; + $vhost = $self->{vhosts}->{$module} = {}; + + $vhost->{port} = $port; + $vhost->{namebased} = $namebased ? 1 : 0; + } + else { + $vhost = $self->{vhosts}->{$module}; + $port = $vhost->{port}; + # remember the already configured Listen/NameVirtualHost + $vhost->{namebased}++; + } + + $servername = $self->{vars}->{servername}; + + $vhost->{servername} = $servername; + $vhost->{name} = join ':', $servername, $port; + $vhost->{hostport} = $self->hostport($vhost, $module); + + $port; +} + +my %outside_container = map { $_, 1 } qw{ +Alias AliasMatch AddType +PerlChildInitHandler PerlTransHandler PerlPostReadRequestHandler +PerlSwitches PerlRequire PerlModule +}; + +my %strip_tags = map { $_ => 1} qw(base noautoconfig); + +#test .pm's can have configuration after the __DATA__ token +sub add_module_config { + my($self, $module, $args) = @_; + my $fh = Symbol::gensym(); + open($fh, $module) or return; + + while (<$fh>) { + last if /^(__(DATA|END)__|\#if CONFIG_FOR_HTTPD_TEST)/; + } + + my %directives; + + while (<$fh>) { + last if /^\#endif/; #for .c modules + next unless /\S+/; + chomp; + s/^\s+//; + $self->replace; + if (/^#/) { + # preserve comments + $self->postamble($_); + next; + } + my($directive, $rest) = split /\s+/, $_, 2; + $directives{$directive}++ unless $directive =~ /^</; + $rest = '' unless defined $rest; + + if ($outside_container{$directive}) { + $self->postamble($directive => $rest); + } + elsif ($directive =~ /IfModule/) { + $self->postamble($_); + } + elsif ($directive =~ m/^<(\w+)/) { + # strip special container directives like <Base> and </Base> + my $strip_container = exists $strip_tags{lc $1} ? 1 : 0; + + $directives{noautoconfig}++ if lc($1) eq 'noautoconfig'; + + my $indent = ''; + $self->process_container($_, $fh, lc($1), + $strip_container, $indent); + } + else { + push @$args, $directive, $rest; + } + } + + \%directives; +} + + +# recursively process the directives including nested containers, +# re-indent 4 and ucfirst the closing tags letter +sub process_container { + my($self, $first_line, $fh, $directive, $strip_container, $indent) = @_; + + my $new_indent = $indent; + + unless ($strip_container) { + $new_indent .= " "; + + local $_ = $first_line; + s/^\s*//; + $self->replace; + + if (/<VirtualHost/) { + $self->process_vhost_open_tag($_, $indent); + } + else { + $self->postamble($indent . $_); + } + } + + $self->process_container_remainder($fh, $directive, $new_indent); + + unless ($strip_container) { + $self->postamble($indent . "</\u$directive>"); + } + +} + + +# processes the body of the container without the last line, including +# the end tag +sub process_container_remainder { + my($self, $fh, $directive, $indent) = @_; + + my $end_tag = "</$directive>"; + + while (<$fh>) { + chomp; + last if m|^\s*\Q$end_tag|i; + s/^\s*//; + $self->replace; + + if (m/^\s*<(\w+)/) { + $self->process_container($_, $fh, $1, 0, $indent); + } + else { + $self->postamble($indent . $_); + } + } +} + +# does the necessary processing to create a vhost container header +sub process_vhost_open_tag { + my($self, $line, $indent) = @_; + + my $cfg = $self->parse_vhost($line); + + if ($cfg) { + my $port = $cfg->{port}; + $cfg->{out_postamble}->(); + $self->postamble($cfg->{line}); + $cfg->{in_postamble}->(); + } else { + $self->postamble("$indent$line"); + } +} + +#the idea for each group: +# Response: there will be many of these, mostly modules to test the API +# that plan tests => ... and output with ok() +# the naming allows grouping, making it easier to run an +# individual set of tests, e.g. t/TEST t/apr +# the PerlResponseHandler and SetHandler modperl is auto-configured +# Hooks: for testing the simpler Perl*Handlers +# auto-generates the Perl*Handler config +# Protocol: protocol modules need their own port/vhost to listen on + +#@INC is auto-modified so each test .pm can be found +#modules can add their own configuration using __DATA__ + +my %hooks = map { $_, ucfirst $_ } + qw(init trans headerparser access authen authz type fixup log); +$hooks{Protocol} = 'ProcessConnection'; +$hooks{Filter} = 'OutputFilter'; + +my @extra_subdirs = qw(Response Protocol PreConnection Hooks Filter); + +# add the subdirs to @INC early, in case mod_perl is started earlier +sub configure_pm_tests_inc { + my $self = shift; + for my $subdir (@extra_subdirs) { + my $dir = catfile $self->{vars}->{t_dir}, lc $subdir; + next unless -d $dir; + + push @{ $self->{inc} }, $dir; + } +} + +# @status fields +use constant APACHE_TEST_CONFIGURE => 0; +use constant APACHE_TEST_CONFIG_ORDER => 1; + +sub configure_pm_tests_pick { + my($self, $entries) = @_; + + for my $subdir (@extra_subdirs) { + my $dir = catfile $self->{vars}->{t_dir}, lc $subdir; + next unless -d $dir; + + finddepth(sub { + return unless /\.pm$/; + + my $file = catfile $File::Find::dir, $_; + my $module = abs2rel $file, $dir; + my $status = $self->run_apache_test_config_scan($file); + push @$entries, [$file, $module, $subdir, $status]; + }, $dir); + } +} + + +# a simple numerical order is performed and configuration sections are +# inserted using that order. If the test package specifies no special +# token that matches /APACHE_TEST_CONFIG_ORDER\s+([+-]?\d+)/ anywhere +# in the file, 0 is assigned as its order. If the token is specified, +# config section with negative values will be inserted first, with +# positive last. By using different values you can arrange for the +# test configuration sections to be inserted in any desired order +sub configure_pm_tests_sort { + my($self, $entries) = @_; + + @$entries = sort { + $a->[3]->[APACHE_TEST_CONFIG_ORDER] <=> + $b->[3]->[APACHE_TEST_CONFIG_ORDER] + } @$entries; + +} + +sub configure_pm_tests { + my $self = shift; + + my @entries = (); + $self->configure_pm_tests_pick(\@entries); + $self->configure_pm_tests_sort(\@entries); + + for my $entry (@entries) { + my ($file, $module, $subdir, $status) = @$entry; + my @args = (); + + my $file_display; + { + $file_display=$file; + my $topdir=$self->{vars}->{top_dir}; + $file_display=~s!^\Q$topdir\E(.)(?:\1)*!!; + } + $self->postamble("\n# included from $file_display"); + my $directives = $self->add_module_config($file, \@args); + $module =~ s,\.pm$,,; + $module =~ s/^[a-z]://i; #strip drive if any + $module = join '::', splitdir $module; + + $self->run_apache_test_configure($file, $module, $status); + + my @base = + map { s/^test//i; $_ } split '::', $module; + + my $sub = pop @base; + + my $hook = ($subdir eq 'Hooks' ? $hooks{$sub} : '') + || $hooks{$subdir} || $subdir; + + if ($hook eq 'OutputFilter' and $module =~ /::i\w+$/) { + #XXX: tmp hack + $hook = 'InputFilter'; + } + + my $handler = join $hook, qw(Perl Handler); + + if ($self->server->{rev} < 2 and lc($hook) eq 'response') { + $handler =~ s/response//i; #s/PerlResponseHandler/PerlHandler/ + } + + debug "configuring $module"; + + unless ($directives->{noautoconfig}) { + if (my $cv = $add_hook_config{$hook}) { + $self->$cv($module, \@args); + } + + my $container = $container_config{$hook} || \&location_container; + + #unless the .pm test already configured the Perl*Handler + unless ($directives->{$handler}) { + my @handler_cfg = ($handler => $module); + + if ($outside_container{$handler}) { + my $cfg = $self->massage_config_args(@handler_cfg); + $self->postamble(IfModule => 'mod_perl.c', $cfg); + } else { + push @args, @handler_cfg; + } + } + + if (@args) { + my $cfg = $self->massage_config_args($self->$container($module), \@args); + $self->postamble(IfModule => 'mod_perl.c', $cfg); + } + } + $self->postamble("# end of $file_display\n"); + + $self->write_pm_test($module, lc $sub, map { lc } @base); + } +} + +# scan tests for interesting information +sub run_apache_test_config_scan { + my ($self, $file) = @_; + + my @status = (); + $status[APACHE_TEST_CONFIGURE] = 0; + $status[APACHE_TEST_CONFIG_ORDER] = 0; + + my $fh = Symbol::gensym(); + if (open $fh, $file) { + local $/; + my $content = <$fh>; + close $fh; + # XXX: optimize to match once? + if ($content =~ /APACHE_TEST_CONFIGURE/m) { + $status[APACHE_TEST_CONFIGURE] = 1; + } + if ($content =~ /APACHE_TEST_CONFIG_ORDER\s+([+-]?\d+)/m) { + $status[APACHE_TEST_CONFIG_ORDER] = int $1; + } + } + else { + error "cannot open $file: $!"; + } + + return \@status; +} + +# We have to test whether tests have APACHE_TEST_CONFIGURE() in them +# and run it if found at this stage, so when the server starts +# everything is ready. +# XXX: however we cannot use a simple require() because some tests +# won't require() outside of mod_perl environment. Therefore we scan +# the slurped file in. and if APACHE_TEST_CONFIGURE has been found we +# require the file and run this function. +sub run_apache_test_configure { + my ($self, $file, $module, $status) = @_; + + return unless $status->[APACHE_TEST_CONFIGURE]; + + eval { require $file }; + warn $@ if $@; + # double check that it's a real sub + if ($module->can('APACHE_TEST_CONFIGURE')) { + eval { $module->APACHE_TEST_CONFIGURE($self); }; + warn $@ if $@; + } +} + + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestHandler.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestHandler.pm new file mode 100644 index 0000000..6b1e691 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestHandler.pm @@ -0,0 +1,175 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestHandler; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test qw/!:DEFAULT/; # call import() to tell about -withouttestmore +use Apache::TestRequest (); + +use Apache2::Const -compile => qw(OK NOT_FOUND SERVER_ERROR); + +#some utility handlers for testing hooks other than response +#see modperl-2.0/t/hooks/TestHooks/authen.pm + +if ($ENV{MOD_PERL} && require mod_perl2) { + require Apache2::RequestRec; # content_type + require Apache2::RequestIO; # puts +} + +#compat with 1.xx +my $send_http_header = Apache->can('send_http_header') || sub {}; +my $print = Apache2->can('print') || Apache2::RequestRec->can('puts'); + +sub ok { + my ($r, $boolean) = @_; + $r->$send_http_header; + $r->content_type('text/plain'); + $r->$print((@_>1 && !$boolean ? "not " : '')."ok"); + 0; +} + +sub ok1 { + my ($r, $boolean) = @_; + Apache::Test::plan($r, tests => 1); + Apache::Test::ok(@_==1 || $boolean); + 0; +} + +# a fixup handler to be used when a few requests need to be run +# against the same perl interpreter, in situations where there is more +# than one client running. For an example of use see +# modperl-2.0/t/response/TestModperl/interp.pm and +# modperl-2.0/t/modperl/interp.t +# +# this handler expects the header X-PerlInterpreter in the request +# - if none is set, Apache::SERVER_ERROR is returned +# - if its value eq 'tie', instance's global UUID is assigned and +# returned via the same header +# - otherwise if its value is not the same the stored instance's +# global UUID Apache::NOT_FOUND is returned +# +# in addition $same_interp_counter counts how many times this instance of +# pi has been called after the reset 'tie' request (inclusive), this +# value can be retrieved with Apache::TestHandler::same_interp_counter() +my $same_interp_id = ""; +# keep track of how many times this instance was called after the reset +my $same_interp_counter = 0; +sub same_interp_counter { $same_interp_counter } +sub same_interp_fixup { + my $r = shift; + my $interp = $r->headers_in->get(Apache::TestRequest::INTERP_KEY); + + unless ($interp) { + # shouldn't be requesting this without an INTERP header + die "can't find the interpreter key"; + } + + my $id = $same_interp_id; + if ($interp eq 'tie') { #first request for an interpreter instance + # unique id for this instance + $same_interp_id = $id = + unpack "H*", pack "Nnn", time, $$, int(rand(60000)); + $same_interp_counter = 0; #reset the counter + } + elsif ($interp ne $same_interp_id) { + # this is not the request interpreter instance + return Apache2::Const::NOT_FOUND; + } + + $same_interp_counter++; + + # so client can save the created instance id or check the existing + # value + $r->headers_out->set(Apache::TestRequest::INTERP_KEY, $id); + + return Apache2::Const::OK; +} + +1; +__END__ + +=encoding utf8 + +=head1 NAME + +Apache::TestHandler - a few response handlers and helpers + +=head1 SYNOPSIS + + package My::Test; + use Apache::TestHandler (); + sub handler { + my ($r) = @_; + my $result = do_my_test; + Apache::TestHandler::ok1 $r, $result; + } + + sub handler2 { + my ($r) = @_; + my $result = do_my_test; + Apache::TestHandler::ok $r, $result; + } + +=head1 DESCRIPTION + +C<Apache::TestHandler> provides 2 very simple response handler. + +=head1 FUNCTIONS + +=over 4 + +=item ok $r, $boolean + +The handler simply prints out C<ok> or C<not ok> depending on the +optional C<$boolean> parameter. + +If C<$boolean> is omitted C<true> is assumed. + +=item ok1 $r, $boolean + +This handler implements a simple response-only test. It can be used on its +own to check if for a certain URI the response phase is reached. Or it +can be called like a normal function to print out the test result. The +client side is automatically created as described in +L<http://perl.apache.org/docs/general/testing/testing.html#Developing_Response_only_Part_of_a_Test>. + +C<$boolean> is optional. If omitted C<true> is assumed. + +=item same_interp_counter + +=item same_interp_fixup + +TODO + +=back + +=head1 SEE ALSO + +The Apache-Test tutorial: +L<http://perl.apache.org/docs/general/testing/testing.html>. + +L<Apache::Test>. + +=head1 AUTHOR + +Doug MacEachern, Geoffrey Young, Stas Bekman, Torsten Förtsch and others. + +Questions can be asked at the test-dev <at> httpd.apache.org list +For more information see: http://httpd.apache.org/test/. + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestHarness.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestHarness.pm new file mode 100644 index 0000000..4128a43 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestHarness.pm @@ -0,0 +1,199 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestHarness; + +use strict; +use warnings FATAL => 'all'; + +use Test::Harness (); +use Apache::Test (); +use Apache::TestSort (); +use Apache::TestTrace; +use File::Spec::Functions qw(catfile catdir); +use File::Find qw(finddepth); +use File::Basename qw(dirname); + +sub inc_fixup { + # use blib + unshift @INC, map "blib/$_", qw(lib arch); + + # fix all relative library locations + for (@INC) { + $_ = "../$_" unless m,^(/)|([a-f]:),i; + } +} + +#skip tests listed in t/SKIP +sub skip { + my($self, $file) = @_; + $file ||= catfile Apache::Test::vars('serverroot'), 'SKIP'; + + return unless -e $file; + + my $fh = Symbol::gensym(); + open $fh, $file or die "open $file: $!"; + my @skip; + local $_; + + while (<$fh>) { + chomp; + s/^\s+//; s/\s+$//; s/^\#.*//; + next unless $_; + s/\*/.*/g; + push @skip, $_; + } + + close $fh; + return join '|', @skip; +} + +#test if all.t would skip tests or not +{ + my $source_lib = ''; + + sub run_t { + my($self, $file) = @_; + my $ran = 0; + + if (Apache::TestConfig::IS_APACHE_TEST_BUILD and !length $source_lib) { + # so we can find Apache/Test.pm from both the perl-framework/ + # and Apache-Test/ + + my $top_dir = Apache::Test::vars('top_dir'); + foreach my $lib (catfile($top_dir, qw(Apache-Test lib)), + catfile($top_dir, qw(.. Apache-Test lib)), + catfile($top_dir, 'lib')) { + + if (-d $lib) { + info "adding source lib $lib to \@INC"; + $source_lib = qq[-Mlib="$lib"]; + last; + } + } + } + + my $cmd = qq[$^X $source_lib $file]; + + my $h = Symbol::gensym(); + open $h, "$cmd|" or die "open $cmd: $!"; + + local $_; + while (<$h>) { + if (/^1\.\.(\d)/) { + $ran = $1; + last; + } + } + + close $h; + + $ran; + } +} + +#if a directory has an all.t test +#skip all tests in that directory if all.t prints "1..0\n" +sub prune { + my($self, @tests) = @_; + my(@new_tests, %skip_dirs); + + foreach my $test (@tests) { + next if $test =~ /\.#/; # skip temp emacs files + my $dir = dirname $test; + if ($test =~ m:\Wall\.t$:) { + unless (__PACKAGE__->run_t($test)) { + $skip_dirs{$dir} = 1; + @new_tests = grep { m:\Wall\.t$: || + not $skip_dirs{dirname $_} } @new_tests; + push @new_tests, $test; + } + } + elsif (!$skip_dirs{$dir}) { + push @new_tests, $test; + } + } + + @new_tests; +} + +sub get_tests { + my $self = shift; + my $args = shift; + my @tests = (); + + my $base = -d 't' ? catdir('t', '.') : '.'; + + my $ts = $args->{tests} || []; + + if (@$ts) { + for (@$ts) { + if (-d $_) { + push(@tests, sort <$base/$_/*.t>); + } + else { + $_ .= ".t" unless /\.t$/; + push(@tests, $_); + } + } + } + else { + if ($args->{tdirs}) { + push @tests, map { sort <$base/$_/*.t> } @{ $args->{tdirs} }; + } + else { + finddepth(sub { + return unless /\.t$/; + my $t = catfile $File::Find::dir, $_; + my $dotslash = catfile '.', ""; + $t =~ s:^\Q$dotslash::; + push @tests, $t + }, $base); + @tests = sort @tests; + } + } + + @tests = $self->prune(@tests); + + if (my $skip = $self->skip) { + # Allow / \ and \\ path delimiters in SKIP file + $skip =~ s![/\\\\]+![/\\\\]!g; + + @tests = grep { not /(?:$skip)/ } @tests; + } + + Apache::TestSort->run(\@tests, $args); + + #when running 't/TEST t/dir' shell tab completion adds a / + #dir//foo output is annoying, fix that. + s:/+:/:g for @tests; + + return @tests; +} + +sub run { + my $self = shift; + my $args = shift || {}; + + $Test::Harness::verbose ||= $args->{verbose}; + + if (my(@subtests) = @{ $args->{subtests} || [] }) { + $ENV{HTTPD_TEST_SUBTESTS} = "@subtests"; + } + + Test::Harness::runtests($self->get_tests($args, @_)); +} + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestHarnessPHP.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestHarnessPHP.pm new file mode 100644 index 0000000..90fdedc --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestHarnessPHP.pm @@ -0,0 +1,139 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestHarnessPHP; + +use strict; +use warnings FATAL => 'all'; + +use File::Spec::Functions qw(catfile catdir); +use File::Find qw(finddepth); +use Apache::TestHarness (); +use Apache::TestTrace; +use Apache::TestConfig (); + +use vars qw(@ISA); +@ISA = qw(Apache::TestHarness); +use TAP::Formatter::Console; +use TAP::Harness; + +sub get_tests { + + my $self = shift; + my $args = shift; + my @tests = (); + + my $base = -d 't' ? catdir('t', '.') : '.'; + + my $ts = $args->{tests} || []; + + if (@$ts) { + for (@$ts) { + if (-d $_) { + push(@tests, sort <$base/$_/*.t>); + push(@tests, sort <$base/$_/*.php>); + } + else { + $_ .= ".t" unless /(\.t|\.php)$/; + push(@tests, $_); + } + } + } + else { + if ($args->{tdirs}) { + push @tests, map { sort <$base/$_/*.t> } @{ $args->{tdirs} }; + push @tests, map { sort <$base/$_/*.php> } @{ $args->{tdirs} }; + } + else { + finddepth(sub { + return unless /\.(t|php)$/; + return if $File::Find::dir =~ m/\b(conf|htdocs|logs|response)\b/; + my $t = catfile $File::Find::dir, $_; + my $dotslash = catfile '.', ""; + $t =~ s:^\Q$dotslash::; + push @tests, $t + }, $base); + @tests = sort @tests; + } + } + + @tests = $self->prune(@tests); + + if (my $skip = $self->skip) { + # Allow / \ and \\ path delimiters in SKIP file + $skip =~ s![/\\\\]+![/\\\\]!g; + + @tests = grep { not /(?:$skip)/ } @tests; + } + + Apache::TestSort->run(\@tests, $args); + + #when running 't/TEST t/dir' shell tab completion adds a / + #dir//foo output is annoying, fix that. + s:/+:/:g for @tests; + + # remove *.php tests unless we can run them with php + if (! Apache::TestConfig::which('php')) { + warning(join ' - ', 'skipping *.php tests', + 'make sure php is in your PATH'); + @tests = grep { not /\.php$/ } @tests; + } + elsif (! $phpclient) { + warning(join ' - ', 'skipping *.php tests', + 'Test::Harness 2.38 not available'); + @tests = grep { not /\.php$/ } @tests; + } + + return @tests; +} + +sub run { + my $self = shift; + my $args = shift || {}; + my $formatter = TAP::Formatter::Console->new; + my $agg = TAP::Parser::Aggregator->new; + my $verbose = $args->{verbose} && $args->{verbose}; + my $php_harness = TAP::Harness->new + ({exec => $self->command_line(), + verbosity => $verbose}); + my $perl_harness = TAP::Harness->new + ({verbosity => $verbose}); + my @tests = $self->get_tests($args, @_); + + $agg->start(); + $php_harness->aggregate_tests($agg, grep {m{\.php$}} @tests); + $perl_harness->aggregate_tests($agg, grep {m{\.t$}} @tests); + $agg->stop(); + + $formatter->summary($agg); +} + +sub command_line { + my $self = shift; + + my $server_root = Apache::Test::vars('serverroot'); + + my $conf = catfile($server_root, 'conf'); + + my $ini = catfile($conf, 'php.ini'); + + my $php = Apache::TestConfig::which('php') || + die 'no php executable found in ' . $ENV{PATH}; + + return ["env", "SERVER_ROOT=$server_root", + $php, "--php-ini", $ini, "--define", "include_path=$conf"]; +} + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestMB.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestMB.pm new file mode 100644 index 0000000..51254a8 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestMB.pm @@ -0,0 +1,410 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package Apache::TestMB; + +use strict; +use vars qw(@ISA); +use Module::Build 0.18; +use Apache::Test (); +use Apache::TestConfig (); +@ISA = qw(Module::Build); + +sub new { + my $pkg = shift; + my($argv, $vars) = + Apache::TestConfig::filter_args(\@ARGV, \%Apache::TestConfig::Usage); + @ARGV = @$argv; + my $self = $pkg->SUPER::new(@_); + $self->{properties}{apache_test_args} = $vars; + $self->{properties}{apache_test_script} ||= 't/TEST'; + $self->generate_script; + return $self; +} + +sub valid_property { + return 1 if defined $_[1] && + ($_[1] eq 'apache_test_args' || $_[1] eq 'apache_test_script'); + shift->SUPER::valid_property(@_); +} + +sub apache_test_args { + my $self = shift; + $self->{properties}{apache_test_args} = shift if @_; + return $self->{properties}{apache_test_args}; +} + +sub apache_test_script { + my $self = shift; + $self->{properties}{apache_test_script} = shift if @_; + return $self->{properties}{apache_test_script}; +} + +sub ACTION_test_clean { + my $self = shift; + # XXX I'd love to do this without t/TEST. + $self->do_system( $self->perl, $self->_bliblib, + $self->localize_file_path($self->apache_test_script), + '-clean'); +} + +sub ACTION_clean { + my $self = shift; + $self->depends_on('test_clean'); + $self->SUPER::ACTION_clean(@_); +} + +sub ACTION_run_tests { + my $self = shift; + $self->depends_on('test_clean'); + # XXX I'd love to do this without t/TEST. + $self->do_system($self->perl, $self->_bliblib, + $self->localize_file_path($self->apache_test_script), + '-bugreport', '-verbose=' . ($self->verbose || 0)); +} + +sub ACTION_testcover { + my $self = shift; + + unless ($self->find_module_by_name('Devel::Cover', \@INC)) { + warn("Cannot run testcover action unless Devel::Cover " + . "is installed.\n" . + "Don't forget to rebuild your Makefile after " + . "installing Devel::Cover\n"); + return; + } + + $self->add_to_cleanup('coverage', 'cover_db'); + + my $atdir = $self->localize_file_path("$ENV{HOME}/.apache-test"); + local $Test::Harness::switches = + local $Test::Harness::Switches = + local $ENV{HARNESS_PERL_SWITCHES} = "-MDevel::Cover=+inc,'$atdir'"; + local $ENV{APACHE_TEST_EXTRA_ARGS} = "-one-process"; + + $self->depends_on('test'); + $self->do_system('cover'); +} + +sub ACTION_test_config { + my $self = shift; + $self->do_system($self->perl, $self->_bliblib, + $self->localize_file_path($self->apache_test_script), + '-conf', '-verbose=' . ($self->verbose || 0)); +} + +sub _bliblib { + my $self = shift; + return ( + '-I', File::Spec->catdir($self->base_dir, $self->blib, 'lib'), + '-I', File::Spec->catdir($self->base_dir, $self->blib, 'arch'), + ); +} + +sub ACTION_test { + my $self = shift; + $self->depends_on('code'); + $self->depends_on('run_tests'); + $self->depends_on('test_clean'); +} + +sub _cmodules { + my ($self, $action) = @_; + die "The cmodules" . ( $action ne 'all' ? "_$action" : '') + . " action is not yet implemented"; + # XXX TBD. + $self->depends_on('test_config'); + my $start_dir = $self->cwd; + chdir $self->localize_file_path('c-modules'); + # XXX How do we get Build.PL to be generated instead of Makefile? + # Subclass Apache::TestConfigC, perhaps? + $self->do_system('Build.PL', $action); + chdir $start_dir; +} + +sub ACTION_cmodules { shift->_cmodues('all') } +sub ACTION_cmodules_clean { shift->_cmodues('clean') } + +# XXX I'd love to make this optional. +sub generate_script { + my $self = shift; + + # If a file name has been passed in, use it. Otherwise, use the + # one set up when the Apache::TestMB object was created. + my $script = $self->localize_file_path($_[0] + ? $self->apache_test_script(shift) + : $self->apache_test_script + ); + + # We need a class to run the tests from t/TEST. + my $class = pop || 'Apache::TestRunPerl'; + + # Delete any existing instance of the file. + unlink $script if -e $script; + + # Start the contents of t/TEST. + my $body = "BEGIN { eval { require blib && blib->import; } }\n"; + + # Configure the arguments for t/TEST. + while (my($k, $v) = each %{ $self->apache_test_args }) { + $v =~ s/\|/\\|/g; + $body .= "\n\$Apache::TestConfig::Argv{'$k'} = q|$v|;\n"; + } + + my $infile = "$script.PL"; + if (-f $infile) { + # Use the existing t/TEST.PL. + my $in = Symbol::gensym(); + open $in, "$infile" or die "Couldn't open $infile: $!"; + local $/; + $body .= <$in>; + close $in; + } else { + # Create t/TEST from scratch. + $body .= join "\n", + Apache::TestConfig->perlscript_header, + "use $class ();", + "$class->new->run(\@ARGV);"; + } + + # Make it so! + print "Generating test running script $script\n" if $self->verbose; + Apache::Test::basic_config()->write_perlscript($script, $body); + $self->add_to_cleanup($self->apache_test_script); +} + + +1; +__END__ + +=head1 NAME + +Apache::TestMB - Subclass of Module::Build to support Apache::Test + +=head1 SYNOPSIS + +Standard process for building & installing modules: + + perl Build.PL + ./Build + ./Build test + ./Build install + +Or, if you're on a platform (like DOS or Windows) that doesn't like the "./" +notation, you can do this: + + perl Build.PL + perl Build + perl Build test + perl Build install + +=head1 DESCRIPTION + +This class subclasses C<Module::Build> to add support for testing +Apache integration with Apache::Test. It is broadly based on +C<Apache::TestMM>, and as such adds a number of build actions to a the +F<Build> script, while simplifying the process of creating F<Build.PL> +scripts. + +Here's how to use C<Apache::TestMB> in a F<Build.PL> script: + + use Module::Build; + + my $build_pkg = eval { require Apache::TestMB } + ? 'Apache::TestMB' : 'Module::Build'; + + my $build = $build_pkg->new( + module_name => 'My::Module', + ); + $build->create_build_script; + +This is identical to how C<Module::Build> is used. Not all target +systems may have C<Apache::Test> (and therefore C<Apache::TestMB> +installed, so we test for it to be installed, first. But otherwise, +its use can be exactly the same. Consult the +L<Module::Build|Module::Build> documentation for more information on +how to use it; L<Module::Build::Cookbook|Module::Build::Cookbook> may +be especially useful for those looking to migrate from +C<ExtUtils::MakeMaker>. + +=head1 INTERFACE + +=head2 Build + +With the above script, users can build your module in the usual +C<Module::Build> way: + + perl Build.PL + ./Build + ./Build test + ./Build install + +If C<Apache::TestMB> is installed, then Apache will be started before +tests are run by the C<test> action, and shut down when the tests +complete. Note that C<Build.PL> can be called C<Apache::Test>-specific +options in addition to the usual C<Module::Build> options. For +example: + + perl Build.PL -apxs /usr/local/apache/bin/apxs + +Consult the L<Apache::Test|Apache::Test> documentation for a complete +list of options. + +In addition to the actions provided by C<Module::Build> (C<build>, +C<clean>, C<code>, C<test>, etc.), C<Apache::TestMB> adds a few extra +actions: + +=over 4 + +=item test_clean + +This action cleans out the files generated by the test script, +F<t/TEST>. It is also executed by the C<clean> action. + +=item run_tests + +This action actually the tests by executing the test script, +F<t/TEST>. It is executed by the C<test> action, so most of the time +it won't be executed directly. + +=item testcover + +C<Apache::TestMB> overrides this action from C<Module::Build> in order to +prevent the C<Apache::Test> preference files from being included in the test +coverage. + +=back + +=head2 Constructor + +=head3 new + +The C<new()> constructor takes all the same arguments as its parent in +C<Module::Build>, but can optionally accept one other parameter: + +=over + +=item apache_test_script + +The name of the C<Apache::Test> test script. The default value is +F<t/TEST>, which will work in the vast majority of cases. If you wish +to specify your own file name, do so with a relative file name using +Unix-style paths; the file name will automatically be converted for +the local platform. + +=back + +When C<new()> is called it does the following: + +=over 4 + +=item * + +Processes the C<Apache::Test>-specific options in C<@ARGV>. See the +L<Apache::Test|Apache::Test> documentation for a complete list of +options. + +=item * + +Sets the name of the C<Apache::Test> test script to F<t/TEST>, unless +it was explicitly specified by the C<apache_test_script> parameter. + +=item * + +Calls C<generate_script()> to generate C<Apache::Test> test script, +usually F<t/TEST>. + +=back + +=head2 Instance Methods + +=head3 apache_test_args + +Returns a hash reference containing all of the settings specified by +options passed to F<Build.PL>, or explicitly added to C<@ARGV> in +F<Build.PL>. Consult the L<Apache::Test|Apache::Test> documentation +for a complete list of options. + +=head3 apache_test_script + +Gets or sets the file name of the C<Apache::Test> test script. + +=head3 generate_script + + $build->generate_script; + $build->generate_script('t/FOO'); + $build->generate_script(undef, 'Apache::TestRun'); + +This method is called by C<new()>, so in most cases it can be +ignored. If you'd like it to use other than the default arguments, you +can call it explicitly in F<Build.PL> and pass it the arguments you +desire. It takes two optional arguments: + +=over 4 + +=item * + +The name of the C<Apache::Test> test script. Defaults to the value +returned by C<apache_test_script()>. + +=item * + +The name of an C<Apache::Test> test running class. Defaults to +C<Apache::TestRunPerl>. + +=back + +If there is an existing F<t/TEST.PL> (or a script with the same name +as specified by the C<apache_test_script> parameter but with F<.PL> +appended to it), then that script will be used as the template for the +test script. Otherwise, a simple test script will be written similar +to what would be written by C<Apache::TestRun::generate_script()> +(although that function is not aware of the arguments passed to +F<Build.PL>, so use this one instead!). + +=head1 SEE ALSO + +=over 4 + +=item L<Apache::TestRequest|Apache::TestRequest> + +Demonstrates how to write tests to send requests to the Apache server +run by C<./Build test>. + +=item L<Module::Build|Module::Build> + +The parent class for C<Apache::TestMB>; consult it's documentation for +more on its interface. + +=item L<http://www.perl.com/pub/a/2003/05/22/testing.html> + +This article by Geoffrey Young explains how to configure Apache and +write tests for your module using Apache::Test. Just use +C<Apache::TestMB> instead of C<Apache::TestMM> to update it for use +with C<Module::Build>. + +=back + +=head1 AUTHOR + +David Wheeler + +Questions can be asked at the test-dev <at> httpd.apache.org list. For +more information see: I<http://httpd.apache.org/test/> and +I<http://perl.apache.org/docs/general/testing/testing.html>. + +=cut + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestMM.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestMM.pm new file mode 100644 index 0000000..f9b862f --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestMM.pm @@ -0,0 +1,258 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestMM; + +use strict; +use warnings FATAL => 'all'; + +use Config; +use Apache::TestConfig (); +use Apache::TestTrace; +use Apache::TestSmoke; + +sub import { + my $class = shift; + + for my $section (@_) { + unless (defined &$section) { + die "unknown Apache::TestMM section: $section"; + } + no strict 'refs'; + my $sub = "MY::$section"; + # Force aliasing, since previous WriteMakefile might have + # moved it + undef &$sub if defined &$sub; + *$sub = \&{$section}; + } +} + +sub add_dep { + my($string, $targ, $add) = @_; + $$string =~ s/($targ\s+::)/$1 $add /; +} + +sub clean { + my $self = shift; + my $string = $self->MM::clean(@_); + add_dep(\$string, clean => 'test_clean'); + $string; +} + +sub test { + my $self = shift; + my $env = Apache::TestConfig->passenv_makestr(); + + my $tests = "TEST_FILES =\n"; + + if (ref $self && exists $self->{'test'}) { + $tests = 'TEST_FILES = ' . $self->{'test'}->{'TESTS'} . "\n"; + } + + my $preamble = Apache::TestConfig::WIN32 ? "" : <<EOF; +PASSENV = $env +EOF + + my $cover; + + if (eval { require Devel::Cover }) { + my $atdir = File::Spec->catfile($ENV{HOME}, '.apache-test'); + + my $cover_exec = Apache::TestConfig::which("cover"); + + my @cover = ("", "testcover :", ); + push @cover, "\t-\@$cover_exec -delete" if $cover_exec; + push @cover, "\t-HARNESS_PERL_SWITCHES=-MDevel::Cover=+inc,$atdir \\", + "\tAPACHE_TEST_EXTRA_ARGS=-one-process \$(MAKE) test"; + push @cover, "\t-\@$cover_exec" if $cover_exec; + $cover = join "\n", @cover, ""; + } + else { + + $cover = <<'EOF'; + +testcover : + @echo "Cannot run testcover action unless Devel::Cover is installed" + @echo "Don't forget to rebuild your Makefile after installing Devel::Cover" +EOF + } + + return $preamble . $tests . <<'EOF' . $cover; +TEST_VERBOSE = 0 + +test_clean : + $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \ + t/TEST $(APACHE_TEST_EXTRA_ARGS) -clean + +run_tests : + $(PASSENV) \ + $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \ + t/TEST $(APACHE_TEST_EXTRA_ARGS) -bugreport -verbose=$(TEST_VERBOSE) $(TEST_FILES) + +test :: pure_all test_clean run_tests + +test_config : + $(PASSENV) \ + $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \ + t/TEST $(APACHE_TEST_EXTRA_ARGS) -conf + +cmodules: test_config + cd c-modules && $(MAKE) all + +cmodules_clean: test_config + cd c-modules && $(MAKE) clean +EOF + +} + +sub generate_script { + my $file = shift; + + unlink $file if -e $file; + + my $body = "BEGIN { eval { require blib && blib->import; } }\n"; + + my %args = @Apache::TestMM::Argv; + while (my($k, $v) = each %args) { + $v =~ s/\|/\\|/g; + $body .= "\n\$Apache::TestConfig::Argv{'$k'} = q|$v|;\n"; + } + + my $in = Symbol::gensym(); + open $in, "$file.PL" or die "Couldn't open $file.PL: $!"; + { + local $/; + $body .= <$in>; + } + close $in; + + info "generating script $file"; + Apache::Test::basic_config()->write_perlscript($file, $body); + Apache::TestSmoke->generate_script; +} + +sub filter_args { + my($argv, $vars) = + Apache::TestConfig::filter_args(\@ARGV, \%Apache::TestConfig::Usage); + @ARGV = @$argv; + @Apache::TestMM::Argv = %$vars; +} + +1; + +=head1 NAME + +Apache::TestMM - Provide MakeMaker Wrapper Methods + +=head1 SYNOPSIS + + require Apache::TestMM; + + # import MY::test and MY::clean overrides for MM + Apache::TestMM->import(qw(test clean)); + + # parse command line args + Apache::TestMM::filter_args(); + + # autogenerate the script + Apache::TestMM::generate_script('t/TEST'); + +=head1 DESCRIPTION + +C<Apache::TestMM> provides wrappers for the C<ExtUtils::MakeMaker> +craft, making it easier to extend the autogenerated F<Makefile> with +C<Apache::Test>. + +=head1 FUNCTIONS + +=head2 C<import> + + use Apache::TestMM qw(test clean); + +or: + + Apache::TestMM->import(qw(test clean)); + +Imports C<MY::> overrides for the default C<ExtUtils::MakeMaker> +I<test> and I<clean> targets, as if you have defined: + + sub MY::test {...} + sub MY::clean {...} + +in F<Makefile.PL>. C<Apache::TestMM> does this for you so that these Makefile +targets will run the Apache server and the tests for it, and clean up after +its mess. + +=head2 C<filter_args> + + push @ARGV, '-apxs', $apxs_path; + Apache::TestMM::filter_args(); + WriteMakefile(...); + +When C<WriteMakefile()> is called it parses C<@ARGV>, hoping to find +special options like C<PREFIX=/home/stas/perl>. C<Apache::Test> +accepts a lot of configuration options of its own. When +C<Apache::TestMM::filter_args()> is called, it removes any +C<Apache::Test>-specific options from C<@ARGV> and stores them +internally, so when C<WriteMakefile()> is called they aren't in +C<@ARGV> and thus won't be processed by C<WriteMakefile()>. + +The options can be set when F<Makefile.PL> is called: + + % perl Makefile.PL -apxs /path/to/apxs + +Or you can push them manually to C<@ARGV> from the code: + + push @ARGV, '-apxs', $apxs_path; + +When: + + Apache::TestMM::generate_script('t/TEST'); + +is called, C<Apache::Test>-specific options extracted by +C<Apache::TestMM::filter_args()> are written to the autogenerated +file. In our example, the autogenerated F<t/TEST> will include: + + %Apache::TestConfig::Argv = qw(apxs /path/to/apxs); + +which is going to be used by the C<Apache::Test> runtime. + +The other frequently used options are: C<-httpd>, telling where to +find the httpd (usually when the C<-apxs> option is not used), +C<-libmodperl> to use a specific mod_perl shared object (if your +mod_perl is built as DSO), C<-maxclients> to change the default number +of the configured C<MaxClients> directive, C<-port> to start the +server on a specific port, etc. To get the complete list of available +configuration options and their purpose and syntax, run: + + % perl -MApache::TestConfig -le 'Apache::TestConfig::usage()' + +You may wish to document some of these in your application's F<README> +file, especially the C<-apxs> and C<-httpd> options. + + +=head2 C<generate_script> + + Apache::TestMM::generate_script('t/TEST'); + +C<generate_script()> accepts the name of the script to generate and +will look for a template with the same name and suffix I<.PL>. So in +our example it'll look for F<t/TEST.PL>. The autogenerated script +F<t/TEST> will include the contents of F<t/TEST.PL>, and special +directives, including any configuration options passed via +C<L<filter_args()|/C_filter_args_>> called from F<Makefile.PL>, special +fixup code, etc. + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestPerlDB.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestPerlDB.pm new file mode 100644 index 0000000..ba2e810 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestPerlDB.pm @@ -0,0 +1,53 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#no 'package Apache::TestPerlDB.pm' here, else we change perldb's package +use strict; + +sub Apache::TestPerlDB::lwpd { + print Apache::TestRequest::lwp_debug(shift || 1); +} + +sub Apache::TestPerlDB::bok { + my $n = shift || 1; + print "breakpoint set at test $n\n"; + DB::cmd_b_sub('ok', "\$Test::ntest == $n"); +} + +my %help = ( + lwpd => 'Set the LWP debug level for Apache::TestRequest', + bok => 'Set breakpoint at test n', +); + +my $setup_db_aliases = sub { + my $package = 'Apache::TestPerlDB'; + my @cmds; + no strict 'refs'; + + while (my($name, $val) = each %{"$package\::"}) { + next unless defined &$val; + *{"main::$name"} = \&{$val}; + push @cmds, $name; + } + + print "$package added perldb commands:\n", + map { " $_ - $help{$_}\n" } @cmds; + +}; + +$setup_db_aliases->(); + +1; +__END__ diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestReport.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestReport.pm new file mode 100644 index 0000000..eb575ea --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestReport.pm @@ -0,0 +1,181 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestReport; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test (); +use Apache::TestConfig (); + +use File::Spec::Functions qw(catfile); +use File::Find; + +sub new { + my $class = shift; + bless { @_ }, $class; +} + +# generate t/REPORT script (or a different filename) which will drive +# Apache::TestReport +sub generate_script { + my ($class, $file) = @_; + + $file ||= catfile 't', 'REPORT'; + + my $content = join "\n", + "BEGIN { eval { require blib && blib->import; } }", + Apache::TestConfig->perlscript_header, + "use $class;", + "$class->new(\@ARGV)->run;"; + + Apache::Test::basic_config()->write_perlscript($file, $content); +} + +sub replace { + my($self, $template) = @_; + + $template =~ s{\@(\w+)\@} { + my $method = lc $1; + eval { $self->$method() } || $self->{$1} || ''; + }eg; + + $template; +} + +sub run { + my $self = shift; + + print $self->replace($self->template); +} + +sub config { Apache::TestConfig::as_string() } + +sub report_to { 'test-dev@httpd.apache.org' } + +sub postit_note { + my $self = shift; + + my($to, $where) = split '@', $self->report_to; + + return <<EOF; +Note: Complete the rest of the details and post this bug report to +$to <at> $where. To subscribe to the list send an empty +email to $to-subscribe\@$where. +EOF +} + +sub executable { $0 } + +my $core_dump; +sub core_dump { + my $self = shift; + + $core_dump = ""; + + if (eval { require Devel::GDB }) { + find(\&dump_core_file, 't') + } + + $core_dump || ' [CORE TRACE COMES HERE]'; +} + +sub dump_core_file { + return unless /^core(\.\d+)?$/; + + my $core = $_; + my $gdb = new Devel::GDB (); + my $test_config = Apache::TestConfig->new({thaw=>1}); + my $httpd = $test_config->{vars}->{httpd}; + + return unless defined $httpd; + + $core_dump .= join '', + $gdb->get("file $httpd"), + $gdb->get('sharedlibrary'), + $gdb->get("core $core"), + $gdb->get('info threads'), + $gdb->get('thread apply all bt'); +} + +sub date { scalar gmtime() . " GMT" } + +sub template { +<<'EOI' +-------------8<---------- Start Bug Report ------------8<---------- +1. Problem Description: + + [DESCRIBE THE PROBLEM HERE] + +2. Used Components and their Configuration: + +@CONFIG@ + +3. This is the core dump trace: (if you get a core dump): + +@CORE_DUMP@ + +This report was generated by @EXECUTABLE@ on @DATE@. + +-------------8<---------- End Bug Report --------------8<---------- + +@POSTIT_NOTE@ + +EOI + +} + +1; +__END__ + +=head1 NAME + +Apache::TestReport - A parent class for generating bug/success reports + +=head1 Synopsis + + use Apache::TestReport; + Apache::TestReport->new(@ARGV)->run; + +=head1 Description + +This class is used to generate a bug or a success report, providing +information about the system the code was running on. + +=head1 Overridable Methods + +=head2 config + +return the information about user's system + +=head2 report_to + +return a string containing the email address the report should be sent +to + +=head2 postit_note + +return a string to close the report with, e.g.: + + my($to, $where) = split '@', $self->report_to; + return <<EOF; + Note: Complete the rest of the details and post this bug report to + $to <at> $where. To subscribe to the list send an empty + email to $to-subscribe\@$where. + + +=cut + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestReportPerl.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestReportPerl.pm new file mode 100644 index 0000000..befd8ff --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestReportPerl.pm @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestReportPerl; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestReport (); +use ModPerl::Config (); + +# a subclass of Apache::TestReport that generates a bug report script +use vars qw(@ISA); +@ISA = qw(Apache::TestReport); + +sub config { + ModPerl::Config::as_string(); +} + +sub report_to { + my $self = shift; + my $pkg = ref $self; + die "you need to implement $pkg\::report_to() to return the " . + "contact email address of your project"; +} + +1; +__END__ diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRequest.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRequest.pm new file mode 100644 index 0000000..55d32c8 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRequest.pm @@ -0,0 +1,1258 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestRequest; + +use strict; +use warnings FATAL => 'all'; + +BEGIN { + $ENV{PERL_LWP_USE_HTTP_10} = 1; # default to http/1.0 + $ENV{APACHE_TEST_HTTP_09_OK} ||= 0; # 0.9 responses are ok +} + +use Apache::Test (); +use Apache::TestConfig (); + +use Carp; + +use constant TRY_TIMES => 200; +use constant INTERP_KEY => 'X-PerlInterpreter'; +use constant UA_TIMEOUT => 60 * 10; #longer timeout for debugging + +my $have_lwp = 0; + +# APACHE_TEST_PRETEND_NO_LWP=1 pretends that LWP is not available so +# one can test whether the test suite survives if the user doesn't +# have lwp installed +unless ($ENV{APACHE_TEST_PRETEND_NO_LWP}) { + $have_lwp = eval { + require LWP::UserAgent; + require HTTP::Request::Common; + + unless (defined &HTTP::Request::Common::OPTIONS) { + package HTTP::Request::Common; + no strict 'vars'; + *OPTIONS = sub { _simple_req(OPTIONS => @_) }; + push @EXPORT, 'OPTIONS'; + } + 1; + }; +} + +unless ($have_lwp) { + require Apache::TestClient; +} + +sub has_lwp { $have_lwp } + +unless ($have_lwp) { + #need to define the shortcuts even though the wont be used + #so Perl can parse test scripts + @HTTP::Request::Common::EXPORT = qw(GET HEAD POST PUT OPTIONS); +} + +sub install_http11 { + eval { + die "no LWP" unless $have_lwp; + LWP->VERSION(5.60); #minimal version + require LWP::Protocol::http; + #LWP::Protocol::http10 is used by default + LWP::Protocol::implementor('http', 'LWP::Protocol::http'); + }; +} + +use vars qw(@EXPORT @ISA $RedirectOK $DebugLWP); + +require Exporter; +*import = \&Exporter::import; +@EXPORT = @HTTP::Request::Common::EXPORT; + +@ISA = qw(LWP::UserAgent); + +my $UA; +my $REDIR = $have_lwp ? undef : 1; +my $conn_opts = {}; + +sub module { + my $module = shift; + $Apache::TestRequest::Module = $module if $module; + $Apache::TestRequest::Module; +} + +sub scheme { + my $scheme = shift; + $Apache::TestRequest::Scheme = $scheme if $scheme; + $Apache::TestRequest::Scheme; +} + +sub module2path { + my $package = shift; + + # httpd (1.3 && 2) / winFU have problems when the first path's + # segment includes ':' (security precaution which breaks the rfc) + # so we can't use /TestFoo::bar as path_info + (my $path = $package) =~ s/::/__/g; + + return $path; +} + +sub module2url { + my $module = shift; + my $opt = shift || {}; + my $scheme = $opt->{scheme} || 'http'; + my $path = exists $opt->{path} ? $opt->{path} : module2path($module); + + module($module); + + my $config = Apache::Test::config(); + my $hostport = hostport($config); + + $path =~ s|^/||; + return "$scheme://$hostport/$path"; +} + +sub user_agent { + my $args = {@_}; + + if (delete $args->{reset}) { + $UA = undef; + } + + if (exists $args->{requests_redirectable}) { + my $redir = $args->{requests_redirectable}; + if (ref $redir and (@$redir > 1 or $redir->[0] ne 'POST')) { + # Set our internal flag if there's no LWP. + $REDIR = $have_lwp ? undef : 1; + } elsif ($redir) { + if ($have_lwp) { + $args->{requests_redirectable} = [ qw/GET HEAD POST/ ]; + $REDIR = undef; + } else { + # Set our internal flag. + $REDIR = 1; + } + } else { + # Make sure our internal flag is false if there's no LWP. + $REDIR = $have_lwp ? undef : 0; + } + } + + $args->{keep_alive} ||= $ENV{APACHE_TEST_HTTP11}; + + if ($args->{keep_alive}) { + install_http11(); + eval { + require LWP::Protocol::https; #https10 is the default + LWP::Protocol::implementor('https', 'LWP::Protocol::https'); + }; + } + + # in LWP 6, verify_hostname defaults to on, so SSL_ca_file + # needs to be set accordingly + if ($have_lwp and $LWP::VERSION >= 6.0 and not exists $args->{ssl_opts}->{SSL_ca_file}) { + my $vars = Apache::Test::vars(); + my $cafile = "$vars->{sslca}/$vars->{sslcaorg}/certs/ca.crt"; + $args->{ssl_opts}->{SSL_ca_file} = $cafile; + # IO::Socket:SSL raw socket compatibility + $conn_opts->{SSL_ca_file} = $cafile; + } + + eval { $UA ||= __PACKAGE__->new(%$args); }; +} + +sub user_agent_request_num { + my $res = shift; + $res->header('Client-Request-Num') || #lwp 5.60 + $res->header('Client-Response-Num'); #lwp 5.62+ +} + +sub user_agent_keepalive { + $ENV{APACHE_TEST_HTTP11} = shift; +} + +sub do_request { + my($ua, $method, $url, $callback) = @_; + my $r = HTTP::Request->new($method, resolve_url($url)); + my $response = $ua->request($r, $callback); + lwp_trace($response); +} + +sub hostport { + my $config = shift || Apache::Test::config(); + my $vars = $config->{vars}; + local $vars->{scheme} = + $Apache::TestRequest::Scheme || $vars->{scheme}; + my $hostport = $config->hostport; + + my $default_hostport = join ':', $vars->{servername}, $vars->{port}; + if (my $module = $Apache::TestRequest::Module) { + $hostport = $module eq 'default' + ? $default_hostport + : $config->{vhosts}->{$module}->{hostport}; + } + + $hostport || $default_hostport; +} + +sub resolve_url { + my $url = shift; + Carp::croak("no url passed") unless defined $url; + + return $url if $url =~ m,^(\w+):/,; + $url = "/$url" unless $url =~ m,^/,; + + my $vars = Apache::Test::vars(); + + local $vars->{scheme} = + $Apache::TestRequest::Scheme || $vars->{scheme} || 'http'; + + scheme_fixup($vars->{scheme}); + + my $hostport = hostport(); + + return "$vars->{scheme}://$hostport$url"; +} + +my %wanted_args = map {$_, 1} qw(username password realm content filename + redirect_ok cert); + +sub wanted_args { + \%wanted_args; +} + +sub redirect_ok { + my $self = shift; + if ($have_lwp) { + # Return user setting or let LWP handle it. + return $RedirectOK if defined $RedirectOK; + return $self->SUPER::redirect_ok(@_); + } + + # No LWP. We don't support redirect on POST. + return 0 if $self->method eq 'POST'; + # Return user setting or our internal calculation. + return $RedirectOK if defined $RedirectOK; + return $REDIR; +} + +my %credentials; + +#subclass LWP::UserAgent +sub new { + my $self = shift->SUPER::new(@_); + + lwp_debug(); #init from %ENV (set by Apache::TestRun) + + my $config = Apache::Test::config(); + if (my $proxy = $config->configure_proxy) { + #t/TEST -proxy + $self->proxy(http => "http://$proxy"); + } + + $self->timeout(UA_TIMEOUT); + + $self; +} + +sub credentials { + my $self = shift; + return $self->get_basic_credentials(@_); +} + +sub get_basic_credentials { + my($self, $realm, $uri, $proxy) = @_; + + for ($realm, '__ALL__') { + next unless $_ && $credentials{$_}; + return @{ $credentials{$_} }; + } + + return (undef,undef); +} + +sub vhost_socket { + my $module = shift; + local $Apache::TestRequest::Module = $module if $module; + + my $hostport = hostport(Apache::Test::config()); + + my($host, $port) = split ':', $hostport; + my(%args) = (PeerAddr => $host, PeerPort => $port); + + if ($module and ($module =~ /ssl/ || $module eq 'h2')) { + require IO::Socket::SSL; + # Add all conn_opts to args + map {$args{$_} = $conn_opts->{$_}} keys %{$conn_opts}; + return IO::Socket::SSL->new(%args, Timeout => UA_TIMEOUT); + } + else { + require IO::Socket; + return IO::Socket::INET->new(%args); + } +} + +#IO::Socket::SSL::getline does not correctly handle OpenSSL *_WANT_*. +#Could care less about performance here, just need a getline() +#that returns the same results with or without ssl. +#Inspired from Net::SSLeay::ssl_read_all(). +my %getline = ( + 'IO::Socket::SSL' => sub { + my $self = shift; + # _get_ssl_object in IO::Socket::SSL only meant for internal use! + # But we need to compensate for unsufficient getline impl there. + my $ssl = $self->_get_ssl_object; + my ($got, $rv, $errs); + my $reply = ''; + + while (1) { + ($got, $rv) = Net::SSLeay::read($ssl, 1); + if (! defined $got) { + my $err = Net::SSLeay::get_error($ssl, $rv); + if ($err != Net::SSLeay::ERROR_WANT_READ() and + $err != Net::SSLeay::ERROR_WANT_WRITE()) { + $errs = Net::SSLeay::print_errs('SSL_read'); + last; + } + next; + } + last if $got eq ''; # EOF + $reply .= $got; + last if $got eq "\n"; + } + + wantarray ? ($reply, $errs) : $reply; + }, +); + +sub getline { + my $sock = shift; + my $class = ref $sock; + my $method = $getline{$class} || 'getline'; + $sock->$method(); +} + +sub socket_trace { + my $sock = shift; + return unless $sock->can('get_peer_certificate'); + + #like having some -v info + my $cert = $sock->get_peer_certificate; + print "#Cipher: ", $sock->get_cipher, "\n"; + print "#Peer DN: ", $cert->subject_name, "\n"; +} + +sub prepare { + my $url = shift; + + if ($have_lwp) { + user_agent(); + $url = resolve_url($url); + } + else { + lwp_debug() if $ENV{APACHE_TEST_DEBUG_LWP}; + } + + my($pass, $keep) = Apache::TestConfig::filter_args(\@_, \%wanted_args); + + %credentials = (); + if (defined $keep->{username}) { + $credentials{$keep->{realm} || '__ALL__'} = + [$keep->{username}, $keep->{password}]; + } + if (defined(my $content = $keep->{content})) { + if ($content eq '-') { + $content = join '', <STDIN>; + } + elsif ($content =~ /^x(\d+)$/) { + $content = 'a' x $1; + } + push @$pass, content => $content; + } + if (exists $keep->{cert}) { + set_client_cert($keep->{cert}); + } + + return ($url, $pass, $keep); +} + +sub UPLOAD { + my($url, $pass, $keep) = prepare(@_); + + local $RedirectOK = exists $keep->{redirect_ok} + ? $keep->{redirect_ok} + : $RedirectOK; + + if ($keep->{filename}) { + return upload_file($url, $keep->{filename}, $pass); + } + else { + return upload_string($url, $keep->{content}); + } +} + +sub UPLOAD_BODY { + UPLOAD(@_)->content; +} + +sub UPLOAD_BODY_ASSERT { + content_assert(UPLOAD(@_)); +} + +#lwp only supports files +sub upload_string { + my($url, $data) = @_; + + my $CRLF = "\015\012"; + my $bound = 742617000027; + my $req = HTTP::Request->new(POST => $url); + + my $content = join $CRLF, + "--$bound", + "Content-Disposition: form-data; name=\"HTTPUPLOAD\"; filename=\"b\"", + "Content-Type: text/plain", "", + $data, "--$bound--", ""; + + $req->header("Content-Length", length($content)); + $req->content_type("multipart/form-data; boundary=$bound"); + $req->content($content); + + $UA->request($req); +} + +sub upload_file { + my($url, $file, $args) = @_; + + my $content = [@$args, filename => [$file]]; + + $UA->request(HTTP::Request::Common::POST($url, + Content_Type => 'form-data', + Content => $content, + )); +} + +#useful for POST_HEAD and $DebugLWP (see below) +sub lwp_as_string { + my($r, $want_body) = @_; + my $content = $r->content; + + unless ($r->isa('HTTP::Request') or + $r->header('Content-Length') or + $r->header('Transfer-Encoding')) + { + $r->header('Content-Length' => length $content); + $r->header('X-Content-length-note' => 'added by Apache::TestRequest'); + } + + $r->content('') unless $want_body; + + (my $string = $r->as_string) =~ s/^/\#/mg; + $r->content($content); #reset + $string; +} + +$DebugLWP = 0; #1 == print METHOD URL and header response for all requests + #2 == #1 + response body + #other == passed to LWP::Debug->import + +sub lwp_debug { + package main; #wtf: else package in perldb changes + my $val = $_[0] || $ENV{APACHE_TEST_DEBUG_LWP}; + + return unless $val; + + if ($val =~ /^\d+$/) { + $Apache::TestRequest::DebugLWP = $val; + return "\$Apache::TestRequest::DebugLWP = $val\n"; + } + else { + my(@args) = @_ ? @_ : split /\s+/, $val; + require LWP::Debug; + LWP::Debug->import(@args); + return "LWP::Debug->import(@args)\n"; + } +} + +sub lwp_trace { + my $r = shift; + + unless ($r->request->protocol) { + #lwp always sends a request, but never sets + #$r->request->protocol, happens deeper in the + #LWP::Protocol::http* modules + my $proto = user_agent_request_num($r) ? "1.1" : "1.0"; + $r->request->protocol("HTTP/$proto"); + } + + my $want_body = $DebugLWP > 1; + print "#lwp request:\n", + lwp_as_string($r->request, $want_body); + + print "#server response:\n", + lwp_as_string($r, $want_body); +} + +sub lwp_call { + my($name, $shortcut) = (shift, shift); + + my $r = (\&{$name})->(@_); + + Carp::croak("$name(@_) didn't return a response object") unless $r; + + my $error = ""; + unless ($shortcut) { + #GET, HEAD, POST + if ($r->method eq "POST" && !defined($r->header("Content-Length"))) { + $r->header('Content-Length' => length($r->content)); + } + $r = $UA ? $UA->request($r) : $r; + my $proto = $r->protocol; + if (defined($proto)) { + if ($proto !~ /^HTTP\/(\d\.\d)$/) { + $error = "response had no protocol (is LWP broken or something?)"; + } + if ($1 ne "1.0" && $1 ne "1.1") { + $error = "response had protocol HTTP/$1 (headers not sent?)" + unless ($1 eq "0.9" && $ENV{APACHE_TEST_HTTP_09_OK}); + } + } + } + + if ($DebugLWP and not $shortcut) { + lwp_trace($r); + } + + Carp::croak($error) if $error; + + return $shortcut ? $r->$shortcut() : $r; +} + +my %shortcuts = (RC => sub { shift->code }, + OK => sub { shift->is_success }, + STR => sub { shift->as_string }, + HEAD => sub { lwp_as_string(shift, 0) }, + BODY => sub { shift->content }, + BODY_ASSERT => sub { content_assert(shift) }, +); + +for my $name (@EXPORT) { + my $package = $have_lwp ? + 'HTTP::Request::Common': 'Apache::TestClient'; + + my $method = join '::', $package, $name; + no strict 'refs'; + + next unless defined &$method; + + *$name = sub { + my($url, $pass, $keep) = prepare(@_); + local $RedirectOK = exists $keep->{redirect_ok} + ? $keep->{redirect_ok} + : $RedirectOK; + return lwp_call($method, undef, $url, @$pass); + }; + + while (my($shortcut, $cv) = each %shortcuts) { + my $alias = join '_', $name, $shortcut; + *$alias = sub { lwp_call($name, $cv, @_) }; + } +} + +my @export_std = @EXPORT; +for my $method (@export_std) { + push @EXPORT, map { join '_', $method, $_ } keys %shortcuts; +} + +push @EXPORT, qw(UPLOAD UPLOAD_BODY UPLOAD_BODY_ASSERT); + +sub to_string { + my $obj = shift; + ref($obj) ? $obj->as_string : $obj; +} + +# request an interpreter instance and use this interpreter id to +# select the same interpreter in requests below +sub same_interp_tie { + my($url) = @_; + + my $res = GET($url, INTERP_KEY, 'tie'); + unless ($res->code == 200) { + die sprintf "failed to init the same_handler data (url=%s). " . + "Failed with code=%s, response:\n%s", + $url, $res->code, $res->content; + } + my $same_interp = $res->header(INTERP_KEY); + + return $same_interp; +} + +# run the request though the selected perl interpreter, by polling +# until we found it +# currently supports only GET, HEAD, PUT, POST subs +sub same_interp_do { + my($same_interp, $sub, $url, @args) = @_; + + die "must pass an interpreter id, obtained via same_interp_tie()" + unless defined $same_interp and $same_interp; + + push @args, (INTERP_KEY, $same_interp); + + my $res = ''; + my $times = 0; + my $found_same_interp = ''; + do { + #loop until we get a response from our interpreter instance + $res = $sub->($url, @args); + die "no result" unless $res; + my $code = $res->code; + if ($code == 200) { + $found_same_interp = $res->header(INTERP_KEY) || ''; + } + elsif ($code == 404) { + # try again + } + else { + die sprintf "failed to run the request (url=%s):\n" . + "code=%s, response:\n%s", $url, $code, $res->content; + } + + unless ($found_same_interp eq $same_interp) { + $found_same_interp = ''; + } + + if ($times++ > TRY_TIMES) { #prevent endless loop + die "unable to find interp $same_interp\n"; + } + } until ($found_same_interp); + + return $found_same_interp ? $res : undef; +} + + +sub set_client_cert { + my $name = shift; + my $vars = Apache::Test::vars(); + my $dir = join '/', $vars->{sslca}, $vars->{sslcaorg}; + + if ($name) { + my ($cert, $key) = ("$dir/certs/$name.crt", "$dir/keys/$name.pem"); + # IO::Socket:SSL raw socket compatibility + $conn_opts->{SSL_cert_file} = $cert; + $conn_opts->{SSL_key_file} = $key; + if ($LWP::VERSION >= 6.0) { + # IO::Socket:SSL doesn't look at environment variables + if ($UA) { + $UA->ssl_opts(SSL_cert_file => $cert); + $UA->ssl_opts(SSL_key_file => $key); + } else { + user_agent(ssl_opts => { SSL_cert_file => $cert, + SSL_key_file => $key }); + } + } + } + else { + # IO::Socket:SSL raw socket compatibility + $conn_opts->{SSL_cert_file} = undef; + $conn_opts->{SSL_key_file} = undef; + if ($LWP::VERSION >= 6.0 and $UA) { + $UA->ssl_opts(SSL_cert_file => undef); + $UA->ssl_opts(SSL_key_file => undef); + } + } +} + +# Only for IO::Socket:SSL raw socket compatibility, +# when using user_agent() already done in its +# constructor. +sub set_ca_cert { + my $vars = Apache::Test::vars(); + my $cafile = "$vars->{sslca}/$vars->{sslcaorg}/certs/ca.crt"; + $conn_opts->{SSL_ca_file} = $cafile; +} + +#want news: urls to work with the LWP shortcuts +#but cant find a clean way to override the default nntp port +#by brute force we trick Net::NTTP into calling FixupNNTP::new +#instead of IO::Socket::INET::new, we fixup the args then forward +#to IO::Socket::INET::new + +#also want KeepAlive on for Net::HTTP +#XXX libwww-perl 5.53_xx has: LWP::UserAgent->new(keep_alive => 1); + +sub install_net_socket_new { + my($module, $code) = @_; + + return unless Apache::Test::have_module($module); + + no strict 'refs'; + + my $new; + my $isa = \@{"$module\::ISA"}; + + for (@$isa) { + last if $new = $_->can('new'); + } + + my $fixup_class = "Apache::TestRequest::$module"; + unshift @$isa, $fixup_class; + + *{"$fixup_class\::new"} = sub { + my $class = shift; + my $args = {@_}; + $code->($args); + return $new->($class, %$args); + }; +} + +my %scheme_fixups = ( + 'news' => sub { + return if $INC{'Net/NNTP.pm'}; + eval { + install_net_socket_new('Net::NNTP' => sub { + my $args = shift; + my($host, $port) = split ':', + Apache::TestRequest::hostport(); + $args->{PeerPort} = $port; + $args->{PeerAddr} = $host; + }); + }; + }, +); + +sub scheme_fixup { + my $scheme = shift; + my $fixup = $scheme_fixups{$scheme}; + return unless $fixup; + $fixup->(); +} + +# when the client side simply prints the response body which should +# include the test's output, we need to make sure that the request +# hasn't failed, or the test will be skipped instead of indicating the +# error. +sub content_assert { + my $res = shift; + + return $res->content if $res->is_success; + + die join "\n", + "request has failed (the response code was: " . $res->code . ")", + "see t/logs/error_log for more details\n"; +} + +1; + +=head1 NAME + +Apache::TestRequest - Send requests to your Apache test server + +=head1 SYNOPSIS + + use Apache::Test qw(ok have_lwp); + use Apache::TestRequest qw(GET POST); + use Apache::Constants qw(HTTP_OK); + + plan tests => 1, have_lwp; + + my $res = GET '/test.html'; + ok $res->code == HTTP_OK, "Request is ok"; + +=head1 DESCRIPTION + +B<Apache::TestRequest> provides convenience functions to allow you to +make requests to your Apache test server in your test scripts. It +subclasses C<LWP::UserAgent>, so that you have access to all if its +methods, but also exports a number of useful functions likely useful +for majority of your test requests. Users of the old C<Apache::test> +(or C<Apache::testold>) module, take note! Herein lie most of the +functions you'll need to use to replace C<Apache::test> in your test +suites. + +Each of the functions exported by C<Apache::TestRequest> uses an +C<LWP::UserAgent> object to submit the request and retrieve its +results. The return value for many of these functions is an +HTTP::Response object. See L<HTTP::Response|HTTP::Response> for +documentation of its methods, which you can use in your tests. For +example, use the C<code()> and C<content()> methods to test the +response code and content of your request. Using C<GET>, you can +perform a couple of tests using these methods like this: + + use Apache::Test qw(ok have_lwp); + use Apache::TestRequest qw(GET POST); + use Apache::Constants qw(HTTP_OK); + + plan tests => 2, have_lwp; + + my $uri = "/test.html?foo=1&bar=2"; + my $res = GET $uri; + ok $res->code == HTTP_OK, "Check that the request was OK"; + ok $res->content eq "foo => 1, bar => 2", "Check its content"; + +Note that you can also use C<Apache::TestRequest> with +C<Test::Builder> and its derivatives, including C<Test::More>: + + use Test::More; + # ... + is $res->code, HTTP_OK, "Check that the request was OK"; + is $res->content, "foo => 1, bar => 2", "Check its content"; + +=head1 CONFIGURATION FUNCTION + +You can tell C<Apache::TestRequest> what kind of C<LWP::UserAgent> +object to use for its convenience functions with C<user_agent()>. This +function uses its arguments to construct an internal global +C<LWP::UserAgent> object that will be used for all subsequent requests +made by the convenience functions. The arguments it takes are the same +as for the C<LWP::UserAgent> constructor. See the +C<L<LWP::UserAgent|LWP::UserAgent>> documentation for a complete list. + +The C<user_agent()> function only creates the internal +C<LWP::UserAgent> object the first time it is called. Since this +function is called internally by C<Apache::TestRequest>, you should +always use the C<reset> parameter to force it to create a new global +C<LWP::UserAgent> Object: + + Apache::TestRequest::user_agent(reset => 1, %params); + +C<user_agent()> differs from C<< LWP::UserAgent->new >> in two +additional ways. First, it supports an additional parameter, +C<keep_alive>, which enables connection persistence, where the same +connection is used to process multiple requests (and, according to the +C<L<LWP::UserAgent|LWP::UserAgent>> documentation, has the effect of +loading and enabling the new experimental HTTP/1.1 protocol module). + +And finally, the semantics of the C<requests_redirectable> parameter is +different than for C<LWP::UserAgent> in that you can pass it a boolean +value as well as an array for C<LWP::UserAgent>. To force +C<Apache::TestRequest> not to follow redirects in any of its convenience +functions, pass a false value to C<requests_redirectable>: + + Apache::TestRequest::user_agent(reset => 1, + requests_redirectable => 0); + +If LWP is not installed, then you can still pass in an array reference +as C<LWP::UserAgent> expects. C<Apache::TestRequest> will examine the +array and allow redirects if the array contains more than one value or +if there is only one value and that value is not "POST": + + # Always allow redirection. + my $redir = have_lwp() ? [qw(GET HEAD POST)] : 1; + Apache::TestRequest::user_agent(reset => 1, + requests_redirectable => $redir); + +But note that redirection will B<not> work with C<POST> unless LWP is +installed. It's best, therefore, to check C<have_lwp> before running +tests that rely on a redirection from C<POST>. + +Sometimes it is desireable to have C<Apache::TestRequest> remember +cookies sent by the pages you are testing and send them back to the +server on subsequent requests. This is especially necessary when +testing pages whose functionality relies on sessions or the presence +of preferences stored in cookies. + +By default, C<LWP::UserAgent> does B<not> remember cookies between +requests. You can tell it to remember cookies between request by +adding: + + Apache::TestRequest::user_agent(cookie_jar => {}); + +before issuing the requests. + + +=head1 FUNCTIONS + +C<Apache::TestRequest> exports a number of functions that will likely +prove convenient for use in the majority of your request tests. + + + + +=head2 Optional Parameters + +Each function also takes a number of optional arguments. + +=over 4 + +=item redirect_ok + +By default a request will follow redirects retrieved from the server. To +prevent this behavior, pass a false value to a C<redirect_ok> +parameter: + + my $res = GET $uri, redirect_ok => 0; + +Alternately, if all of your tests need to disable redirects, tell +C<Apache::TestRequest> to use an C<LWP::UserAgent> object that +disables redirects: + + Apache::TestRequest::user_agent( reset => 1, + requests_redirectable => 0 ); + +=item cert + +If you need to force an SSL request to use a particular SSL +certificate, pass the name of the certificate via the C<cert> +parameter: + + my $res = GET $uri, cert => 'my_cert'; + +=item content + +If you need to add content to your request, use the C<content> +parameter: + + my $res = GET $uri, content => 'hello world!'; + +=item filename + +The name of a local file on the file system to be sent to the Apache +test server via C<UPLOAD()> and its friends. + +=back + +=head2 The Functions + +=head3 GET + + my $res = GET $uri; + +Sends a simple GET request to the Apache test server. Returns an +C<HTTP::Response> object. + +You can also supply additional headers to be sent with the request by +adding their name/value pairs after the C<url> parameter, for example: + + my $res = GET $url, 'Accept-Language' => 'de,en-us,en;q=0.5'; + +=head3 GET_STR + +A shortcut function for C<GET($uri)-E<gt>as_string>. + +=head3 GET_BODY + +A shortcut function for C<GET($uri)-E<gt>content>. + +=head3 GET_BODY_ASSERT + +Use this function when your test is outputting content that you need +to check, and you want to make sure that the request was successful +before comparing the contents of the request. If the request was +unsuccessful, C<GET_BODY_ASSERT> will return an error +message. Otherwise it will simply return the content of the request +just as C<GET_BODY> would. + +=head3 GET_OK + +A shortcut function for C<GET($uri)-E<gt>is_success>. + +=head3 GET_RC + +A shortcut function for C<GET($uri)-E<gt>code>. + +=head3 GET_HEAD + +Throws out the content of the request, and returns the string +representation of the request. Since the body has been thrown out, the +representation will consist solely of the headers. Furthermore, +C<GET_HEAD> inserts a "#" at the beginning of each line of the return +string, so that the contents are suitable for printing to STDERR +during your tests without interfering with the workings of +C<Test::Harness>. + +=head3 HEAD + + my $res = HEAD $uri; + +Sends a HEAD request to the Apache test server. Returns an +C<HTTP::Response> object. + +=head3 HEAD_STR + +A shortcut function for C<HEAD($uri)-E<gt>as_string>. + +=head3 HEAD_BODY + +A shortcut function for C<HEAD($uri)-E<gt>content>. Of course, this +means that it will likely return nothing. + +=head3 HEAD_BODY_ASSERT + +Use this function when your test is outputting content that you need +to check, and you want to make sure that the request was successful +before comparing the contents of the request. If the request was +unsuccessful, C<HEAD_BODY_ASSERT> will return an error +message. Otherwise it will simply return the content of the request +just as C<HEAD_BODY> would. + +=head3 HEAD_OK + +A shortcut function for C<GET($uri)-E<gt>is_success>. + +=head3 HEAD_RC + +A shortcut function for C<GET($uri)-E<gt>code>. + +=head3 HEAD_HEAD + +Throws out the content of the request, and returns the string +representation of the request. Since the body has been thrown out, the +representation will consist solely of the headers. Furthermore, +C<GET_HEAD> inserts a "#" at the beginning of each line of the return +string, so that the contents are suitable for printing to STDERR +during your tests without interfering with the workings of +C<Test::Harness>. + +=head3 PUT + + my $res = PUT $uri; + +Sends a simple PUT request to the Apache test server. Returns an +C<HTTP::Response> object. + +=head3 PUT_STR + +A shortcut function for C<PUT($uri)-E<gt>as_string>. + +=head3 PUT_BODY + +A shortcut function for C<PUT($uri)-E<gt>content>. + +=head3 PUT_BODY_ASSERT + +Use this function when your test is outputting content that you need +to check, and you want to make sure that the request was successful +before comparing the contents of the request. If the request was +unsuccessful, C<PUT_BODY_ASSERT> will return an error +message. Otherwise it will simply return the content of the request +just as C<PUT_BODY> would. + +=head3 PUT_OK + +A shortcut function for C<PUT($uri)-E<gt>is_success>. + +=head3 PUT_RC + +A shortcut function for C<PUT($uri)-E<gt>code>. + +=head3 PUT_HEAD + +Throws out the content of the request, and returns the string +representation of the request. Since the body has been thrown out, the +representation will consist solely of the headers. Furthermore, +C<PUT_HEAD> inserts a "#" at the beginning of each line of the return +string, so that the contents are suitable for printing to STDERR +during your tests without interfering with the workings of +C<Test::Harness>. + +=head3 POST + + my $res = POST $uri, [ arg => $val, arg2 => $val ]; + +Sends a POST request to the Apache test server and returns an +C<HTTP::Response> object. An array reference of parameters passed as +the second argument will be submitted to the Apache test server as the +POST content. Parameters corresponding to those documented in +L<Optional Parameters|/Optional +Parameters> can follow the optional array reference of parameters, or after +C<$uri>. + +To upload a chunk of data, simply use: + + my $res = POST $uri, content => $data; + +=head3 POST_STR + +A shortcut function for C<POST($uri, @args)-E<gt>content>. + +=head3 POST_BODY + +A shortcut function for C<POST($uri, @args)-E<gt>content>. + +=head3 POST_BODY_ASSERT + +Use this function when your test is outputting content that you need +to check, and you want to make sure that the request was successful +before comparing the contents of the request. If the request was +unsuccessful, C<POST_BODY_ASSERT> will return an error +message. Otherwise it will simply return the content of the request +just as C<POST_BODY> would. + +=head3 POST_OK + +A shortcut function for C<POST($uri, @args)-E<gt>is_success>. + +=head3 POST_RC + +A shortcut function for C<POST($uri, @args)-E<gt>code>. + +=head3 POST_HEAD + +Throws out the content of the request, and returns the string +representation of the request. Since the body has been thrown out, the +representation will consist solely of the headers. Furthermore, +C<POST_HEAD> inserts a "#" at the beginning of each line of the return +string, so that the contents are suitable for printing to STDERR +during your tests without interfering with the workings of +C<Test::Harness>. + +=head3 UPLOAD + + my $res = UPLOAD $uri, \@args, filename => $filename; + +Sends a request to the Apache test server that includes an uploaded +file. Other POST parameters can be passed as a second argument as an +array reference. + +C<Apache::TestRequest> will read in the contents of the file named via +the C<filename> parameter for submission to the server. If you'd +rather, you can submit use the C<content> parameter instead of +C<filename>, and its value will be submitted to the Apache server as +file contents: + + my $res = UPLOAD $uri, undef, content => "This is file content"; + +The name of the file sent to the server will simply be "b". Note that +in this case, you cannot pass other POST arguments to C<UPLOAD()> -- +they would be ignored. + +=head3 UPLOAD_BODY + +A shortcut function for C<UPLOAD($uri, @params)-E<gt>content>. + +=head3 UPLOAD_BODY_ASSERT + +Use this function when your test is outputting content that you need +to check, and you want to make sure that the request was successful +before comparing the contents of the request. If the request was +unsuccessful, C<UPLOAD_BODY_ASSERT> will return an error +message. Otherwise it will simply return the content of the request +just as C<UPLOAD_BODY> would. + +=head3 OPTIONS + + my $res = OPTIONS $uri; + +Sends an C<OPTIONS> request to the Apache test server. Returns an +C<HTTP::Response> object with the I<Allow> header, indicating which +methods the server supports. Possible methods include C<OPTIONS>, +C<GET>, C<HEAD> and C<POST>. This function thus can be useful for +testing what options the Apache server supports. Consult the HTTPD 1.1 +specification, section 9.2, at +I<http://www.faqs.org/rfcs/rfc2616.html> for more information. + + + + + +=head2 URL Manipulation Functions + +C<Apache::TestRequest> also includes a few helper functions to aid in +the creation of urls used in the functions above. + + + +=head3 C<module2path> + + $path = Apache::TestRequest::module2path($module_name); + +Convert a module name to a path, safe for use in the various request +methods above. e.g. C<::> can't be used in URLs on win32. For example: + + $path = Apache::TestRequest::module2path('Foo::Bar'); + +returns: + + /Foo__Bar + + + + +=head3 C<module2url> + + $url = Apache::TestRequest::module2url($module); + $url = Apache::TestRequest::module2url($module, \%options); + +Convert a module name to a full URL including the current +configurations C<hostname:port> and sets C<module> accordingly. + + $url = Apache::TestRequest::module2url('Foo::Bar'); + +returns: + + http://$hostname:$port/Foo__Bar + +The default scheme used is C<http>. You can override this by passing +your preferred scheme into an optional second param. For example: + + $module = 'MyTestModule::TestHandler'; + $url = Apache::TestRequest::module2url($module, {scheme => 'https'}); + +returns: + + https://$hostname:$port/MyTestModule__TestHandler + +You may also override the default path with a path of your own: + + $module = 'MyTestModule::TestHandler'; + $url = Apache::TestRequest::module2url($module, {path => '/foo'}); + +returns: + + http://$hostname:$port/foo + + + + + +=head1 ENVIRONMENT VARIABLES + +The following environment variables can affect the behavior of +C<Apache::TestRequest>: + +=over + +=item APACHE_TEST_PRETEND_NO_LWP + +If the environment variable C<APACHE_TEST_PRETEND_NO_LWP> is set to a +true value, C<Apache::TestRequest> will pretend that LWP is not +available so one can test whether the test suite will survive on a +system which doesn't have libwww-perl installed. + +=item APACHE_TEST_HTTP_09_OK + +If the environment variable C<APACHE_TEST_HTTP_09_OK> is set to a +true value, C<Apache::TestRequest> will allow HTTP/0.9 responses +from the server to proceed. The default behavior is to die if +the response protocol is not either HTTP/1.0 or HTTP/1.1. + +=back + +=head1 SEE ALSO + +L<Apache::Test|Apache::Test> is the main Apache testing module. Use it +to set up your tests, create a plan, and to ensure that you have the +Apache version and modules you need. + +Use L<Apache::TestMM|Apache::TestMM> in your I<Makefile.PL> to set up +your distribution for testing. + +=head1 AUTHOR + +Doug MacEachern with contributions from Geoffrey Young, Philippe +M. Chiasson, Stas Bekman and others. Documentation by David Wheeler. + +Questions can be asked at the test-dev <at> httpd.apache.org list. For +more information see: I<http://httpd.apache.org/test/> and +I<http://perl.apache.org/docs/general/testing/testing.html>. diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm new file mode 100644 index 0000000..f398eb5 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm @@ -0,0 +1,1220 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestRun; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test (); +use Apache::TestMM (); +use Apache::TestConfig (); +use Apache::TestConfigC (); +use Apache::TestRequest (); +use Apache::TestHarness (); +use Apache::TestTrace; + +use Cwd; +use ExtUtils::MakeMaker; +use File::Find qw(finddepth); +use File::Path; +use File::Spec::Functions qw(catfile catdir canonpath); +use File::Basename qw(basename dirname); +use Getopt::Long qw(GetOptions); +use Config; + +use constant IS_APACHE_TEST_BUILD => Apache::TestConfig::IS_APACHE_TEST_BUILD; + +use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases) + +use subs qw(exit_shell exit_perl); + +my $orig_command; +my $orig_cwd; +my $orig_conf_opts; + +my %core_files = (); + +my @std_run = qw(start-httpd run-tests stop-httpd); +my @others = qw(verbose configure clean help ssl http11 bugreport + save no-httpd one-process); +my @flag_opts = (@std_run, @others); +my @string_opts = qw(order trace); +my @ostring_opts = qw(proxy ping); +my @debug_opts = qw(debug); +my @list_opts = qw(preamble postamble breakpoint); +my @hash_opts = qw(header); +my @help_opts = qw(clean help); +my @request_opts = qw(get post head); + +my @exit_opts_no_need_httpd = (@help_opts); +my @exit_opts_need_httpd = (@debug_opts, qw(ping)); + +my %usage = ( + 'start-httpd' => 'start the test server', + 'run-tests' => 'run the tests', + 'order=mode' => 'run the tests in one of the modes: ' . + '(repeat|random|SEED)', + 'stop-httpd' => 'stop the test server', + 'no-httpd' => 'run the tests without configuring or starting httpd', + 'verbose[=1]' => 'verbose output', + 'configure' => 'force regeneration of httpd.conf ' . + ' (tests will not be run)', + 'clean' => 'remove all generated test files', + 'help' => 'display this message', + 'bugreport' => 'print the hint how to report problems', + 'preamble' => 'config to add at the beginning of httpd.conf', + 'postamble' => 'config to add at the end of httpd.conf', + 'ping[=block]' => 'test if server is running or port in use', + 'debug[=name]' => 'start server under debugger name (gdb, ddd, etc.)', + 'breakpoint=bp' => 'set breakpoints (multiply bp can be set)', + 'header' => "add headers to (" . + join('|', @request_opts) . ") request", + 'http11' => 'run all tests with HTTP/1.1 (keep alive) requests', + 'ssl' => 'run tests through ssl', + 'proxy' => 'proxy requests (default proxy is localhost)', + 'trace=T' => 'change tracing default to: warning, notice, ' . + 'info, debug, ...', + 'one-process' => 'run the server in single process mode', + (map { $_, "\U$_\E url" } @request_opts), +); + +sub fixup { + #make sure we use an absolute path to perl + #else Test::Harness uses the perl in our PATH + #which might not be the one we want + $^X = $Config{perlpath} unless -e $^X; +} + +# if the test suite was aborted because of a user-error we don't want +# to call the bugreport and invite users to submit a bug report - +# after all it's a user error. but we still want the program to fail, +# so raise this flag in such a case. +my $user_error = 0; +sub user_error { + my $self = shift; + $user_error = shift if @_; + $user_error; +} + +sub new { + my $class = shift; + + my $self = bless { + tests => [], + @_, + }, $class; + + $self->fixup; + + $self; +} + +#split arguments into test files/dirs and options +#take extra care if -e, the file matches /\.t$/ +# if -d, the dir contains .t files +#so we dont slurp arguments that are not tests, example: +# httpd $HOME/apache-2.0/bin/httpd + +sub split_test_args { + my($self) = @_; + + my(@tests); + my $top_dir = $self->{test_config}->{vars}->{top_dir}; + my $t_dir = $self->{test_config}->{vars}->{t_dir}; + + my $argv = $self->{argv}; + my @leftovers = (); + for (@$argv) { + my $arg = $_; + # need the t/ (or t\) for stat-ing, but don't want to include + # it in test output + $arg =~ s@^(?:\.[\\/])?t[\\/]@@; + my $file = catfile $t_dir, $arg; + if (-d $file and $_ ne '/') { + my @files = <$file/*.t>; + my $remove = catfile $top_dir, ""; + if (@files) { + push @tests, map { s,^\Q$remove,,; $_ } @files; + next; + } + } + else { + if ($file =~ /\.t$/ and -e $file) { + push @tests, "t/$arg"; + next; + } + elsif (-e "$file.t") { + push @tests, "t/$arg.t"; + next; + } + elsif (/^[\d.]+$/) { + my @t = $_; + #support range of subtests: t/TEST t/foo/bar 60..65 + if (/^(\d+)\.\.(\d+)$/) { + @t = $1..$2; + } + + push @{ $self->{subtests} }, @t; + next; + } + } + push @leftovers, $_; + } + + $self->{tests} = [ map { canonpath($_) } @tests ]; + $self->{argv} = \@leftovers; +} + +sub die_on_invalid_args { + my($self) = @_; + + # at this stage $self->{argv} should be empty + my @invalid_argv = @{ $self->{argv} }; + if (@invalid_argv) { + error "unknown opts or test names: @invalid_argv\n" . + "-help will list options\n"; + exit_perl 0; + } + +} + +sub passenv { + my $passenv = Apache::TestConfig->passenv; + for (keys %$passenv) { + return 1 if $ENV{$_}; + } + 0; +} + +sub getopts { + my($self, $argv) = @_; + + local *ARGV = $argv; + my(%opts, %vopts, %conf_opts); + + # a workaround to support -verbose and -verbose=0|1 + # $Getopt::Long::VERSION > 2.26 can use the "verbose:1" rule + # but we have to support older versions as well + @ARGV = grep defined, + map {/-verbose=(\d)/ ? ($1 ? '-verbose' : undef) : $_ } @ARGV; + + # permute : optional values can come before the options + # pass_through : all unknown things are to be left in @ARGV + Getopt::Long::Configure(qw(pass_through permute)); + + # grab from @ARGV only the options that we expect + GetOptions(\%opts, @flag_opts, @help_opts, + (map "$_:s", @debug_opts, @request_opts, @ostring_opts), + (map "$_=s", @string_opts), + (map { ("$_=s", $vopts{$_} ||= []) } @list_opts), + (map { ("$_=s", $vopts{$_} ||= {}) } @hash_opts)); + + $opts{$_} = $vopts{$_} for keys %vopts; + + # separate configuration options and test files/dirs + my $req_wanted_args = Apache::TestRequest::wanted_args(); + my @argv = (); + my %req_args = (); + + while (@ARGV) { + my $val = shift @ARGV; + if ($val =~ /^--?(.+)/) { # must have a leading - or -- + my $key = lc $1; + # a known config option? + if (exists $Apache::TestConfig::Usage{$key}) { + $conf_opts{$key} = shift @ARGV; + next; + } # a TestRequest config option? + elsif (exists $req_wanted_args->{$key}) { + $req_args{$key} = shift @ARGV; + next; + } + } + # to be processed later + push @argv, $val; + } + + # save the orig args (make a deep copy) + $orig_conf_opts = { %conf_opts }; + + # fixup the filepath options on win32 (spaces, short names, etc.) + if (Apache::TestConfig::WIN32) { + for my $key (keys %conf_opts) { + next unless Apache::TestConfig::conf_opt_is_a_filepath($key); + next unless -e $conf_opts{$key}; + $conf_opts{$key} = Win32::GetShortPathName($conf_opts{$key}); + } + } + + $opts{req_args} = \%req_args; + + # only test files/dirs if any at all are left in argv + $self->{argv} = \@argv; + + # force regeneration of httpd.conf if commandline args want to + # modify it. configure_opts() has more checks to decide whether to + # reconfigure or not. + # XXX: $self->passenv() is already tested in need_reconfiguration() + $self->{reconfigure} = $opts{configure} || + (grep { $opts{$_}->[0] } qw(preamble postamble)) || + (grep { $Apache::TestConfig::Usage{$_} } keys %conf_opts ) || + $self->passenv() || (! -e 't/conf/httpd.conf'); + + if (exists $opts{debug}) { + $opts{debugger} = $opts{debug}; + $opts{debug} = 1; + } + + if ($opts{trace}) { + my %levels = map {$_ => 1} @Apache::TestTrace::Levels; + if (exists $levels{ $opts{trace} }) { + $Apache::TestTrace::Level = $opts{trace}; + # propogate the override for the server-side. + # -trace overrides any previous APACHE_TEST_TRACE_LEVEL settings + $ENV{APACHE_TEST_TRACE_LEVEL} = $opts{trace}; + } + else { + error "unknown trace level: $opts{trace}", + "valid levels are: @Apache::TestTrace::Levels"; + exit_perl 0; + } + } + + # breakpoint automatically turns the debug mode on + if (@{ $opts{breakpoint} }) { + $opts{debug} ||= 1; + } + + if ($self->{reconfigure}) { + $conf_opts{save} = 1; + delete $self->{reconfigure}; + } + else { + $conf_opts{thaw} = 1; + } + + #propagate some values + for (qw(verbose)) { + $conf_opts{$_} = $opts{$_}; + } + + $self->{opts} = \%opts; + $self->{conf_opts} = \%conf_opts; +} + +sub default_run_opts { + my $self = shift; + my($opts, $tests) = ($self->{opts}, $self->{tests}); + + unless (grep { exists $opts->{$_} } @std_run, @request_opts) { + if (@$tests && $self->{server}->ping) { + # if certain tests are specified and server is running, + # dont restart + $opts->{'run-tests'} = 1; + } + else { + #default is start-server run-tests stop-server + $opts->{$_} = 1 for @std_run; + } + } + + $opts->{'run-tests'} ||= @$tests; +} + +my $parent_pid = $$; +sub is_parent { $$ == $parent_pid } + +my $caught_sig_int = 0; + +sub install_sighandlers { + my $self = shift; + + my($server, $opts) = ($self->{server}, $self->{opts}); + + $SIG{__DIE__} = sub { + return unless $_[0] =~ /^Failed/i; #dont catch Test::ok failures + + # _show_results() calls die() under a few conditions, such as + # when no tests are run or when tests fail. make sure the message + # is propagated back to the user. + print $_[0] if (caller(1))[3]||'' eq 'Test::Harness::_show_results'; + + $server->stop(1) if $opts->{'start-httpd'}; + $server->failed_msg("error running tests"); + exit_perl 0; + }; + + $SIG{INT} = sub { + if ($caught_sig_int++) { + warning "\ncaught SIGINT"; + exit_perl 0; + } + warning "\nhalting tests"; + $server->stop if $opts->{'start-httpd'}; + exit_perl 0; + }; + + #try to make sure we scan for core no matter what happens + #must eval "" to "install" this END block, otherwise it will + #always run, a subclass might not want that + eval 'END { + return unless is_parent(); # because of fork + $self ||= + Apache::TestRun->new(test_config => Apache::TestConfig->thaw); + { + local $?; # preserve the exit status + eval { + $self->scan_core; + }; + } + $self->try_bug_report(); + }'; + die "failed: $@" if $@; + +} + +sub try_bug_report { + my $self = shift; + if ($? && !$self->user_error && + $self->{opts}->{bugreport} && $self->can('bug_report')) { + $self->bug_report; + } +} + +#throw away cached config and start fresh +sub refresh { + my $self = shift; + $self->opt_clean(1); + $self->{conf_opts}->{save} = delete $self->{conf_opts}->{thaw} || 1; + $self->{test_config} = $self->new_test_config()->httpd_config; + $self->{test_config}->{server}->{run} = $self; + $self->{server} = $self->{test_config}->server; +} + +sub configure_opts { + my $self = shift; + my $save = shift; + my $refreshed = 0; + + my($test_config, $opts) = ($self->{test_config}, $self->{opts}); + + $test_config->{vars}->{scheme} = + $opts->{ssl} ? 'https' : + $self->{conf_opts}->{scheme} || 'http'; + + if ($opts->{http11}) { + $ENV{APACHE_TEST_HTTP11} = 1; + } + + # unless we are already reconfiguring, check for .conf.in files changes + if (!$$save && + (my @reasons = + $self->{test_config}->need_reconfiguration($self->{conf_opts}))) { + warning "forcing re-configuration:"; + warning "\t- $_." for @reasons; + unless ($refreshed) { + $self->refresh; + $refreshed = 1; + $test_config = $self->{test_config}; + } + } + + # unless we are already reconfiguring, check for -proxy + if (!$$save && exists $opts->{proxy}) { + my $max = $test_config->{vars}->{maxclients}; + $opts->{proxy} ||= 'on'; + + #if config is cached and MaxClients == 1, must reconfigure + if (!$$save and $opts->{proxy} eq 'on' and $max == 1) { + $$save = 1; + warning "server is reconfigured for proxy"; + unless ($refreshed) { + $self->refresh; + $refreshed = 1; + $test_config = $self->{test_config}; + } + } + + $test_config->{vars}->{proxy} = $opts->{proxy}; + } + else { + $test_config->{vars}->{proxy} = 'off'; + } + + return unless $$save; + + my $preamble = sub { shift->preamble($opts->{preamble}) }; + my $postamble = sub { shift->postamble($opts->{postamble}) }; + + $test_config->preamble_register($preamble); + $test_config->postamble_register($postamble); +} + +sub pre_configure { } + +sub configure { + my $self = shift; + + if ($self->{opts}->{'no-httpd'}) { + warning "skipping httpd configuration"; + return; + } + + # create the conf dir as early as possible + $self->{test_config}->prepare_t_conf(); + + my $save = \$self->{conf_opts}->{save}; + $self->configure_opts($save); + + my $config = $self->{test_config}; + unless ($$save) { + my $addr = \$config->{vars}->{remote_addr}; + my $remote_addr = $config->our_remote_addr; + unless ($$addr eq $remote_addr) { + warning "local ip address has changed, updating config cache"; + $$addr = $remote_addr; + } + #update minor changes to cached config + #without complete regeneration + #for example this allows switching between + #'t/TEST' and 't/TEST -ssl' + $config->sync_vars(qw(scheme proxy remote_addr)); + return; + } + + my $test_config = $self->{test_config}; + $test_config->sslca_generate; + $test_config->generate_ssl_conf if $self->{opts}->{ssl}; + $test_config->cmodules_configure; + $test_config->generate_httpd_conf; + $test_config->save; + +} + +sub try_exit_opts { + my $self = shift; + my @opts = @_; + + for (@opts) { + next unless exists $self->{opts}->{$_}; + my $method = "opt_$_"; + my $rc = $self->$method(); + exit_perl $rc if $rc; + } + + if ($self->{opts}->{'stop-httpd'}) { + my $ok = 1; + if ($self->{server}->ping) { + $ok = $self->{server}->stop; + $ok = $ok < 0 ? 0 : 1; # adjust to 0/1 logic + } + else { + warning "server $self->{server}->{name} is not running"; + # cleanup a stale pid file if found + my $pid_file = $self->{test_config}->{vars}->{t_pid_file}; + unlink $pid_file if -e $pid_file; + } + exit_perl $ok; + } +} + +sub start { + my $self = shift; + + my $opts = $self->{opts}; + my $server = $self->{server}; + + #if t/TEST -d is running make sure we don't try to stop/start the server + my $file = $server->debugger_file; + if (-e $file and $opts->{'start-httpd'}) { + if ($server->ping) { + warning "server is running under the debugger, " . + "defaulting to -run"; + $opts->{'start-httpd'} = $opts->{'stop-httpd'} = 0; + } + else { + warning "removing stale debugger note: $file"; + unlink $file; + } + } + + $self->check_runtime_user(); + + if ($opts->{'start-httpd'}) { + exit_perl 0 unless $server->start; + } + elsif ($opts->{'run-tests'}) { + my $is_up = $server->ping + || (exists $self->{opts}->{ping} + && $self->{opts}->{ping} eq 'block' + && $server->wait_till_is_up(STARTUP_TIMEOUT)); + unless ($is_up) { + error "server is not ready yet, try again."; + exit_perl 0; + } + } +} + +sub run_tests { + my $self = shift; + + my $test_opts = { + verbose => $self->{opts}->{verbose}, + tests => $self->{tests}, + order => $self->{opts}->{order}, + subtests => $self->{subtests} || [], + }; + + if (grep { exists $self->{opts}->{$_} } @request_opts) { + run_request($self->{test_config}, $self->{opts}); + } + else { + Apache::TestHarness->run($test_opts) + if $self->{opts}->{'run-tests'}; + } +} + +sub stop { + my $self = shift; + + return $self->{server}->stop if $self->{opts}->{'stop-httpd'}; +} + +sub new_test_config { + my $self = shift; + + Apache::TestConfig->new($self->{conf_opts}); +} + +sub set_ulimit_via_sh { + return if Apache::TestConfig::WINFU; + return if $ENV{APACHE_TEST_ULIMIT_SET}; + + # only root can allow unlimited core dumps on Solaris (8 && 9?) + if (Apache::TestConfig::SOLARIS) { + my $user = getpwuid($>) || ''; + if ($user ne 'root') { + warning "Skipping 'set unlimited ulimit for coredumps', " . + "since we are running as a non-root user on Solaris"; + return; + } + } + + my $binsh = '/bin/sh'; + return unless -e $binsh; + $ENV{APACHE_TEST_ULIMIT_SET} = 1; + + my $sh = Symbol::gensym(); + open $sh, "echo ulimit -a | $binsh|" or die; + local $_; + while (<$sh>) { + if (/^core.*unlimited$/) { + #already set to unlimited + $ENV{APACHE_TEST_ULIMIT_SET} = 1; + return; + } + } + close $sh; + + $orig_command = "ulimit -c unlimited; $orig_command"; + warning "setting ulimit to allow core files\n$orig_command"; + # use 'or die' to avoid warnings due to possible overrides of die + exec $orig_command or die "exec $orig_command has failed"; +} + +sub set_ulimit { + my $self = shift; + #return if $self->set_ulimit_via_bsd_resource; + eval { $self->set_ulimit_via_sh }; +} + +sub set_env { + #export some environment variables for t/modules/env.t + #(the values are unimportant) + $ENV{APACHE_TEST_HOSTNAME} = 'test.host.name'; + $ENV{APACHE_TEST_HOSTTYPE} = 'z80'; +} + +sub run { + my $self = shift; + + # assuming that test files are always in the same directory as the + # driving script, make it possible to run the test suite from any place + # use a full path, which will work after chdir (e.g. ./TEST) + $0 = File::Spec->rel2abs($0); + if (-e $0) { + my $top = dirname dirname $0; + chdir $top if $top and -d $top; + } + + # reconstruct argv, preserve multiwords args, eg 'PerlTrace all' + my $argv = join " ", map { /^-/ ? $_ : qq['$_'] } @ARGV; + $orig_command = "$^X $0 $argv"; + $orig_cwd = Cwd::cwd(); + $self->set_ulimit; + $self->set_env; #make sure these are always set + + $self->detect_relocation($orig_cwd); + + my(@argv) = @_; + + $self->getopts(\@argv); + + $self->pre_configure(); + + # can't setup the httpd-specific parts of the config object yet + $self->{test_config} = $self->new_test_config(); + + $self->warn_core(); + + # give TestServer access to our runtime configuration directives + # so we can tell the server stuff if we need to + $self->{test_config}->{server}->{run} = $self; + + $self->{server} = $self->{test_config}->server; + + local($SIG{__DIE__}, $SIG{INT}); + $self->install_sighandlers; + + $self->try_exit_opts(@exit_opts_no_need_httpd); + + # httpd is found here (unless it was already configured before) + $self->{test_config}->httpd_config(); + + $self->try_exit_opts(@exit_opts_need_httpd); + + if ($self->{opts}->{configure}) { + warning "cleaning out current configuration"; + $self->opt_clean(1); + } + + $self->split_test_args; + + $self->die_on_invalid_args; + + $self->default_run_opts; + + # if configure() fails for some reason before it has flushed the + # config to a file, save it so -clean will be able to clean + if ($self->{opts}->{'start-httpd'} || $self->{opts}->{'configure'}) { + eval { $self->configure }; + if ($@) { + error "configure() has failed:\n$@"; + warning "forcing Apache::TestConfig object save"; + $self->{test_config}->save; + warning "run 't/TEST -clean' to clean up before continuing"; + exit_perl 0; + } + } + + if ($self->{opts}->{configure}) { + warning "reconfiguration done"; + exit_perl 1; + } + + $self->start unless $self->{opts}->{'no-httpd'}; + + $self->run_tests; + + $self->stop unless $self->{opts}->{'no-httpd'}; +} + +sub rerun { + my $vars = shift; + + # in %$vars + # - httpd will be always set + # - apxs is optional + + $orig_cwd ||= Cwd::cwd(); + chdir $orig_cwd; + my $new_opts = " -httpd $vars->{httpd}"; + $new_opts .= " -apxs $vars->{apxs}" if $vars->{apxs}; + + my $new_command = $orig_command; + + # strip any old bogus -httpd/-apxs + $new_command =~ s/--?httpd\s+$orig_conf_opts->{httpd}// + if $orig_conf_opts->{httpd}; + $new_command =~ s/--?httpd\s+$orig_conf_opts->{httpd}// + if $orig_conf_opts->{httpd} and $vars->{apxs}; + + # add new opts + $new_command .= $new_opts; + + warning "running with new config opts: $new_command"; + + # use 'or die' to avoid warnings due to possible overrides of die + exec $new_command or die "exec $new_command has failed"; +} + + +# make it easy to move the whole distro w/o running +# 't/TEST -clean' before moving. when moving the whole package, +# the old cached config will stay, so we want to nuke it only if +# we realize that it's no longer valid. we can't just check the +# existance of the saved top_dir value, since the project may have +# been copied and the old dir could be still there, but that's not +# the one that we work in +sub detect_relocation { + my($self, $cur_top_dir) = @_; + + my $config_file = catfile qw(t conf apache_test_config.pm); + return unless -e $config_file; + + my %inc = %INC; + eval { require "$config_file" }; + %INC = %inc; # be stealth + warn($@), return if $@; + + my $cfg = 'apache_test_config'->new; + + # if the top_dir from saved config doesn't match the current + # top_dir, that means that the whole project was relocated to a + # different directory, w/o running t/TEST -clean first (in each + # directory with a test suite) + my $cfg_top_dir = $cfg->{vars}->{top_dir}; + return unless $cfg_top_dir; + return if $cfg_top_dir eq $cur_top_dir; + + # if that's the case silently fixup the saved config to use the + # new paths, and force a complete cleanup. if we don't fixup the + # config files, the cleanup process won't be able to locate files + # to delete and re-configuration will fail + { + # in place editing + local @ARGV = $config_file; + local $^I = ".bak"; # Win32 needs a backup + while (<>) { + s{$cfg_top_dir}{$cur_top_dir}g; + print; + } + unlink $config_file . $^I; + } + + my $cleanup_cmd = "$^X $0 -clean"; + warning "cleaning up the old config"; + # XXX: do we care to check success? + system $cleanup_cmd; + + # XXX: I tried hard to accomplish that w/o starting a new process, + # but too many things get on the way, so for now just keep it as an + # external process, as it's absolutely transparent to the normal + # app-run +} + +my @oh = qw(jeez golly gosh darn shucks dangit rats nuts dangnabit crap); +sub oh { + $oh[ rand scalar @oh ]; +} + +#e.g. t/core or t/core.12499 +my $core_pat = '^core(\.\d+)?' . "\$"; + +# $self->scan_core_incremental([$only_top_dir]) +# normally would be called after each test +# and since it updates the list of seen core files +# scan_core() won't report these again +# currently used in Apache::TestSmoke +# +# if $only_t_dir arg is true only the t_dir dir (t/) will be scanned +sub scan_core_incremental { + my($self, $only_t_dir) = @_; + my $vars = $self->{test_config}->{vars}; + + # no core files dropped on win32 + return () if Apache::TestConfig::WIN32; + + if ($only_t_dir) { + require IO::Dir; + my @cores = (); + for (IO::Dir->new($vars->{t_dir})->read) { + my $file = catfile $vars->{t_dir}, $_; + next unless -f $file; + next unless /$core_pat/o; + next if exists $core_files{$file} && + $core_files{$file} == -M $file; + $core_files{$file} = -M $file; + push @cores, $file; + } + return @cores + ? join "\n", "server dumped core, for stacktrace, run:", + map { "gdb $vars->{httpd} -core $_" } @cores + : (); + } + + my @msg = (); + finddepth({ no_chdir => 1, + wanted => sub { + return unless -f $_; + my $file = basename $File::Find::name; + return unless $file =~ /$core_pat/o; + my $core = $File::Find::name; + unless (exists $core_files{$core} && $core_files{$core} == -M $core) { + # new core file! + + # XXX: could rename the file if it doesn't include the pid + # in its name (i.e., just called 'core', instead of 'core.365') + + # XXX: could pass the test name and rename the core file + # to use that name as a suffix, plus pid, time or some + # other unique identifier, in case the same test is run + # more than once and each time it caused a segfault + $core_files{$core} = -M $core; + push @msg, "server dumped core, for stacktrace, run:\n" . + "gdb $vars->{httpd} -core $core"; + } + }}, $vars->{top_dir}); + + return @msg; + +} + +sub scan_core { + my $self = shift; + my $vars = $self->{test_config}->{vars}; + my $times = 0; + + # no core files dropped on win32 + return if Apache::TestConfig::WIN32; + + finddepth({ no_chdir => 1, + wanted => sub { + return unless -f $_; + my $file = basename $File::Find::name; + return unless $file =~ /$core_pat/o; + my $core = $File::Find::name; + if (exists $core_files{$core} && $core_files{$core} == -M $core) { + # we have seen this core file before the start of the test + info "an old core file has been found: $core"; + } + else { + my $oh = oh(); + my $again = $times++ ? "again" : ""; + error "oh $oh, server dumped core $again"; + error "for stacktrace, run: gdb $vars->{httpd} -core $core"; + } + }}, $vars->{top_dir}); +} + +# warn the user that there is a core file before the tests +# start. suggest to delete it before proceeding or a false alarm can +# be generated at the end of the test routine run. +sub warn_core { + my $self = shift; + my $vars = $self->{test_config}->{vars}; + %core_files = (); # reset global + + # no core files dropped on win32 + return if Apache::TestConfig::WIN32; + + finddepth(sub { + return unless -f $_; + return unless /$core_pat/o; + my $core = "$File::Find::dir/$_"; + info "consider removing an old $core file before running tests"; + # remember the timestamp of $core so we can check if it's the + # old core file at the end of the run and not complain then + $core_files{$core} = -M $core; + }, $vars->{top_dir}); +} + +# catch any attempts to ./t/TEST the tests as root user + +sub check_runtime_user { + my $self = shift; + + return if Apache::TestConfig::WINFU; + + my $user = getpwuid($>) || ''; + + if ($user eq 'root') { + error "Apache cannot spawn child processes as root, therefore the test suite must be run as a non-privileged user."; + exit_perl(1); + } + + return 1; +} + +sub run_request { + my($test_config, $opts) = @_; + + my @args = (%{ $opts->{header} }, %{ $opts->{req_args} }); + + my($request, $url) = ("", ""); + + for (@request_opts) { + next unless exists $opts->{$_}; + $url = $opts->{$_} if $opts->{$_}; + $request = join $request ? '_' : '', $request, $_; + } + + if ($request) { + my $method = \&{"Apache::TestRequest::\U$request"}; + my $res = $method->($url, @args); + print Apache::TestRequest::to_string($res); + } +} + +sub opt_clean { + my($self, $level) = @_; + my $test_config = $self->{test_config}; + $test_config->server->stop; + $test_config->clean($level); + 1; +} + +sub opt_ping { + my($self) = @_; + + my $test_config = $self->{test_config}; + my $server = $test_config->server; + my $pid = $server->ping; + my $name = $server->{name}; + # support t/TEST -ping=block -run ... + my $exit = not $self->{opts}->{'run-tests'}; + + if ($pid) { + if ($pid == -1) { + error "port $test_config->{vars}->{port} is in use, ". + "but cannot determine server pid"; + } + else { + my $version = $server->{version}; + warning "server $name running (pid=$pid, version=$version)"; + } + return $exit; + } + + if (exists $self->{opts}->{ping} && $self->{opts}->{ping} eq 'block') { + $server->wait_till_is_up(STARTUP_TIMEOUT); + } + else { + warning "no server is running on $name"; + exit_perl(0); + } + + return $exit; #means call exit() if true +} + +sub test_inc { + map { "$_/Apache-Test/lib" } qw(. ..); +} + +sub set_perl5lib { + $ENV{PERL5LIB} = join $Config{path_sep}, shift->test_inc(); +} + +sub set_perldb_opts { + my $config = shift->{test_config}; + my $file = catfile $config->{vars}->{t_logs}, 'perldb.out'; + $config->genfile($file); #mark for -clean + $ENV{PERLDB_OPTS} = "NonStop frame=4 AutoTrace LineInfo=$file"; + warning "perldb log is t/logs/perldb.out"; +} + +sub opt_debug { + my $self = shift; + my $server = $self->{server}; + + my $opts = $self->{opts}; + my $debug_opts = {}; + + for (qw(debugger breakpoint)) { + $debug_opts->{$_} = $opts->{$_}; + } + + if (my $db = $opts->{debugger}) { + if ($db =~ s/^perl=?//) { + $opts->{'run-tests'} = 1; + $self->start; #if not already running + $self->set_perl5lib; + $self->set_perldb_opts if $db eq 'nostop'; + system $^X, '-MApache::TestPerlDB', '-d', @{ $self->{tests} }; + $self->stop; + return 1; + } + elsif ($db =~ s/^lwp[=:]?//) { + $ENV{APACHE_TEST_DEBUG_LWP} = $db || 1; + $opts->{verbose} = 1; + return 0; + } + } + + $server->stop; + $server->start_debugger($debug_opts); + 1; +} + +sub opt_help { + my $self = shift; + + print <<EOM; +usage: TEST [options ...] + where options include: +EOM + + for (sort keys %usage){ + printf " -%-13s %s\n", $_, $usage{$_}; + } + + print "\n configuration options:\n"; + + Apache::TestConfig->usage; + 1; +} + +# generate t/TEST script (or a different filename) which will drive +# Apache::TestRun +sub generate_script { + my ($class, @opts) = @_; + + my %opts = (); + + # back-compat + if (@opts == 1) { + $opts{file} = $opts[0]; + } + else { + %opts = @opts; + $opts{file} ||= catfile 't', 'TEST'; + } + + my $body = "BEGIN { eval { require blib && blib->import; } }\n"; + + my %args = @Apache::TestMM::Argv; + while (my($k, $v) = each %args) { + $v =~ s/\|/\\|/g; + $body .= "\n\$Apache::TestConfig::Argv{'$k'} = q|$v|;\n"; + } + + my $header = Apache::TestConfig->perlscript_header; + + $body .= join "\n", + $header, "use $class ();"; + + if (my $report = $opts{bugreport}) { + $body .= "\n\npackage $class;\n" . + "sub bug_report { print '$report' }\n\n"; + } + + $body .= "$class->new->run(\@ARGV);"; + + Apache::Test::basic_config()->write_perlscript($opts{file}, + $body); +} + +# in idiomatic perl functions return 1 on success and 0 on +# failure. Shell expects the opposite behavior. So this function +# reverses the status. +sub exit_perl { + exit_shell $_[0] ? 0 : 1; +} + +# expects shell's exit status values (0==success) +sub exit_shell { +# require Carp; +# Carp::cluck('exiting'); + CORE::exit $_[0]; +} + +1; + +__END__ + +=head1 NAME + +Apache::TestRun - Run the test suite + +=head1 SYNOPSIS + + +=head1 DESCRIPTION + +The C<Apache::TestRun> package controls the configuration and running +of the test suite. + +=head1 METHODS + +Several methods are sub-classable, if the default behavior should be +changed. + +=head2 C<bug_report> + +The C<bug_report()> method is executed when C<t/TEST> was executed +with the C<-bugreport> option, and C<make test> (or C<t/TEST>) +fail. Normally this is callback which you can use to tell the user how +to deal with the problem, e.g. suggesting to read some document or +email some details to someone who can take care of it. By default +nothing is executed. + +The C<-bugreport> option is needed so this feature won't become +annoying to developers themselves. It's automatically added to the +C<run_tests> target in F<Makefile>. So if you repeateadly have to test +your code, just don't use C<make test> but run C<t/TEST> +directly. Here is an example of a custom C<t/TEST> + + My::TestRun->new->run(@ARGV); + + package My::TestRun; + use base 'Apache::TestRun'; + + sub bug_report { + my $self = shift; + + print <<EOI; + +--------------------------------------------------------+ + | Please file a bug report: http://perl.apache.org/bugs/ | + +--------------------------------------------------------+ + EOI + } + +=head2 C<pre_configure> + +The C<pre_configure()> method is executed before the configuration for +C<Apache::Test> is generated. So if you need to adjust the setup +before I<httpd.conf> and other files are autogenerated, this is the +right place to do so. + +For example if you don't want to inherit a LoadModule directive for +I<mod_apreq.so> but to make sure that the local version is used, you +can sub-class C<Apache::TestRun> and override this method in +I<t/TEST.PL>: + + package My::TestRun; + use base 'Apache::TestRun'; + use Apache::TestConfig; + __PACKAGE__->new->run(@ARGV); + + sub pre_configure { + my $self = shift; + # Don't load an installed mod_apreq + Apache::TestConfig::autoconfig_skip_module_add('mod_apreq.c'); + + $self->SUPER::pre_configure(); + } + +Notice that the extension is I<.c>, and not I<.so>. + +Don't forget to run the super class' c<pre_configure()> method. + + + +=head2 C<new_test_config> + +META: to be completed + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm new file mode 100644 index 0000000..d2965ba --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm @@ -0,0 +1,332 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestRunPHP; + +use strict; +use warnings FATAL => 'all'; + +use File::Spec::Functions qw(catfile canonpath); + +use Apache::TestRun (); +use Apache::TestConfigParse (); +use Apache::TestTrace; +use Apache::TestConfigPHP (); +use Apache::TestHarnessPHP (); + +use vars qw($VERSION); +$VERSION = '1.00'; # make CPAN.pm's r() version scanner happy + +use File::Spec::Functions qw(catfile); + +# subclass of Apache::TestRun that configures php things +use vars qw(@ISA); +@ISA = qw(Apache::TestRun); + +sub start { + my $self = shift; + + # point php to our own php.ini file + $ENV{PHPRC} = catfile $self->{test_config}->{vars}->{serverroot}, + 'conf'; + + $self->SUPER::start(@_); +} + +sub new_test_config { + my $self = shift; + + Apache::TestConfigPHP->new($self->{conf_opts}); +} + +sub configure_php { + my $self = shift; + + my $test_config = $self->{test_config}; + + $test_config->postamble_register(qw(configure_php_inc + configure_php_ini + configure_php_functions + configure_php_tests)); +} + +sub configure { + my $self = shift; + + $self->configure_php; + + $self->SUPER::configure; +} + +#if Apache::TestRun refreshes config in the middle of configure +#we need to re-add php configure hooks +sub refresh { + my $self = shift; + $self->SUPER::refresh; + $self->configure_php; +} + +my @request_opts = qw(get post head); + +sub run_tests { + my $self = shift; + + my $test_opts = { + verbose => $self->{opts}->{verbose}, + tests => $self->{tests}, + order => $self->{opts}->{order}, + subtests => $self->{subtests} || [], + }; + + if (grep { exists $self->{opts}->{$_} } @request_opts) { + run_request($self->{test_config}, $self->{opts}); + } + else { + Apache::TestHarnessPHP->run($test_opts) + if $self->{opts}->{'run-tests'}; + } +} + +sub split_test_args { + my($self) = @_; + + my(@tests); + my $top_dir = $self->{test_config}->{vars}->{top_dir}; + my $t_dir = $self->{test_config}->{vars}->{t_dir}; + + my $argv = $self->{argv}; + my @leftovers = (); + for (@$argv) { + my $arg = $_; + # need the t/ (or t\) for stat-ing, but don't want to include + # it in test output + $arg =~ s@^(?:\.[\\/])?t[\\/]@@; + my $file = catfile $t_dir, $arg; + if (-d $file and $_ ne '/') { + my @files = <$file/*.t>; + push @files, <$file/*.php>; + my $remove = catfile $top_dir, ""; + if (@files) { + push @tests, map { s,^\Q$remove,,; $_ } @files; + next; + } + } + else { + if (($file =~ /\.t$/ || $file =~ /\.php$/) and -e $file) { + push @tests, "t/$arg"; + next; + } + elsif (-e "$file.t") { + push @tests, "t/$arg.t"; + next; + } + elsif (/^[\d.]+$/) { + my @t = $_; + #support range of subtests: t/TEST t/foo/bar 60..65 + if (/^(\d+)\.\.(\d+)$/) { + @t = $1..$2; + } + + push @{ $self->{subtests} }, @t; + next; + } + } + push @leftovers, $_; + } + + $self->{tests} = [ map { canonpath($_) } @tests ]; + $self->{argv} = \@leftovers; +} +1; +__END__ + +=head1 NAME + +Apache::TestRunPHP - configure and run a PHP-based test suite + +=head1 SYNOPSIS + + use Apache::TestRunPHP; + Apache::TestRunPHP->new->run(@ARGV); + +=head1 DESCRIPTION + +The C<Apache::TestRunPHP> package controls the configuration and +running of the test suite for PHP-based tests. It's a subclass +of C<Apache::TestRun> and similar in function to C<Apache::TestRunPerl>. + +Refer to the C<Apache::TestRun> manpage for information on the +available API. + +=head1 EXAMPLE + +C<TestRunPHP> works almost identially to C<TestRunPerl>, but in +case you are new to C<Apache-Test> here is a quick getting started +guide. be sure to see the links at the end of this document for +places to find additional details. + +because C<Apache-Test> is a Perl-based testing framework we start +from a C<Makefile.PL>, which should have the following lines (in +addition to the standard C<Makefile.PL> parts): + + use Apache::TestMM qw(test clean); + use Apache::TestRunPHP (); + + Apache::TestMM::filter_args(); + + Apache::TestRunPHP->generate_script(); + +C<generate_script()> will create a script named C<t/TEST>, the gateway +to the Perl testing harness and what is invoked when you call +C<make test>. C<filter_args()> accepts some C<Apache::Test>-specific +arguments and passes them along. for example, to point to a specific +C<httpd> installation you would invoke C<Makefile.PL> as follows + + $ perl Makefile.PL -httpd /my/local/apache/bin/httpd + +and C</my/local/apache/bin/httpd> will be propagated throughout the +rest of the process. note that PHP needs to be active within Apache +prior to configuring the test framework as shown above, either by +virtue of PHP being compiled into the C<httpd> binary statically or +through an active C<LoadModule> statement within the configuration +located in C</my/local/apache/conf/httpd.conf>. Other required modules +are the (very common) mod_alias and mod_env. + +now, like with C<Apache::TestRun> and C<Apache::TestRunPerl>, you can +place client-side Perl test scripts under C<t/>, such as C<t/01basic.t>, +and C<Apache-Test> will run these scripts when you call C<make test>. +however, what makes C<Apache::TestRunPHP> unique is some added magic +specifically tailored to a PHP environment. here are the mechanics. + +C<Apache::TestRunPHP> will look for PHP test scripts in that match +the following pattern + + t/response/TestFoo/bar.php + +where C<Foo> and C<bar> can be anything you like, and C<t/response/Test*> +is case sensitive. when this format is adhered to, C<Apache::TestRunPHP> +will create an associated Perl test script called C<t/foo/bar.t>, which +will be executed when you call C<make test>. all C<bar.t> does is issue +a simple GET to C<bar.php>, leaving the actual testing to C<bar.php>. in +essence, you can forget that C<bar.t> even exists. + +what does C<bar.php> look like? here is an example: + + <?php + print "1..1\n"; + print "ok 1\n" + ?> + +if it looks odd, that's ok because it is. I could explain to you exactly +what this means, but it isn't important to understand the gory details. +instead, it is sufficient to understand that when C<Apache::Test> calls +C<bar.php> it feeds the results directly to C<Test::Harness>, a module +that comes with every Perl installation, and C<Test::Harness> expects +what it receives to be formated in a very specific way. by itself, all +of this is pretty useless, so C<Apache::Test> provides PHP testers with +something much better. here is a much better example: + + <?php + # import the Test::More emulation layer + # see + # http://search.cpan.org/dist/Test-Simple/lib/Test/More.pm + # for Perl's documentation - these functions should behave + # in the same way + require 'test-more.php'; + + # plan() the number of tests + plan(6); + + # call ok() for each test you plan + ok ('foo' == 'foo', 'foo is equal to foo'); + ok ('foo' != 'foo', 'foo is not equal to foo'); + + # ok() can be other things as well + is ('bar', 'bar', 'bar is bar'); + is ('baz', 'bar', 'baz is baz'); + isnt ('bar', 'beer', 'bar is not beer'); + like ('bar', '/ar$/', 'bar matches ar$'); + + diag("printing some debugging information"); + + # whoops! one too many tests. I wonder what will happen... + is ('biff', 'biff', 'baz is a baz'); + ?> + +the include library C<test-more.php> is automatically generated by +C<Apache::TestConfigPHP> and configurations tweaked in such a +a way that your PHP scripts can find it without issue. the +functions provided by C<test-more.php> are equivalent in name and +function to those in C<Test::More>, a standard Perl testing +library, so you can see that manpage for details on the syntax +and functionality of each. + +at this point, we have enough in place to run some tests from +PHP-land - a C<Makefile.PL> to configure Apache for us, and +a PHP script in C<t/response/TestFoo/bar.php> to send some +results out to the testing engine. issuing C<make test> +would start Apache, issue the request to C<bar.php>, generate +a report, and shut down Apache. the report would look like +something like this after running the tests in verbose mode +(eg C<make test TEST_VERBOSE=1>): + + t/php/bar....1..6 + ok 1 - foo is equal to foo + not ok 2 - foo is not equal to foo + # Failed test (/src/devel/perl-php-test/t/response/TestFoo/bar.php at line 13) + ok 3 - bar is bar + not ok 4 - baz is baz + # Failed test (/src/devel/perl-php-test/t/response/TestFoo/bar.php at line 17) + # got: 'baz' + # expected: 'bar' + ok 5 - bar is not beer + ok 6 - bar matches ar$ + # printing some debugging information + ok 7 - baz is a baz + FAILED tests 2, 4, 7 + Failed 3/6 tests, 50.00% okay + Failed Test Stat Wstat Total Fail Failed List of Failed + ------------------------------------------------------------------------------- + t/php/bar.t 6 3 50.00% 2 4 7 + Failed 1/1 test scripts, 0.00% okay. 1/6 subtests failed, 83.33% okay. + +note that the actual test file that was run was C<t/php/bar.t>. this +file is autogenerated based on the C<t/response/TestFoo/bar.php> +pattern of your PHP script. C<t/php/bar.t> happens to be written in +Perl, but you really don't need to worry about it too much. + +as an interesting aside, if you are using perl-5.8.3 or later you can +actually create your own C<t/foo.php> client-side scripts and they +will be run via php (using our C<php.ini>). but more on that later... + +=head1 SEE ALSO + +the best source of information about using Apache-Test with +PHP (at this time) is probably the talk given at ApacheCon 2004 +(L<http://xrl.us/phpperl>), as well as the code from the talk +(L<http://xrl.us/phpperlcode>). there is also the online tutorial +L<http://perl.apache.org/docs/general/testing/testing.html> +which has all of the mod_perl-specific syntax and features have been +ported to PHP with this class. + +=head1 AUTHOR + +C<Apache-Test> is a community effort, maintained by a group of +dedicated volunteers. + +Questions can be asked at the test-dev <at> httpd.apache.org list +For more information see: http://httpd.apache.org/test/. + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRunParrot.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRunParrot.pm new file mode 100644 index 0000000..21bd3a9 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRunParrot.pm @@ -0,0 +1,68 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestRunParrot; + +use strict; +use warnings FATAL => 'all'; + +use File::Spec::Functions qw(catfile canonpath); + +use Apache::TestRun (); +use Apache::TestConfigParse (); +use Apache::TestTrace; +use Apache::TestConfigParrot (); + +use vars qw($VERSION); +$VERSION = '1.00'; # make CPAN.pm's r() version scanner happy + +use File::Spec::Functions qw(catfile); + +# subclass of Apache::TestRun that configures parrot things +use vars qw(@ISA); +@ISA = qw(Apache::TestRun); + +sub new_test_config { + my $self = shift; + + Apache::TestConfigParrot->new($self->{conf_opts}); +} + +sub configure_parrot { + my $self = shift; + + my $test_config = $self->{test_config}; + + $test_config->postamble_register(qw(configure_parrot_tests)); +} + +sub configure { + my $self = shift; + + $self->configure_parrot; + + $self->SUPER::configure; +} + +#if Apache::TestRun refreshes config in the middle of configure +#we need to re-add parrotconfigure hooks +sub refresh { + my $self = shift; + $self->SUPER::refresh; + $self->configure_parrot; +} + +1; +__END__ diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRunPerl.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRunPerl.pm new file mode 100644 index 0000000..2226575 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRunPerl.pm @@ -0,0 +1,139 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestRunPerl; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRun (); +use Apache::TestConfigParse (); +use Apache::TestTrace; + +use vars qw($VERSION); +$VERSION = '1.00'; # make CPAN.pm's r() version scanner happy + +use File::Spec::Functions qw(catfile); + +#subclass of Apache::TestRun that configures mod_perlish things +use vars qw(@ISA); +@ISA = qw(Apache::TestRun); + +sub pre_configure { + my $self = shift; + + # Apache::TestConfigPerl already configures mod_perl.so + Apache::TestConfig::autoconfig_skip_module_add('mod_perl.c'); + + # skip over Embperl.so - it's funky + Apache::TestConfig::autoconfig_skip_module_add('Embperl.c'); +} + +sub configure_modperl { + my $self = shift; + + my $test_config = $self->{test_config}; + + my $rev = $test_config->server->{rev}; + my $ver = $test_config->server->{version}; + + # sanity checking and loading the right mod_perl version + + # remove mod_perl.pm from %INC so that the below require() + # calls accurately populate $mp_ver + delete $INC{'mod_perl.pm'}; + + if ($rev == 2) { + eval { require mod_perl2 }; + } else { + eval { require mod_perl }; + } + + my $mp_ver = $mod_perl::VERSION; + if ($@) { + error "You are using mod_perl response handlers ", + "but do not have a mod_perl capable Apache."; + Apache::TestRun::exit_perl(0); + } + if (($rev == 1 && $mp_ver >= 1.99) || + ($rev == 2 && $mp_ver < 1.99)) { + error "Found mod_perl/$mp_ver, but it can't be used with $ver"; + Apache::TestRun::exit_perl(0); + } + + if ($rev == 2) { + # load apreq2 if it is present + # do things a bit differently that find_and_load_module() + # because apreq2 can't be loaded that way (the 2 causes a problem) + my $name = 'mod_apreq2.so'; + if (my $mod_path = $test_config->find_apache_module($name)) { + + # don't match the 2 here + my ($sym) = $name =~ m/mod_(\w+)2\./; + + if ($mod_path && -e $mod_path) { + $test_config->preamble(IfModule => "!mod_$sym.c", + qq{LoadModule ${sym}_module "$mod_path"\n}); + } + } + } + + $test_config->preamble_register(qw(configure_libmodperl + configure_env)); + + $test_config->postamble_register(qw(configure_inc + configure_pm_tests_inc + configure_startup_pl + configure_pm_tests)); +} + +sub configure { + my $self = shift; + + $self->configure_modperl; + + $self->SUPER::configure; +} + +#if Apache::TestRun refreshes config in the middle of configure +#we need to re-add modperl configure hooks +sub refresh { + my $self = shift; + $self->SUPER::refresh; + $self->configure_modperl; +} + +1; +__END__ + +=head1 NAME + +Apache::TestRunPerl - Run mod_perl-requiring Test Suite + +=head1 SYNOPSIS + + use Apache::TestRunPerl; + Apache::TestRunPerl->new->run(@ARGV); + +=head1 DESCRIPTION + +The C<Apache::TestRunPerl> package controls the configuration and +running of the test suite. It's a subclass of C<Apache::TestRun>, and +should be used only when you need to run mod_perl tests. + +Refer to the C<Apache::TestRun> manpage for information on the +available API. + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm new file mode 100644 index 0000000..fc4c685 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm @@ -0,0 +1,595 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestSSLCA; + +use strict; +use warnings FATAL => 'all'; + +use Cwd (); +use DirHandle (); +use File::Path (); +use File::Copy 'cp'; +use File::Basename; +use File::Spec::Functions qw(devnull); +use Apache::TestConfig (); +use Apache::TestTrace; + +use constant SSLCA_DB => 'index.txt'; + +use vars qw(@EXPORT_OK &import); + +use subs qw(symlink); + +@EXPORT_OK = qw(dn dn_vars dn_oneline); +*import = \&Exporter::import; + +my $openssl = $ENV{APACHE_TEST_OPENSSL_CMD} || 'openssl'; +my $version = version(); + +my $CA = 'asf'; +my $Config; #global Apache::TestConfig object + +my $days = '-days 365'; +my $cakey = 'keys/ca.pem'; +my $cacert = 'certs/ca.crt'; +my $capolicy = '-policy policy_anything'; +my $cacrl = 'crl/ca-bundle.crl'; +my $dgst = 'sha256'; + +#we use the same password for everything +my $pass = 'httpd'; +my $passin = "-passin pass:$pass"; +my $passout = "-passout pass:$pass"; + +# (limited) subjectAltName otherName testing +my $san_msupn = ', otherName:msUPN;UTF8:$mail'; +my $san_dnssrv = ', otherName:1.3.6.1.5.5.7.8.7;IA5:_https.$CN'; + +# in 0.9.7 s/Email/emailAddress/ in DN +my $email_field = Apache::Test::normalize_vstring($version) < + Apache::Test::normalize_vstring("0.9.7") ? + "Email" : "emailAddress"; + +# downgrade to SHA-1 for OpenSSL before 0.9.8 +if (Apache::Test::normalize_vstring($version) < + Apache::Test::normalize_vstring("0.9.8")) { + $dgst = 'sha1'; + # otherNames in x509v3_config are not supported either + $san_msupn = $san_dnssrv = ""; +} + +my $sslproto = "all"; + +eval { require Net::SSLeay; }; +if (Apache::Test::normalize_vstring($version) >= + Apache::Test::normalize_vstring("1.1.1") + && !defined(&Net::SSLeay::CTX_set_post_handshake_auth)) { + # OpenSSL 1.1.1 disables PHA by default client-side in TLSv1.3 but + # most clients are not updated to enable it (at time of writing). + # Many mod_ssl tests require working PHA, so disable v1.3 unless + # using an updated Net::SSLeay. This is strictly insufficient + # since an updated IO::Socket::SSL is also needed; to be + # continued. Ref: https://github.com/openssl/openssl/issues/6933 + $sslproto = "all -TLSv1.3"; +} + +my $ca_dn = { + asf => { + C => 'US', + ST => 'California', + L => 'San Francisco', + O => 'ASF', + OU => 'httpd-test', + CN => '', + $email_field => 'test-dev@httpd.apache.org', + }, +}; + +my $cert_dn = { + client_snakeoil => { + C => 'AU', + ST => 'Queensland', + L => 'Mackay', + O => 'Snake Oil, Ltd.', + OU => 'Staff', + }, + client_ok => { + }, + client_colon => { + CN => "user:colon", + }, + client_revoked => { + }, + server => { + CN => 'localhost', + OU => 'httpd-test/rsa-test', + }, + server2 => { + CN => 'localhost', + OU => 'httpd-test/rsa-test-2', + }, + server_des3 => { + CN => 'localhost', + OU => 'httpd-test/rsa-des3-test', + }, + server2_des3 => { + CN => 'localhost', + OU => 'httpd-test/rsa-des3-test-2', + }, +}; + +#generate DSA versions of the server certs/keys +for my $key (keys %$cert_dn) { + next unless $key =~ /^server/; + my $val = $$cert_dn{$key}; + my $name = join '_', $key, 'dsa'; + $cert_dn->{$name} = { %$val }; #copy + $cert_dn->{$name}->{OU} =~ s/rsa/dsa/; +} + +sub ca_dn { + $ca_dn = shift if @_; + $ca_dn; +} + +sub cert_dn { + $cert_dn = shift if @_; + $cert_dn; +} + +sub dn { + my $name = shift; + + my %dn = %{ $ca_dn->{$CA} }; #default values + $dn{CN} ||= $name; #try make sure each Common Name is different + + my $default_dn = $cert_dn->{$name}; + + if ($default_dn) { + while (my($key, $value) = each %$default_dn) { + #override values + $dn{$key} = $value; + } + } + + return wantarray ? %dn : \%dn; +} + +sub dn_vars { + my($name, $type) = @_; + + my $dn = dn($name); + my $prefix = join '_', 'SSL', $type, 'DN'; + + return { map { $prefix ."_$_", $dn->{$_} } keys %$dn }; +} + +sub dn_oneline { + my($dn, $rfc2253) = @_; + + unless (ref $dn) { + $dn = dn($dn); + } + + my $string = ""; + my @parts = (qw(C ST L O OU CN), $email_field); + @parts = reverse @parts if $rfc2253; + + for my $k (@parts) { + next unless $dn->{$k}; + if ($rfc2253) { + my $tmp = $dn->{$k}; + $tmp =~ s{([,+"\\<>;])}{\\$1}g; + $tmp =~ s{^([ #])}{\\$1}; + $tmp =~ s{ $}{\\ }; + $string .= "," if $string; + $string .= "$k=$tmp"; + } + else { + $string .= "/$k=$dn->{$k}"; + } + } + + $string; +} + +sub openssl { + return $openssl unless @_; + + my $cmd = "$openssl @_"; + + info $cmd; + + unless (system($cmd) == 0) { + my $status = $? >> 8; + die "system @_ failed (exit status=$status)"; + } +} + +my @dirs = qw(keys newcerts certs crl export csr conf proxy); + +sub init { + for my $dir (@dirs) { + gendir($dir); + } +} + +sub config_file { + my $name = shift; + + my $file = "conf/$name.cnf"; + return $file if -e $file; + + my $dn = dn($name); + my $db = SSLCA_DB; + + writefile($db, '', 1) unless -e $db; + + writefile($file, <<EOF); +mail = $dn->{$email_field} +CN = $dn->{CN} + +[ req ] +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +default_bits = 2048 +output_password = $pass + +[ req_distinguished_name ] +C = $dn->{C} +ST = $dn->{ST} +L = $dn->{L} +O = $dn->{O} +OU = $dn->{OU} +CN = \$CN +$email_field = \$mail + +[ req_attributes ] +challengePassword = $pass + +[ ca ] +default_ca = CA_default + +[ CA_default ] +certs = certs # Where the issued certs are kept +new_certs_dir = newcerts # default place for new certs. +crl_dir = crl # Where the issued crl are kept +database = $db # database index file. +serial = serial # The current serial number + +certificate = $cacert # The CA certificate +crl = $cacrl # The current CRL +private_key = $cakey # The private key + +default_days = 365 # how long to certify for +default_crl_days = 365 # how long before next CRL +default_md = $dgst # which md to use. +preserve = no # keep passed DN ordering + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +$email_field = optional + +[ client_ok_ext ] +nsComment = This Is A Comment +1.3.6.1.4.1.18060.12.0 = DER:0c064c656d6f6e73 +subjectAltName = email:\$mail$san_msupn + +[ server_ext ] +subjectAltName = DNS:\$CN$san_dnssrv +EOF + + return $file; +} + +sub config { + my $name = shift; + + my $file = config_file($name); + + my $config = "-config $file"; + + $config; +} + +use constant PASSWORD_CLEARTEXT => + Apache::TestConfig::WIN32 || Apache::TestConfig::NETWARE; + +#http://www.modssl.org/docs/2.8/ssl_reference.html#ToC21 +my $basic_auth_password = + PASSWORD_CLEARTEXT ? 'password': 'xxj31ZMTZzkVA'; +my $digest_auth_hash = '$1$OXLyS...$Owx8s2/m9/gfkcRVXzgoE/'; + +sub new_ca { + writefile('serial', "01\n", 1); + + writefile('ssl.htpasswd', + join ':', dn_oneline('client_snakeoil'), + $basic_auth_password); + + openssl req => "-new -x509 -keyout $cakey -out $cacert $days", + config('ca'); + + export_cert('ca'); #useful for importing into IE +} + +sub new_key { + my $name = shift; + + my $encrypt = @_ ? "@_ $passout" : ""; + + my $out = "-out keys/$name.pem $encrypt"; + + if ($name =~ /dsa/) { + #this takes a long time so just do it once + #don't do this in real life + unless (-e 'dsa-param') { + openssl dsaparam => '-inform PEM -out dsa-param 2048'; + } + openssl gendsa => "$out dsa-param"; + } + else { + openssl genrsa => "$out 2048"; + } +} + +sub new_cert { + my $name = shift; + + openssl req => "-new -key keys/$name.pem -out csr/$name.csr", + $passin, $passout, config($name); + + sign_cert($name); + + export_cert($name); +} + +sub sign_cert { + my $name = shift; + my $exts = ''; + + $exts = ' -extensions client_ok_ext' if $name =~ /client_ok/; + + $exts = ' -extensions server_ext' if $name =~ /server/; + + openssl ca => "$capolicy -in csr/$name.csr -out certs/$name.crt", + $passin, config($name), '-batch', $exts; +} + +#handy for importing into a browser such as netscape +sub export_cert { + my $name = shift; + + return if $name =~ /^server/; #no point in exporting server certs + + openssl pkcs12 => "-export -in certs/$name.crt -inkey keys/$name.pem", + "-out export/$name.p12", $passin, $passout; +} + +sub revoke_cert { + my $name = shift; + + my @args = (config('cacrl'), $passin); + + #revokes in the SSLCA_DB database + openssl ca => "-revoke certs/$name.crt", @args; + + #generates crl from the index.txt database + openssl ca => "-gencrl -out $cacrl", @args; +} + +sub symlink { + my($file, $symlink) = @_; + + my $what = 'linked'; + + if (Apache::TestConfig::WINFU) { + cp $file, $symlink; + $what = 'copied'; + } + else { + CORE::symlink($file, $symlink); + } + + info "$what $file to $symlink"; +} + +sub hash_certs { + my($type, $dir) = @_; + + chdir $dir; + + my $dh = DirHandle->new('.') or die "opendir $dir: $!"; + my $n = 0; + + for my $file ($dh->read) { + next unless $file =~ /\.cr[tl]$/; + chomp(my $hash = `openssl $type -noout -hash < $file`); + next unless $hash; + my $symlink = "$hash.r$n"; + $n++; + symlink $file, $symlink; + } + + close $dh; + + chdir $CA; +} + +sub make_proxy_cert { + my $name = shift; + + my $from = "certs/$name.crt"; + my $to = "proxy/$name.pem"; + + info "generating proxy cert: $to"; + + my $fh_to = Symbol::gensym(); + my $fh_from = Symbol::gensym(); + + open $fh_to, ">$to" or die "open $to: $!"; + open $fh_from, $from or die "open $from: $!"; + + cp $fh_from, $fh_to; + + $from = "keys/$name.pem"; + + open $fh_from, $from or die "open $from: $!"; + + cp $fh_from, $fh_to; + + close $fh_from; + close $fh_to; +} + +sub setup { + $CA = shift; + + unless ($ca_dn->{$CA}) { + die "unknown CA $CA"; + } + + gendir($CA); + + chdir $CA; + + init(); + new_ca(); + + my @names = keys %$cert_dn; + + for my $name (@names) { + my @key_args = (); + if ($name =~ /_des3/) { + push @key_args, '-des3'; + } + + new_key($name, @key_args); + new_cert($name); + + if ($name =~ /_revoked$/) { + revoke_cert($name); + } + + if ($name =~ /^client_/) { + make_proxy_cert($name); + } + } + + hash_certs(crl => 'crl'); +} + +sub generate { + $Config = shift; + + $CA = shift || $Config->{vars}->{sslcaorg}; + + my $root = $Config->{vars}->{sslca}; + + return if -d $root; + + my $pwd = Cwd::cwd(); + my $base = dirname $root; + my $dir = basename $root; + + chdir $base; + + # Ensure the CNs used in the server certs match up with the + # hostname being used for testing. + while (my($key, $val) = each %$cert_dn) { + next unless $key =~ /^server/; + $val->{CN} = $Config->{vars}->{servername}; + } + + #make a note that we created the tree + $Config->clean_add_path($root); + + gendir($dir); + + chdir $dir; + + warning "generating SSL CA for $CA"; + + setup($CA); + + chdir $pwd; +} + +sub clean { + my $config = shift; + + #rel2abs adds same drive letter for win32 that clean_add_path added + my $dir = File::Spec->rel2abs($config->{vars}->{sslca}); + + unless ($config->{clean}->{dirs}->{$dir}) { + return; #we did not generate this ca + } + + unless ($config->{clean_level} > 1) { + #skip t/TEST -conf + warning "skipping regeneration of SSL CA; run t/TEST -clean to force"; + return; + } + + File::Path::rmtree([$dir], 1, 1); +} + +#not using Apache::TestConfig methods because the openssl commands +#will generate heaps of files we cannot keep track of + +sub writefile { + my($file, $content) = @_; + + my $fh = Symbol::gensym(); + open $fh, ">$file" or die "open $file: $!"; + print $fh $content; + close $fh; +} + +sub gendir { + my($dir) = @_; + + return if -d $dir; + mkdir $dir, 0755; +} + +sub version { + my $devnull = devnull(); + my $version = qx($openssl version 2>$devnull); + return $1 if $version =~ /^\S+SSL (\S+)/; + die "FATAL: unable to determine openssl version via `$openssl version` from: $version"; +} + +sub dgst { + return $dgst; +} + +sub email_field { + return $email_field; +} + +sub sslproto { + return $sslproto; +} + +1; +__END__ diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestServer.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestServer.pm new file mode 100644 index 0000000..3a30a63 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestServer.pm @@ -0,0 +1,724 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestServer; + +use strict; +use warnings FATAL => 'all'; + +use Config; +use Socket (); +use File::Spec::Functions qw(catfile); + +use Apache::TestTrace; +use Apache::TestRun; +use Apache::TestConfig (); +use Apache::TestRequest (); + +use constant COLOR => Apache::TestConfig::COLOR; +use constant WIN32 => Apache::TestConfig::WIN32; + +my $CTRL_M = COLOR ? "\r" : "\n"; + +# some debuggers use the same syntax as others, so we reuse the same +# code by using the following mapping +my %debuggers = ( + gdb => 'gdb', + ddd => 'gdb', + valgrind => 'valgrind', + strace => 'strace', +); + +sub new { + my $class = shift; + my $config = shift; + + my $self = bless { + config => $config || Apache::TestConfig->thaw, + }, $class; + + $self->{name} = join ':', + map { $self->{config}->{vars}->{$_} } qw(servername port); + + $self->{port_counter} = $self->{config}->{vars}->{port}; + + $self; +} + +# call this when you already know where httpd is +sub post_config { + my($self) = @_; + + $self->{version} = $self->{config}->httpd_version || ''; + $self->{mpm} = $self->{config}->httpd_mpm || ''; + + # try to get the revision number from the standard Apache version + # string and various variations made by distributions which mangle + # that string + + # Foo-Apache-Bar/x.y.z + ($self->{rev}) = $self->{version} =~ m|/(\d)\.|; + + if ($self->{rev}) { + debug "Matched Apache revision $self->{version} $self->{rev}"; + } + else { + # guessing is not good as it'll only mislead users + # and we can't die since a config object is required + # during Makefile.PL's write_perlscript when path to httpd may + # be unknown yet. so default to non-existing version 0 for now. + # and let TestRun.pm figure out the required pieces + debug "can't figure out Apache revision, from string: " . + "'$self->{version}', using a non-existing revision 0"; + $self->{rev} = 0; # unknown + } + + ($self->{revminor}) = $self->{version} =~ m|/\d\.(\d)|; + + if ($self->{revminor}) { + debug "Matched Apache revminor $self->{version} $self->{revminor}"; + } + else { + $self->{revminor} = 0; + } + + $self; +} + +sub version_of { + my($self, $thing) = @_; + die "Can't figure out what Apache server generation we are running" + unless $self->{rev}; + + $thing->{$self->{rev}}; +} + +my @apache_logs = qw( +error_log access_log httpd.pid +apache_runtime_status rewrite_log +ssl_engine_log ssl_request_log +cgisock +); + +sub clean { + my $self = shift; + + my $dir = $self->{config}->{vars}->{t_logs}; + + for (@apache_logs) { + my $file = catfile $dir, $_; + if (unlink $file) { + debug "unlink $file"; + } + } +} + +sub pid_file { + my $self = shift; + + my $vars = $self->{config}->{vars}; + + return $vars->{t_pid_file} || catfile $vars->{t_logs}, 'httpd.pid'; +} + +sub dversion { + my $self = shift; + + my $dv = "-D APACHE$self->{rev}"; + + if ($self->{rev} == 2 and $self->{revminor} == 4) { + $dv .= " -D APACHE2_4"; + } + + return $dv; +} + +sub config_defines { + my $self = shift; + + my @defines = (); + + for my $item (qw(useithreads)) { + next unless $Config{$item} and $Config{$item} eq 'define'; + push @defines, "-D PERL_\U$item"; + } + + if (my $defines = $self->{config}->{vars}->{defines}) { + push @defines, map { "-D $_" } split " ", $defines; + } + + "@defines"; +} + +sub args { + my $self = shift; + my $vars = $self->{config}->{vars}; + my $dversion = $self->dversion; #for .conf version conditionals + my $defines = $self->config_defines; + + "-d $vars->{serverroot} -f $vars->{t_conf_file} $dversion $defines"; +} + +my %one_process = (1 => '-X', 2 => '-D ONE_PROCESS'); + +sub start_cmd { + my $self = shift; + + my $args = $self->args; + my $config = $self->{config}; + my $vars = $config->{vars}; + my $httpd = $vars->{httpd}; + + my $one_process = $self->{run}->{opts}->{'one-process'} + ? $self->version_of(\%one_process) + : ''; + + #XXX: threaded mpm does not respond to SIGTERM with -D ONE_PROCESS + + return "$httpd $one_process $args"; +} + +sub default_gdbinit { + my $gdbinit = ""; + my @sigs = qw(PIPE); + + for my $sig (@sigs) { + for my $flag (qw(pass nostop)) { + $gdbinit .= "handle SIG$sig $flag\n"; + } + } + + $gdbinit; +} + +sub strace_cmd { + my($self, $strace, $file) = @_; + #XXX truss, ktrace, etc. + "$strace -f -o $file -s1024"; +} + +sub valgrind_cmd { + my($self, $valgrind) = @_; + "$valgrind -v --leak-check=yes --show-reachable=yes --error-limit=no"; +} + +sub start_valgrind { + my $self = shift; + my $opts = shift; + + my $config = $self->{config}; + my $args = $self->args; + my $one_process = $self->version_of(\%one_process); + my $valgrind_cmd = $self->valgrind_cmd($opts->{debugger}); + my $httpd = $config->{vars}->{httpd}; + + my $command = "$valgrind_cmd $httpd $one_process $args"; + + debug $command; + system $command; +} + +sub start_strace { + my $self = shift; + my $opts = shift; + + my $config = $self->{config}; + my $args = $self->args; + my $one_process = $self->version_of(\%one_process); + my $file = catfile $config->{vars}->{t_logs}, 'strace.log'; + my $strace_cmd = $self->strace_cmd($opts->{debugger}, $file); + my $httpd = $config->{vars}->{httpd}; + + $config->genfile($file); #just mark for cleanup + + my $command = "$strace_cmd $httpd $one_process $args"; + + debug $command; + system $command; +} + +sub start_gdb { + my $self = shift; + my $opts = shift; + + my $debugger = $opts->{debugger}; + my @breakpoints = @{ $opts->{breakpoint} || [] }; + my $config = $self->{config}; + my $args = $self->args; + my $one_process = $self->version_of(\%one_process); + + my $file = catfile $config->{vars}->{serverroot}, '.gdb-test-start'; + my $fh = $config->genfile($file); + + print $fh default_gdbinit(); + + if (@breakpoints) { + print $fh "b ap_run_pre_config\n"; + print $fh "run $one_process $args\n"; + print $fh "finish\n"; + for (@breakpoints) { + print $fh "b $_\n" + } + print $fh "continue\n"; + } + else { + print $fh "run $one_process $args\n"; + } + close $fh; + + my $command; + my $httpd = $config->{vars}->{httpd}; + + if ($debugger eq 'ddd') { + $command = qq{ddd --gdb --debugger "gdb -command $file" $httpd}; + } + else { + ## defaults to gdb if not set in %ENV or via -debug + $command = "$debugger $httpd -command $file"; + } + + $self->note_debugging; + debug $command; + system $command; + + unlink $file; +} + +sub debugger_file { + my $self = shift; + catfile $self->{config}->{vars}->{serverroot}, '.debugging'; +} + +#make a note that the server is running under the debugger +#remove note when this process exits via END + +sub note_debugging { + my $self = shift; + my $file = $self->debugger_file; + my $fh = $self->{config}->genfile($file); + eval qq(END { unlink "$file" }); +} + +sub start_debugger { + my $self = shift; + my $opts = shift; + + $opts->{debugger} ||= $ENV{MP_DEBUGGER} || 'gdb'; + + # XXX: FreeBSD 5.2+ + # gdb 6.1 and before segfaults when trying to + # debug httpd startup code. 6.5 has been proven + # to work. FreeBSD typically installs this as + # gdb65. + # Is it worth it to check the debugger and os version + # and die ? + + unless (grep { /^$opts->{debugger}/ } keys %debuggers) { + error "$opts->{debugger} is not a supported debugger", + "These are the supported debuggers: ". + join ", ", sort keys %debuggers; + die("\n"); + } + + my $debugger = $opts->{debugger}; + $debugger =~ s/\d+$//; + + my $method = "start_" . $debuggers{$debugger}; + + ## $opts->{debugger} is passed through unchanged + ## so when we try to run it next, its found. + $self->$method($opts); +} + +sub pid { + my $self = shift; + my $file = $self->pid_file; + my $fh = Symbol::gensym(); + open $fh, $file or do { + return 0; + }; + + # try to avoid the race condition when the pid file was created + # but not yet written to + for (1..8) { + last if -s $file > 0; + select undef, undef, undef, 0.25; + } + + chomp(my $pid = <$fh> || ''); + $pid; +} + +sub select_next_port { + my $self = shift; + + my $max_tries = 100; #XXX + while ($max_tries-- > 0) { + return $self->{port_counter} + if $self->port_available(++$self->{port_counter}); + } + + return 0; +} + +sub port_available { + my $self = shift; + my $port = shift || $self->{config}->{vars}->{port}; + local *S; + + my $proto = getprotobyname('tcp'); + + socket(S, Socket::PF_INET(), + Socket::SOCK_STREAM(), $proto) || die "socket: $!"; + setsockopt(S, Socket::SOL_SOCKET(), + Socket::SO_REUSEADDR(), + pack("l", 1)) || die "setsockopt: $!"; + + if (bind(S, Socket::sockaddr_in($port, Socket::INADDR_ANY()))) { + close S; + return 1; + } + else { + return 0; + } +} + +=head2 stop() + +attempt to stop the server. + +returns: + + on success: $pid of the server + on failure: -1 + +=cut + +sub stop { + my $self = shift; + my $aborted = shift; + + if (WIN32) { + require Win32::Process; + my $obj = $self->{config}->{win32obj}; + my $pid = -1; + if ($pid = $obj ? $obj->GetProcessID : $self->pid) { + if (kill(0, $pid)) { + Win32::Process::KillProcess($pid, 0); + warning "server $self->{name} shutdown"; + } + } + unlink $self->pid_file if -e $self->pid_file; + return $pid; + } + + my $pid = 0; + my $tries = 3; + my $tried_kill = 0; + + my $port = $self->{config}->{vars}->{port}; + + while ($self->ping) { + #my $state = $tried_kill ? "still" : "already"; + #print "Port $port $state in use\n"; + + if ($pid = $self->pid and !$tried_kill++) { + if (kill TERM => $pid) { + warning "server $self->{name} shutdown"; + sleep 1; + + for (1..6) { + if (! $self->ping) { + if ($_ == 1) { + unlink $self->pid_file if -e $self->pid_file; + return $pid; + } + last; + } + if ($_ == 1) { + warning "port $port still in use..."; + } + else { + print "..."; + } + sleep $_; + } + + if ($self->ping) { + error "\nserver was shutdown but port $port ". + "is still in use, please shutdown the service ". + "using this port or select another port ". + "for the tests"; + } + else { + print "done\n"; + } + } + else { + error "kill $pid failed: $!"; + } + } + else { + error "port $port is in use, ". + "cannot determine server pid to shutdown"; + return -1; + } + + if (--$tries <= 0) { + error "cannot shutdown server on Port $port, ". + "please shutdown manually"; + unlink $self->pid_file if -e $self->pid_file; + return -1; + } + } + + unlink $self->pid_file if -e $self->pid_file; + return $pid; +} + +sub ping { + my $self = shift; + my $pid = $self->pid; + + if ($pid and kill 0, $pid) { + return $pid; + } + elsif (! $self->port_available) { + return -1; + } + + return 0; +} + +sub failed_msg { + my $self = shift; + my($log, $rlog) = $self->{config}->error_log; + my $log_file_info = -e $log ? + "please examine $rlog" : + "$rlog wasn't created, start the server in the debug mode"; + error "@_ ($log_file_info)"; +} + +#this doesn't work well on solaris or hpux at the moment +use constant USE_SIGCHLD => $^O eq 'linux'; + +sub start { + my $self = shift; + + my $old_pid = -1; + if (WIN32) { + # Stale PID files (e.g. left behind from a previous test run + # that crashed) cannot be trusted on Windows because PID's are + # re-used too frequently, so just remove it. If there is an old + # server still running then the attempt to start a new one below + # will simply fail because the port will be unavailable. + if (-f $self->pid_file) { + error "Removing old PID file -- " . + "Unclean shutdown of previous test run?\n"; + unlink $self->pid_file; + } + $old_pid = 0; + } + else { + $old_pid = $self->stop; + } + my $cmd = $self->start_cmd; + my $config = $self->{config}; + my $vars = $config->{vars}; + my $httpd = $vars->{httpd} || 'unknown'; + + if ($old_pid == -1) { + return 0; + } + + local $| = 1; + + unless (-x $httpd) { + my $why = -e $httpd ? "is not executable" : "does not exist"; + error "cannot start server: httpd ($httpd) $why"; + return 0; + } + + print "$cmd\n"; + my $old_sig; + + if (WIN32) { + #make sure only 1 process is started for win32 + #else Kill will only shutdown the parent + my $one_process = $self->version_of(\%one_process); + require Win32::Process; + my $obj; + # We need the "1" below to inherit the calling processes + # handles when running Apache::TestSmoke so as to properly + # dup STDOUT/STDERR + Win32::Process::Create($obj, + $httpd, + "$cmd $one_process", + 1, + Win32::Process::NORMAL_PRIORITY_CLASS(), + '.'); + unless ($obj) { + die "Could not start the server: " . + Win32::FormatMessage(Win32::GetLastError()); + } + $config->{win32obj} = $obj; + } + else { + $old_sig = $SIG{CHLD}; + + if (USE_SIGCHLD) { + # XXX: try not to be POSIX dependent + require POSIX; + + #XXX: this is not working well on solaris or hpux + $SIG{CHLD} = sub { + while ((my $child = waitpid(-1, POSIX::WNOHANG())) > 0) { + my $status = $? >> 8; + #error "got child exit $status"; + if ($status) { + my $msg = "server has died with status $status"; + $self->failed_msg("\n$msg"); + Apache::TestRun->new(test_config => $config)->scan_core; + kill SIGTERM => $$; + } + } + }; + } + + defined(my $pid = fork) or die "Can't fork: $!"; + unless ($pid) { # child + my $status = system "$cmd"; + if ($status) { + $status = $? >> 8; + #error "httpd didn't start! $status"; + } + CORE::exit $status; + } + } + + while ($old_pid and $old_pid == $self->pid) { + warning "old pid file ($old_pid) still exists"; + sleep 1; + } + + my $version = $self->{version}; + my $mpm = $config->{mpm} || ""; + $mpm = "($mpm MPM)" if $mpm; + print "using $version $mpm\n"; + + my $timeout = $vars->{startup_timeout} || + $ENV{APACHE_TEST_STARTUP_TIMEOUT} || + 60; + + my $start_time = time; + my $preamble = "${CTRL_M}waiting $timeout seconds for server to start: "; + print $preamble unless COLOR; + while (1) { + my $delta = time - $start_time; + print COLOR + ? ($preamble, sprintf "%02d:%02d", (gmtime $delta)[1,0]) + : '.'; + sleep 1; + if ($self->pid) { + print $preamble, "ok (waited $delta secs)\n"; + last; + } + elsif ($delta > $timeout) { + my $suggestion = $timeout + 300; + print $preamble, "not ok\n"; + error <<EOI; +giving up after $delta secs. If you think that your system +is slow or overloaded try again with a longer timeout value. +by setting the environment variable APACHE_TEST_STARTUP_TIMEOUT +to a high value (e.g. $suggestion) and repeat the last command. +EOI + last; + } + } + + # now that the server has started don't abort the test run if it + # dies + $SIG{CHLD} = $old_sig || 'DEFAULT'; + + if (my $pid = $self->pid) { + print "server $self->{name} started\n"; + + my $vh = $config->{vhosts}; + my $by_port = sub { $vh->{$a}->{port} <=> $vh->{$b}->{port} }; + + for my $module (sort $by_port keys %$vh) { + print "server $vh->{$module}->{name} listening ($module)\n", + } + + if ($config->configure_proxy) { + print "tests will be proxied through $vars->{proxy}\n"; + } + } + else { + $self->failed_msg("server failed to start!"); + return 0; + } + + return 1 if $self->wait_till_is_up($timeout); + + $self->failed_msg("failed to start server!"); + return 0; +} + + +# wait till the server is up and return 1 +# if the waiting times out returns 0 +sub wait_till_is_up { + my($self, $timeout) = @_; + my $config = $self->{config}; + my $sleep_interval = 1; # secs + + my $server_up = sub { + local $SIG{__WARN__} = sub {}; #avoid "cannot connect ..." warnings + # avoid fatal errors when LWP is not available + return eval { + my $r=Apache::TestRequest::GET('/index.html'); + $r->code!=500 or $r->header('client-warning')!~/internal/i; + } || 0; + }; + + if ($server_up->()) { + return 1; + } + + my $start_time = time; + my $preamble = "${CTRL_M}still waiting for server to warm up: "; + print $preamble unless COLOR; + while (1) { + my $delta = time - $start_time; + print COLOR + ? ($preamble, sprintf "%02d:%02d", (gmtime $delta)[1,0]) + : '.'; + sleep $sleep_interval; + if ($server_up->()) { + print "${CTRL_M}the server is up (waited $delta secs) \n"; + return 1; + } + elsif ($delta > $timeout) { + print "${CTRL_M}the server is down, giving up after $delta secs\n"; + return 0; + } + else { + # continue + } + } +} + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestSmoke.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestSmoke.pm new file mode 100644 index 0000000..decc11b --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestSmoke.pm @@ -0,0 +1,949 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestSmoke; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test (); +use Apache::TestConfig (); +use Apache::TestTrace; + +use Apache::TestHarness (); +use Apache::TestRun (); # for core scan functions +use Apache::TestSort; + +use Getopt::Long qw(GetOptions); +use File::Spec::Functions qw(catfile); +use FindBin; +use POSIX (); +use Symbol (); + +#use constant DEBUG => 1; + +# how many times to run all tests at the first iteration +use constant DEFAULT_TIMES => 10; + +# if after this number of tries to reduce the number of tests fails we +# give up on more tries +use constant MAX_REDUCTION_TRIES => 50; + +my @num_opts = qw(times); +my @string_opts = qw(order report); +my @flag_opts = qw(help verbose bug_mode); + +my %order = map {$_ => 1} qw(random repeat); + +my %usage = ( + 'times=N' => 'how many times to run the entire test suite' . + ' (default: ' . DEFAULT_TIMES . ')', + 'order=MODE' => 'modes: random, repeat' . + ' (default: random)', + 'report=FILENAME' => 'save report in a filename' . + ' (default: smoke-report-<date>.txt)', + 'verbose[=1]' => 'verbose output' . + ' (default: 0)', + 'bug_mode' => 'bug report mode' . + ' (default: 0)', +); + +sub new { + my($class, @argv) = @_; + + my $self = bless { + seen => {}, # seen sequences and tried them md5 hash + results => {}, # final reduced sequences md5 hash + smoking_completed => 0, + tests => [], + total_iterations => 0, + total_reduction_attempts => 0, + total_reduction_successes => 0, + total_tests_run => 0, + }, ref($class)||$class; + + $self->{test_config} = Apache::TestConfig->thaw; + + $self->getopts(\@argv); + my $opts = $self->{opts}; + + chdir "$FindBin::Bin/.."; + $self->{times} = $opts->{times} || DEFAULT_TIMES; + $self->{order} = $opts->{order} || 'random'; + $self->{verbose} = $opts->{verbose} || 0; + + $self->{run_iter} = $self->{times}; + + # this is like 'make test' but produces an output to be used in + # the bug report + if ($opts->{bug_mode}) { + $self->{bug_mode} = 1; + $self->{run_iter} = 1; + $self->{times} = 1; + $self->{verbose} = 1; + $self->{order} = 'random'; + $self->{trace} = 'debug'; + } + + # specific tests end up in $self->{tests} and $self->{subtests}; + # and get removed from $self->{argv} + $self->Apache::TestRun::split_test_args(); + + my $test_opts = { + verbose => $self->{verbose}, + tests => $self->{tests}, + order => $self->{order}, + subtests => $self->{subtests} || [], + }; + + @{ $self->{tests} } = $self->get_tests($test_opts); + + $self->{base_command} = "$^X $FindBin::Bin/TEST"; + + # options common to all + $self->{base_command} .= " -verbose" if $self->{verbose}; + + # options specific to the startup + $self->{start_command} = "$self->{base_command} -start"; + $self->{start_command} .= " -trace=" . $self->{trace} if $self->{trace}; + + # options specific to the run + $self->{run_command} = "$self->{base_command} -run"; + + # options specific to the stop + $self->{stop_command} = "$self->{base_command} -stop"; + + $self; +} + +sub getopts { + my($self, $argv) = @_; + my %opts; + local *ARGV = $argv; + + # permute : optional values can come before the options + # pass_through : all unknown things are to be left in @ARGV + Getopt::Long::Configure(qw(pass_through permute)); + + # grab from @ARGV only the options that we expect + GetOptions(\%opts, @flag_opts, + (map "$_=s", @string_opts), + (map "$_=i", @num_opts)); + + if (exists $opts{order} && !exists $order{$opts{order}}) { + error "unknown -order mode: $opts{order}"; + $self->opt_help(); + exit; + } + + if ($opts{help}) { + $self->opt_help; + exit; + } + + # min + $self->{opts} = \%opts; + + $self->{argv} = [@ARGV]; +} + +# XXX: need proper sub-classing +# from Apache::TestHarness +sub skip { Apache::TestHarness::skip(@_); } +sub prune { Apache::TestHarness::prune(@_); } +sub get_tests { Apache::TestHarness::get_tests(@_);} + +sub install_sighandlers { + my $self = shift; + + $SIG{INT} = sub { + # make sure that there the server is down + $self->kill_proc(); + + $self->report_finish; + exit; + }; +} + +END { + local $?; # preserve the exit status + eval { + Apache::TestRun->new(test_config => + Apache::TestConfig->thaw)->scan_core; + }; +} + +sub run { + my($self) = shift; + + $self->Apache::TestRun::warn_core(); + local $SIG{INT}; + $self->install_sighandlers; + + $self->report_start(); + + if ($self->{bug_mode}) { + # 'make test', but useful for bug reports + $self->run_bug_mode(); + } + else { + # normal smoke + my $iter = 0; + while ($iter++ < $self->{run_iter}) { + my $last = $self->run_iter($iter); + last if $last; + } + } + $self->{smoking_completed} = 1; + $self->report_finish(); + exit; +} + +sub sep { + my($char, $title) = @_; + my $width = 60; + if ($title) { + my $side = int( ($width - length($title) - 2) / 2); + my $pad = ($side+1) * 2 + length($title) < $width ? 1 : 0; + return $char x $side . " $title " . $char x ($side+$pad); + } + else { + return $char x $width; + } +} + +my %log_files = (); +use constant FH => 0; +use constant POS => 1; +sub logs_init { + my($self, @log_files) = @_; + + for my $path (@log_files) { + my $fh = Symbol::gensym(); + open $fh, "<$path" or die "Can't open $path: $!"; + seek $fh, 0, POSIX::SEEK_END(); + $log_files{$path}[FH] = $fh; + $log_files{$path}[POS] = tell $fh; + } +} + +sub logs_end { + for my $path (keys %log_files) { + close $log_files{$path}[FH]; + } +} + +sub log_diff { + my($self, $path) = @_; + + my $log = $log_files{$path}; + die "no such log file: $path" unless $log; + + my $fh = $log->[FH]; + # no checkpoints were made yet? + unless (defined $log->[POS]) { + seek $fh, 0, POSIX::SEEK_END(); + $log->[POS] = tell $fh; + return ''; + } + + seek $fh, $log->[POS], POSIX::SEEK_SET(); # not really needed + local $/; # slurp mode + my $diff = <$fh>; + seek $fh, 0, POSIX::SEEK_END(); # not really needed + $log->[POS] = tell $fh; + + return $diff || ''; +} + +# this is a special mode, which really just runs 't/TEST -start; +# t/TEST -run; t/TEST -stop;' but it runs '-run' separately for each +# test, and checks whether anything bad has happened after the run +# of each test (i.e. either a test has failed, or a test may be successful, +# but server may have dumped a core file, we detect that). +sub run_bug_mode { + my($self) = @_; + + my $iter = 0; + + warning "running t/TEST in the bug report mode"; + + my $reduce_iter = 0; + my @good = (); + + # first time run all tests, or all specified tests + my @tests = @{ $self->{tests} }; # copy + my $bad = $self->run_test($iter, $reduce_iter, \@tests, \@good); + $self->{total_iterations}++; + +} + + +# returns true if for some reason no more iterations should be made +sub run_iter { + my($self, $iter) = @_; + my $stop_now = 0; + my $reduce_iter = 0; + my @good = (); + warning "\n" . sep("-"); + warning sprintf "[%03d-%02d-%02d] running all tests", + $iter, $reduce_iter, $self->{times}; + + + # first time run all tests, or all specified tests + my @tests = @{ $self->{tests} }; # copy + + # hack to ensure a new random seed is generated + Apache::TestSort->run(\@tests, $self); + + my $bad = $self->run_test($iter, $reduce_iter, \@tests, \@good); + unless ($bad) { + $self->{total_iterations}++; + return $stop_now; + } + error "recorded a positive failure ('$bad'), " . + "will try to minimize the input now"; + + my $command = $self->{base_command}; + + # does the test fail on its own + { + $reduce_iter++; + warning sprintf "[%03d-%02d-%02d] trying '$bad' on its own", + $iter, $reduce_iter, 1; + my @good = (); + my @tests = ($bad); + my $bad = $self->run_test($iter, $reduce_iter, \@tests, \@good); + # if a test is failing on its own there is no point to + # continue looking for other sequences + if ($bad) { + $stop_now = 1; + $self->{total_iterations}++; + unless ($self->sequence_seen($self->{results}, [@good, $bad])) { + $self->report_success($iter, $reduce_iter, "$command $bad", 1); + } + return $stop_now; + } + } + + # positive failure + my $ok_tests = @good; + my $reduction_success = 0; + my $done = 0; + while (@good > 1) { + my $tries = 0; + my $reduce_sub = $self->reduce_stream(\@good); + $reduce_iter++; + while ($tries++ < MAX_REDUCTION_TRIES) { + $self->{total_reduction_attempts}++; + my @try = @{ $reduce_sub->() }; + + # reduction stream is empty (tried all?) + unless (@try) { + $done = 1; + last; + } + + warning sprintf "\n[%03d-%02d-%02d] trying %d tests", + $iter, $reduce_iter, $tries, scalar(@try); + my @ok = (); + my @tests = (@try, $bad); + my $new_bad = $self->run_test($iter, $reduce_iter, \@tests, \@ok); + if ($new_bad) { + # successful reduction + $reduction_success++; + @good = @ok; + $tries = 0; + my $num = @ok; + error "*** reduction $reduce_iter succeeded ($num tests) ***"; + $self->{total_reduction_successes}++; + $self->log_successful_reduction($iter, \@ok); + last; + } + } + + # last round of reducing has failed, so we give up + if ($done || $tries >= MAX_REDUCTION_TRIES){ + error "no further reductions were made"; + $done = 1; + last; + } + + } + + # we have a minimal failure sequence at this point (to the extend + # of success of our attempts to reduce) + + # report the sequence if we didn't see such one yet in the + # previous iterations + unless ($self->sequence_seen($self->{results}, [@good, $bad])) { + # if no reduction succeeded, it's 0 + $reduce_iter = 0 unless $reduction_success; + $self->report_success($iter, $reduce_iter, + "$command @good $bad", @good + 1); + } + + $self->{total_iterations}++; + + return $stop_now; +} + +# my $sub = $self->reduce_stream(\@items); +sub reduce_stream { + my($self) = shift; + my @items = @{+shift}; + + my $items = @items; + my $odd = $items % 2 ? 1 : 0; + my $middle = int($items/2) - 1; + my $c = 0; + + return sub { + $c++; # remember stream's state + + # a single item is not reduce-able + return \@items if $items == 1; + + my @try = (); + my $max_repeat_tries = 50; # avoid seen sequences + my $repeat = 0; + while ($repeat++ <= $max_repeat_tries) { + + # try to use a binary search + if ($c == 1) { + # right half + @try = @items[($middle+1)..($items-1)]; + } + elsif ($c == 2) { + # left half + @try = @items[0..$middle]; + } + + # try to use a random window size alg + else { + my $left = int rand($items); + $left = $items - 1 if $left == $items - 1; + my $right = $left + int rand($items - $left); + $right = $items - 1 if $right >= $items; + @try = @items[$left..$right]; + } + + if ($self->sequence_seen($self->{seen}, \@try)) { + @try = (); + } + else { + last; # found an unseen sequence + } + } + return \@try; + } +} + +sub sequence_seen { + my ($self, $rh_store, $ra_tests) = @_; + + require Digest::MD5; + my $digest = Digest::MD5::md5_hex(join '', @$ra_tests); + #error $self->{seen}; + return $rh_store->{$digest}++ ? 1 : 0 + +} + +sub run_test { + require IPC::Run3; + my($self, $iter, $count, $tests, $ra_ok) = @_; + my $bad = ''; + my $ra_nok = []; + + #warning "$self->{base_command} @$tests"; + + #$SIG{PIPE} = 'IGNORE'; + $SIG{PIPE} = sub { die "pipe broke" }; + + # start server + { + my $command = $self->{start_command}; + my $log = ''; + IPC::Run3::run3($command, undef, \$log, \$log); + my $started_ok = ($log =~ /started/) ? 1 : 0; + unless ($started_ok) { + error "failed to start server\n $log"; + exit 1; + } + } + + my $t_logs = $self->{test_config}->{vars}->{t_logs}; + my @log_files = map { catfile $t_logs, $_ } qw(error_log access_log); + $self->logs_init(@log_files); + + # run tests + { + my $command = $self->{run_command}; + + my $max_len = 1; + for my $test (@$tests) { + $max_len = length $test if length $test > $max_len; + } + + for my $test (@$tests) { + (my $test_name = $test) =~ s/\.t$//; + my $fill = "." x ($max_len - length $test_name); + $self->{total_tests_run}++; + + my $test_command = "$command $test"; + my $log = ''; + IPC::Run3::run3($test_command, undef, \$log, \$log); + my $ok = ($log =~ /All tests successful|NOTESTS/) ? 1 : 0; + + my @core_files_msg = $self->Apache::TestRun::scan_core_incremental(1); + + # if the test has caused core file(s) it's not ok + $ok = 0 if @core_files_msg; + + if ($ok == 1) { + push @$ra_ok, $test; + if ($self->{verbose}) { + + if ($log =~ m/NOTESTS/) { + print STDERR "$test_name${fill}skipped\n"; + } else { + print STDERR "$test_name${fill}ok\n"; + } + } + # need to run log_diff to reset the position of the fh + my %log_diffs = map { $_ => $self->log_diff($_) } @log_files; + + } + elsif ($ok == 0) { + push @$ra_nok, $test; + $bad = $test; + + if ($self->{verbose}) { + print STDERR "$test_name${fill}FAILED\n"; + error sep("-"); + + # give server some time to finish the + # logging. it's ok to wait long time since we have + # to deal with an error + sleep 5; + my %log_diffs = map { $_ => $self->log_diff($_) } @log_files; + + # client log + error "\t\t*** run log ***"; + $log =~ s/^/ /mg; + print STDERR "$log\n"; + + # server logs + for my $path (@log_files) { + next unless length $log_diffs{$path}; + error "\t\t*** $path ***"; + $log_diffs{$path} =~ s/^/ /mg; + print STDERR "$log_diffs{$path}\n"; + } + } + if (@core_files_msg) { + unless ($self->{verbose}) { + # currently the output of 'run log' already + # includes the information about core files once + # Test::Harness::Straps allows us to run callbacks + # after each test, and we move back to run all + # tests at once, we will log the message here + error "$test_name caused core"; + print STDERR join "\n", @core_files_msg, "\n"; + } + } + + if ($self->{verbose}) { + error sep("-"); + } + + unless ($self->{bug_mode}) { + # normal smoke stop the run, but in the bug_mode + # we want to complete all the tests + last; + } + } + + + } + } + + $self->logs_end(); + + # stop server + $self->kill_proc(); + + if ($self->{bug_mode}) { + warning sep("-"); + if (@$ra_nok == 0) { + printf STDERR "All tests successful (%d)\n", scalar @$ra_ok; + } + else { + error sprintf "error running %d tests out of %d\n", + scalar(@$ra_nok), scalar @$ra_ok + @$ra_nok; + } + } + else { + return $bad; + } + + +} + +sub report_start { + my($self) = shift; + + my $time = scalar localtime; + $self->{start_time} = $time; + $time =~ s/\s/_/g; + $time =~ s/:/-/g; # winFU + my $file = $self->{opts}->{report} || + catfile Apache::Test::vars('top_dir'), "smoke-report-$time.txt"; + $self->{runtime}->{report} = $file; + info "Report file: $file"; + + open my $fh, ">$file" or die "cannot open $file for writing: $!"; + $self->{fh} = $fh; + my $sep = sep("-"); + my $title = sep('=', "Special Tests Sequence Failure Finder Report"); + + print $fh <<EOM; +$title +$sep +First iteration used: +$self->{base_command} @{$self->{tests}} +$sep +EOM + +} + +sub report_success { + my($self, $iter, $reduce_iter, $sequence, $tests) = @_; + + my @report = ("iteration $iter ($tests tests):\n", + "\t$sequence\n", + "(made $reduce_iter successful reductions)\n\n"); + + print @report; + if (my $fh = $self->{fh}) { + print $fh @report; + } +} + +sub report_finish { + my($self) = @_; + + my $start_time = $self->{start_time}; + my $end_time = scalar localtime; + if (my $fh = delete $self->{fh}) { + my $failures = scalar keys %{ $self->{results} }; + + my $sep = sep("-"); + my $cfg_as_string = $self->build_config_as_string; + my $unique_seqs = scalar keys %{ $self->{results} }; + my $attempts = $self->{total_reduction_attempts}; + my $successes = $self->{total_reduction_successes}; + my $completion = $self->{smoking_completed} + ? "Completed" + : "Not Completed (aborted by user)"; + + my $status = "Unknown"; + if ($self->{total_iterations} > 0) { + if ($failures) { + $status = "*** NOT OK ***"; + } + else { + $status = "+++ OK +++"; + } + } + + my $title = sep('=', "Summary"); + + my $iter_made = sprintf "Iterations (%s) made : %d", + $self->{order}, $self->{total_iterations}; + + print $fh <<EOM; + +$title +Completion : $completion +Status : $status +Tests run : $self->{total_tests_run} +$iter_made +EOM + + if ($attempts > 0 && $failures) { + my $reduction_stats = sprintf "%d/%d (%d%% success)", + $attempts, $successes, $successes / $attempts * 100; + + print $fh <<EOM; +Unique sequences found : $unique_seqs +Reduction tries/success : $reduction_stats +EOM + } + + print $fh <<EOM; +$sep +--- Started at: $start_time --- +--- Ended at: $end_time --- +$sep +The smoke testing was run on the system with the following +parameters: + +$cfg_as_string + +-- this report was generated by $0 +EOM + close $fh; + } +} + +# in case the smoke gets killed before it had a chance to finish and +# write the report, at least we won't lose the last successful reduction +# XXX: this wasn't needed before we switched to IPC::Run3, since +# Ctrl-C would log the collected data, but it doesn't work with +# IPC::Run3. So if that gets fixed, we can remove that function +sub log_successful_reduction { + my($self, $iter, $tests) = @_; + + my $file = $self->{runtime}->{report} . ".$iter.temp"; + debug "saving in $file"; + open my $fh, ">$file" or die "cannot open $file for writing: $!"; + print $fh join " ", @$tests; + close $fh; +} + +sub build_config_as_string { + Apache::TestConfig::as_string(); +} + +sub kill_proc { + my($self) = @_; + + my $command = $self->{stop_command}; + my $log = ''; + require IPC::Run3; + IPC::Run3::run3($command, undef, \$log, \$log); + + my $stopped_ok = ($log =~ /shutdown/) ? 1 : 0; + unless ($stopped_ok) { + error "failed to stop server\n $log"; + } +} + +sub opt_help { + my $self = shift; + + print <<EOM; +usage: t/SMOKE [options ...] [tests] + where the options are: +EOM + + for (sort keys %usage){ + printf " -%-16s %s\n", $_, $usage{$_}; + } + print <<EOM; + + if 'tests' argument is not provided all available tests will be run +EOM +} + +# generate t/SMOKE script (or a different filename) which will drive +# Apache::TestSmoke +sub generate_script { + my ($class, $file) = @_; + + $file ||= catfile 't', 'SMOKE'; + + my $content = join "\n", + "BEGIN { eval { require blib && blib->import; } }", + Apache::TestConfig->perlscript_header, + "use $class;", + "$class->new(\@ARGV)->run;"; + + Apache::Test::basic_config()->write_perlscript($file, $content); +} + +1; +__END__ + +=head1 NAME + +Apache::TestSmoke - Special Tests Sequence Failure Finder + +=head1 SYNOPSIS + + # get the usage and the default values + % t/SMOKE -help + + # repeat all tests 5 times and save the report into + # the file 'myreport' + % t/SMOKE -times=5 -report=myreport + + # run all tests default number of iterations, and repeat tests + # default number of times + % t/SMOKE + + # same as above but work only the specified tests + % t/SMOKE foo/bar foo/tar + + # run once a sequence of tests in a non-random mode + # e.g. when trying to reduce a known long sequence that fails + % t/SMOKE -order=rotate -times=1 foo/bar foo/tar + + # show me each currently running test + # it's not the same as running the tests in the verbose mode + % t/SMOKE -verbose + + # run t/TEST, but show any problems after *each* tests is run + # useful for bug reports (it actually runs t/TEST -start, then + # t/TEST -run for each test separately and finally t/TEST -stop + % t/SMOKE -bug_mode + + # now read the created report file + +=head1 DESCRIPTION + +=head2 The Problem + +When we try to test a stateless machine (i.e. all tests are +independent), running all tests once ensures that all tested things +properly work. However when a state machine is tested (i.e. where a +run of one test may influence another test) it's not enough to run all +the tests once to know that the tested features actually work. It's +quite possible that if the same tests are run in a different order +and/or repeated a few times, some tests may fail. This usually +happens when some tests don't restore the system under test to its +pristine state at the end of the run, which may influence other tests +which rely on the fact that they start on pristine state, when in fact +it's not true anymore. In fact it's possible that a single test may +fail when run twice or three times in a sequence. + +=head2 The Solution + +To reduce the possibility of such dependency errors, it's helpful to +run random testing repeated many times with many different srand +seeds. Of course if no failures get spotted that doesn't mean that +there are no tests inter-dependencies, which may cause a failure in +production. But random testing definitely helps to spot many problems +and can give better test coverage. + +=head2 Resolving Sequence Problems + +When this kind of testing is used and a failure is detected there are +two problems: + +=over + +=item 1 + +First is to be able to reproduce the problem so if we think we fixed +it, we could verify the fix. This one is easy, just remember the +sequence of tests run till the failed test and rerun the same sequence +once again after the problem has been fixed. + +=item 2 + +Second is to be able to understand the cause of the problem. If during +the random test the failure has happened after running 400 tests, how +can we possibly know which previously running tests has caused to the +failure of the test 401. Chances are that most of the tests were clean +and don't have inter-dependency problem. Therefore it'd be very +helpful if we could reduce the long sequence to a minimum. Preferably +1 or 2 tests. That's when we can try to understand the cause of the +detected problem. + +=back + +This utility attempts to solve both problems, and at the end of each +iteration print a minimal sequence of tests causing to a failure. This +doesn't always succeed, but works in many cases. + +This utility: + +=over + +=item 1 + +Runs the tests randomly until the first failure is detected. Or +non-randomly if the option I<-order> is set to I<repeat> or I<rotate>. + +=item 2 + +Then it tries to reduce that sequence of tests to a minimum, and this +sequence still causes to the same failure. + +=item 3 + +(XXX: todo): then it reruns the minimal sequence in the verbose mode +and saves the output. + +=item 4 + +It reports all the successful reductions as it goes to STDOUT and +report file of the format: smoke-report-<date>.txt. + +In addition the systems build parameters are logged into the report +file, so the detected problems could be reproduced. + +=item 5 + +Goto 1 and run again using a new random seed, which potentially should +detect different failures. + +=back + +=head1 Reduction Algorithm + +Currently for each reduction path, the following reduction algorithms +get applied: + +=over + +=item 1 + +Binary search: first try the upper half then the lower. + +=item 2 + +Random window: randomize the left item, then the right item and return +the items between these two points. + +=back + +=head1 t/SMOKE.PL + +I<t/SMOKE.PL> is driving this module, if you don't have it, create it: + + #!perl + + use strict; + use warnings FATAL => 'all'; + + use FindBin; + use lib "$FindBin::Bin/../Apache-Test/lib"; + use lib "$FindBin::Bin/../lib"; + + use Apache::TestSmoke (); + + Apache::TestSmoke->new(@ARGV)->run; + +usually I<Makefile.PL> converts it into I<t/SMOKE> while adjusting the +perl path, but you create I<t/SMOKE> in first place as well. + +=head1 AUTHOR + +Stas Bekman + +=cut diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestSmokePerl.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestSmokePerl.pm new file mode 100644 index 0000000..265a4f7 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestSmokePerl.pm @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestSmokePerl; + +use strict; +use warnings FATAL => 'all'; + +use Apache::TestSmoke (); +use ModPerl::Config (); + +# a subclass of Apache::TestSmoke that configures mod_perlish things +use vars qw(@ISA); +@ISA = qw(Apache::TestSmoke); + +sub build_config_as_string { + ModPerl::Config::as_string(); +} + +1; +__END__ + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestSort.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestSort.pm new file mode 100644 index 0000000..33eabc2 --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestSort.pm @@ -0,0 +1,76 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestSort; + +use strict; +use warnings FATAL => 'all'; +use Apache::TestTrace; + +sub repeat { + my($list) = @_; + return @{$list}; +} + +sub random { + my($list) = @_; + + my $seed = $ENV{APACHE_TEST_SEED} || ''; + my $info = ""; + + if ($seed) { + $info = " (user defined)"; + # so we could reproduce the order + } + else { + $info = " (autogenerated)"; + $seed = time ^ ($$ + ($$ << 15)); + } + + warning "Using random number seed: $seed" . $info; + + srand($seed); + + #from perlfaq4.pod + for (my $i = @$list; --$i; ) { + my $j = int rand($i+1); + next if $i == $j; + @$list[$i,$j] = @$list[$j,$i]; + } +} + +sub run { + my($self, $list, $args) = @_; + + my $order = $args->{order} || 'repeat'; + if ($order =~ /^\d+$/) { + #dont want an explicit -seed option but env var can be a pain + #so if -order is number assume it is the random seed + $ENV{APACHE_TEST_SEED} = $order; + $order = 'random'; + } + my $sort = \&{$order}; + + # re-shuffle the list according to the requested order + if (defined &$sort) { + $sort->($list); + } + else { + error "unknown order '$order'"; + } + +} + +1; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm new file mode 100644 index 0000000..00426ea --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm @@ -0,0 +1,256 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestTrace; + +use strict; +use warnings FATAL => 'all'; + +use Exporter (); +use vars qw(@Levels @Utils @Level_subs @Util_subs + @ISA @EXPORT $VERSION $Level $LogFH); + +BEGIN { + @Levels = qw(emerg alert crit error warning notice info debug); + @Utils = qw(todo); + @Level_subs = map {($_, "${_}_mark", "${_}_sub")} (@Levels); + @Util_subs = map {($_, "${_}_mark", "${_}_sub")} (@Utils); +} + +@ISA = qw(Exporter); +@EXPORT = (@Level_subs); +$VERSION = '0.01'; +use subs (@Level_subs, @Util_subs); + +# default settings overrideable by users +$Level = undef; +$LogFH = \*STDERR; + +# private data +use constant COLOR => ($ENV{APACHE_TEST_COLOR} && -t STDOUT) ? 1 : 0; +use constant HAS_COLOR => eval { + #XXX: another way to color WINFU terms? + !(grep { $^O eq $_ } qw(MSWin32 cygwin NetWare)) and + COLOR and require Term::ANSIColor; +}; +use constant HAS_DUMPER => eval { require Data::Dumper; }; + +# emerg => 1, alert => 2, crit => 3, ... +my %levels; @levels{@Levels} = 1..@Levels; +$levels{todo} = $levels{debug}; +my $default_level = 'info'; # to prevent user typos + +my %colors = (); + +if (HAS_COLOR) { + %colors = ( + emerg => 'bold white on_blue', + alert => 'bold blue on_yellow', + crit => 'reverse', + error => 'bold red', + warning => 'yellow', + notice => 'green', + info => 'cyan', + debug => 'magenta', + reset => 'reset', + todo => 'underline', + ); + + $Term::ANSIColor::AUTORESET = 1; + + for (keys %colors) { + $colors{$_} = Term::ANSIColor::color($colors{$_}); + } +} + +*expand = HAS_DUMPER ? + sub { map { ref $_ ? Data::Dumper::Dumper($_) : $_ } @_ } : + sub { @_ }; + +sub prefix { + my $prefix = shift; + + if ($prefix eq 'mark') { + return join(":", (caller(3))[1..2]) . " : "; + } + elsif ($prefix eq 'sub') { + return (caller(3))[3] . " : "; + } + else { + return ''; + } +} + +sub c_trace { + my ($level, $prefix_type) = (shift, shift); + my $prefix = prefix($prefix_type); + print $LogFH + map { "$colors{$level}$prefix$_$colors{reset}\n"} + grep defined($_), expand(@_); +} + +sub nc_trace { + my ($level, $prefix_type) = (shift, shift); + my $prefix = prefix($prefix_type); + print $LogFH + map { sprintf "[%7s] %s%s\n", $level, $prefix, $_ } + grep defined($_), expand(@_); +} + +{ + my $trace = HAS_COLOR ? \&c_trace : \&nc_trace; + my @prefices = ('', 'mark', 'sub'); + # if the level is sufficiently high, enable the tracing for a + # given level otherwise assign NOP + for my $level (@Levels, @Utils) { + no strict 'refs'; + for my $prefix (@prefices) { + my $func = $prefix ? "${level}_$prefix" : $level; + *$func = sub { $trace->($level, $prefix, @_) + if trace_level() >= $levels{$level}; + }; + } + } +} + +sub trace_level { + # overriden by user/-trace + (defined $Level && $levels{$Level}) || + # or overriden by env var + (exists $ENV{APACHE_TEST_TRACE_LEVEL} && + $levels{$ENV{APACHE_TEST_TRACE_LEVEL}}) || + # or default + $levels{$default_level}; +} + +1; +__END__ + +=head1 NAME + +Apache::TestTrace - Helper output generation functions + +=head1 SYNOPSIS + + use Apache::TestTrace; + + debug "foo bar"; + + info_sub "missed it"; + + error_mark "something is wrong"; + + # test sub that exercises all the tracing functions + sub test { + print $Apache::TestTrace::LogFH + "TraceLevel: $Apache::TestTrace::Level\n"; + $_->($_,[1..3],$_) for qw(emerg alert crit error + warning notice info debug todo); + print $Apache::TestTrace::LogFH "\n\n" + }; + + # demo the trace subs using default setting + test(); + + { + # override the default trace level with 'crit' + local $Apache::TestTrace::Level = 'crit'; + # now only 'crit' and higher levels will do tracing lower level + test(); + } + + { + # set the trace level to 'debug' + local $Apache::TestTrace::Level = 'debug'; + # now only 'debug' and higher levels will do tracing lower level + test(); + } + + { + open OUT, ">/tmp/foo" or die $!; + # override the default Log filehandle + local $Apache::TestTrace::LogFH = \*OUT; + # now the traces will go into a new filehandle + test(); + close OUT; + } + + # override tracing level via -trace opt + % t/TEST -trace=debug + + # override tracing level via env var + % env APACHE_TEST_TRACE_LEVEL=debug t/TEST + +=head1 DESCRIPTION + +This module exports a number of functions that make it easier +generating various diagnostics messages in your programs in a +consistent way and saves some keystrokes as it handles the new lines +and sends the messages to STDERR for you. + +This module provides the same trace methods as syslog(3)'s log +levels. Listed from low level to high level: emerg(), alert(), crit(), +error(), warning(), notice(), info(), debug(). The only different +function is warning(), since warn is already taken by Perl. + +The module provides another trace function called todo() which is +useful for todo items. It has the same level as I<debug> (the +highest). + +There are two more variants of each of these functions. If the +I<_mark> suffix is appended (e.g., I<error_mark>) the trace will start +with the filename and the line number the function was called from. If +the I<_sub> suffix is appended (e.g., I<error_info>) the trace will +start with the name of the subroutine the function was called from. + +If you have C<Term::ANSIColor> installed the diagnostic messages will +be colorized, otherwise a special for each function prefix will be +used. + +If C<Data::Dumper> is installed and you pass a reference to a variable +to any of these functions, the variable will be dumped with +C<Data::Dumper::Dumper()>. + +Functions whose level is above the level set in +C<$Apache::TestTrace::Level> become NOPs. For example if the level is +set to I<alert>, only alert() and emerg() functions will generate the +output. The default setting of this variable is I<warning>. Other +valid values are: I<emerg>, I<alert>, I<crit>, I<error>, I<warning>, +I<notice>, I<info>, I<debug>. + +Another way to affect the trace level is to set +C<$ENV{APACHE_TEST_TRACE_LEVEL}>, which takes effect if +C<$Apache::TestTrace::Level> is not set. So an explicit setting of +C<$Apache::TestTrace::Level> always takes precedence. + +By default all the output generated by these functions goes to +STDERR. You can override the default filehandler by overriding +C<$Apache::TestTrace::LogFH> with a new filehandler. + +When you override this package's global variables, think about +localizing your local settings, so it won't affect other modules using +this module in the same run. + +=head1 TODO + + o provide an option to disable the coloring altogether via some flag + or import() + +=head1 AUTHOR + +Stas Bekman with contributions from Doug MacEachern + +=cut + diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestUtil.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestUtil.pm new file mode 100644 index 0000000..3e3c9cd --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestUtil.pm @@ -0,0 +1,989 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Apache::TestUtil; + +use strict; +use warnings FATAL => 'all'; + +use File::Find (); +use File::Path (); +use Exporter (); +use Carp (); +use Config; +use File::Basename qw(dirname); +use File::Spec::Functions qw(catfile catdir file_name_is_absolute tmpdir); +use Symbol (); +use Fcntl qw(SEEK_END); + +use Apache::Test (); +use Apache::TestConfig (); + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %CLEAN); + +$VERSION = '0.02'; +@ISA = qw(Exporter); + +@EXPORT = qw(t_cmp t_debug t_append_file t_write_file t_open_file + t_mkdir t_rmtree t_is_equal t_filepath_cmp t_write_test_lib + t_server_log_error_is_expected t_server_log_warn_is_expected + t_client_log_error_is_expected t_client_log_warn_is_expected +); + +@EXPORT_OK = qw(t_write_perl_script t_write_shell_script t_chown + t_catfile_apache t_catfile t_file_watch_for + t_start_error_log_watch t_finish_error_log_watch + t_start_file_watch t_read_file_watch t_finish_file_watch); + +%CLEAN = (); + +$Apache::TestUtil::DEBUG_OUTPUT = \*STDOUT; + +# 5.005's Data::Dumper has problems to dump certain datastructures +use constant HAS_DUMPER => eval { $] >= 5.006 && require Data::Dumper; }; +use constant INDENT => 4; + +{ + my %files; + sub t_start_file_watch (;$) { + my $name = defined $_[0] ? $_[0] : 'error_log'; + $name = File::Spec->catfile(Apache::Test::vars->{t_logs}, $name) + unless (File::Spec->file_name_is_absolute($name)); + + if (open my $fh, '<', $name) { + seek $fh, 0, SEEK_END; + $files{$name} = $fh; + } + else { + delete $files{$name}; + } + + return; + } + + sub t_finish_file_watch (;$) { + my $name = defined $_[0] ? $_[0] : 'error_log'; + $name = File::Spec->catfile(Apache::Test::vars->{t_logs}, $name) + unless (File::Spec->file_name_is_absolute($name)); + + my $fh = delete $files{$name}; + unless (defined $fh) { + open $fh, '<', $name or return; + return readline $fh; + } + + return readline $fh; + } + + sub t_read_file_watch (;$) { + my $name = defined $_[0] ? $_[0] : 'error_log'; + $name = File::Spec->catfile(Apache::Test::vars->{t_logs}, $name) + unless (File::Spec->file_name_is_absolute($name)); + + my $fh = $files{$name}; + unless (defined $fh) { + open $fh, '<', $name or return; + $files{$name} = $fh; + } + + return readline $fh; + } + + sub t_file_watch_for ($$$) { + my ($name, $re, $timeout) = @_; + local $/ = "\n"; + $re = qr/$re/ unless ref $re; + $timeout *= 10; + my $buf = ''; + my @acc; + while ($timeout >= 0) { + my $line = t_read_file_watch $name; + unless (defined $line) { # EOF + select undef, undef, undef, 0.1; + $timeout--; + next; + } + $buf .= $line; + next unless $buf =~ /\n$/; # incomplete line + + # found a complete line + $line = $buf; + $buf = ''; + + push @acc, $line; + return wantarray ? @acc : $line if $line =~ $re; + } + return; + } + + sub t_start_error_log_watch { + t_start_file_watch; + } + + sub t_finish_error_log_watch { + local $/ = "\n"; + return my @lines = t_finish_file_watch; + } +} + +# because of the prototype and recursive call to itself a forward +# declaration is needed +sub t_is_equal ($$); + +# compare any two datastructures (must pass references for non-scalars) +# undef()'s are valid args +sub t_is_equal ($$) { + my ($a, $b) = @_; + return 0 unless @_ == 2; + + # this was added in Apache::Test::VERSION 1.12 - remove deprecated + # logic sometime around 1.15 or mid September, 2004. + if (UNIVERSAL::isa($a, 'Regexp')) { + my @warning = ("WARNING!!! t_is_equal() argument order has changed.", + "use of a regular expression as the first argument", + "is deprecated. support will be removed soon."); + t_debug(@warning); + ($a, $b) = ($b, $a); + } + + if (defined $a && defined $b) { + my $ref_a = ref $a; + my $ref_b = ref $b; + if (!$ref_a && !$ref_b) { + return $a eq $b; + } + elsif ($ref_a eq 'ARRAY' && $ref_b eq 'ARRAY') { + return 0 unless @$a == @$b; + for my $i (0..$#$a) { + t_is_equal($a->[$i], $b->[$i]) || return 0; + } + } + elsif ($ref_a eq 'HASH' && $ref_b eq 'HASH') { + return 0 unless (keys %$a) == (keys %$b); + for my $key (sort keys %$a) { + return 0 unless exists $b->{$key}; + t_is_equal($a->{$key}, $b->{$key}) || return 0; + } + } + elsif ($ref_b eq 'Regexp') { + return $a =~ $b; + } + else { + # try to compare the references + return $a eq $b; + } + } + else { + # undef == undef! a valid test + return (defined $a || defined $b) ? 0 : 1; + } + return 1; +} + + + +sub t_cmp ($$;$) { + Carp::carp(join(":", (caller)[1..2]) . + ' usage: $res = t_cmp($received, $expected, [$comment])') + if @_ < 2 || @_ > 3; + + my ($received, $expected) = @_; + + # this was added in Apache::Test::VERSION 1.12 - remove deprecated + # logic sometime around 1.15 or mid September, 2004. + if (UNIVERSAL::isa($_[0], 'Regexp')) { + my @warning = ("WARNING!!! t_cmp() argument order has changed.", + "use of a regular expression as the first argument", + "is deprecated. support will be removed soon."); + t_debug(@warning); + ($received, $expected) = ($expected, $received); + } + + t_debug("testing : " . pop) if @_ == 3; + t_debug("expected: " . struct_as_string(0, $expected)); + t_debug("received: " . struct_as_string(0, $received)); + return t_is_equal($received, $expected); +} + +# Essentially t_cmp, but on Win32, first converts pathnames +# to their DOS long name. +sub t_filepath_cmp ($$;$) { + my @a = (shift, shift); + if (Apache::TestConfig::WIN32) { + $a[0] = Win32::GetLongPathName($a[0]) if defined $a[0] && -e $a[0]; + $a[1] = Win32::GetLongPathName($a[1]) if defined $a[1] && -e $a[1]; + } + return @_ == 1 ? t_cmp($a[0], $a[1], $_[0]) : t_cmp($a[0], $a[1]); +} + + +*expand = HAS_DUMPER ? + sub { map { ref $_ ? Data::Dumper::Dumper($_) : $_ } @_ } : + sub { @_ }; + +sub t_debug { + my $out = $Apache::TestUtil::DEBUG_OUTPUT; + print $out map {"# $_\n"} map {split /\n/} grep {defined} expand(@_); +} + +sub t_open_file { + my $file = shift; + + die "must pass a filename" unless defined $file; + + # create the parent dir if it doesn't exist yet + makepath(dirname $file); + + my $fh = Symbol::gensym(); + open $fh, ">$file" or die "can't open $file: $!"; + t_debug("writing file: $file"); + $CLEAN{files}{$file}++; + + return $fh; +} + +sub _temp_package_dir { + return catdir(tmpdir(), 'apache_test'); +} + +sub t_write_test_lib { + my $file = shift; + + die "must pass a filename" unless defined $file; + + t_write_file(catdir(_temp_package_dir(), $file), @_); +} + +sub t_write_file { + my $file = shift; + + die "must pass a filename" unless defined $file; + + # create the parent dir if it doesn't exist yet + makepath(dirname $file); + + my $fh = Symbol::gensym(); + open $fh, ">$file" or die "can't open $file: $!"; + t_debug("writing file: $file"); + print $fh join '', @_ if @_; + close $fh; + $CLEAN{files}{$file}++; +} + +sub t_append_file { + my $file = shift; + + die "must pass a filename" unless defined $file; + + # create the parent dir if it doesn't exist yet + makepath(dirname $file); + + # add to the cleanup list only if we created it now + $CLEAN{files}{$file}++ unless -e $file; + + my $fh = Symbol::gensym(); + open $fh, ">>$file" or die "can't open $file: $!"; + print $fh join '', @_ if @_; + close $fh; +} + +sub t_write_shell_script { + my $file = shift; + + my $code = join '', @_; + my($ext, $shebang); + + if (Apache::TestConfig::WIN32()) { + $code =~ s/echo$/echo./mg; #required to echo newline + $ext = 'bat'; + $shebang = "\@echo off\nREM this is a bat"; + } + else { + $ext = 'sh'; + $shebang = '#!/bin/sh'; + } + + $file .= ".$ext"; + t_write_file($file, "$shebang\n", $code); + $ext; +} + +sub t_write_perl_script { + my $file = shift; + + my $shebang = "#!$Config{perlpath}\n"; + my $warning = Apache::TestConfig->thaw->genwarning($file); + t_write_file($file, $shebang, $warning, @_); + chmod 0755, $file; +} + + +sub t_mkdir { + my $dir = shift; + makepath($dir); +} + +# returns a list of dirs successfully created +sub makepath { + my($path) = @_; + + return if !defined($path) || -e $path; + my $full_path = $path; + + # remember which dirs were created and should be cleaned up + while (1) { + $CLEAN{dirs}{$path} = 1; + $path = dirname $path; + last if -e $path; + } + + return File::Path::mkpath($full_path, 0, 0755); +} + +sub t_rmtree { + die "must pass a dirname" unless defined $_[0]; + File::Path::rmtree((@_ > 1 ? \@_ : $_[0]), 0, 1); +} + +#chown a file or directory to the test User/Group +#noop if chown is unsupported + +sub t_chown { + my $file = shift; + my $config = Apache::Test::config(); + my($uid, $gid); + + eval { + #XXX cache this lookup + ($uid, $gid) = (getpwnam($config->{vars}->{user}))[2,3]; + }; + + if ($@) { + if ($@ =~ /^The getpwnam function is unimplemented/) { + #ok if unsupported, e.g. win32 + return 1; + } + else { + die $@; + } + } + + CORE::chown($uid, $gid, $file) || die "chown $file: $!"; +} + +# $string = struct_as_string($indent_level, $var); +# +# return any nested datastructure via Data::Dumper or ala Data::Dumper +# as a string. undef() is a valid arg. +# +# $indent_level should be 0 (used for nice indentation during +# recursive datastructure traversal) +sub struct_as_string{ + return "???" unless @_ == 2; + my $level = shift; + + return "undef" unless defined $_[0]; + my $pad = ' ' x (($level + 1) * INDENT); + my $spad = ' ' x ($level * INDENT); + + if (HAS_DUMPER) { + local $Data::Dumper::Terse = 1; + $Data::Dumper::Terse = $Data::Dumper::Terse; # warn + my $data = Data::Dumper::Dumper(@_); + $data =~ s/\n$//; # \n is handled by the caller + return $data; + } + else { + if (ref($_[0]) eq 'ARRAY') { + my @data = (); + for my $i (0..$#{ $_[0] }) { + push @data, + struct_as_string($level+1, $_[0]->[$i]); + } + return join "\n", "[", map({"$pad$_,"} @data), "$spad\]"; + } elsif ( ref($_[0])eq 'HASH') { + my @data = (); + for my $key (keys %{ $_[0] }) { + push @data, + "$key => " . + struct_as_string($level+1, $_[0]->{$key}); + } + return join "\n", "{", map({"$pad$_,"} @data), "$spad\}"; + } else { + return $_[0]; + } + } +} + +my $banner_format = + "\n*** The following %s expected and harmless ***\n"; + +sub is_expected_banner { + my $type = shift; + my $count = @_ ? shift : 1; + sprintf $banner_format, $count == 1 + ? "$type entry is" + : "$count $type entries are"; +} + +sub t_server_log_is_expected { + print STDERR is_expected_banner(@_); +} + +sub t_client_log_is_expected { + my $vars = Apache::Test::config()->{vars}; + my $log_file = catfile $vars->{serverroot}, "logs", "error_log"; + + my $fh = Symbol::gensym(); + open $fh, ">>$log_file" or die "Can't open $log_file: $!"; + my $oldfh = select($fh); $| = 1; select($oldfh); + print $fh is_expected_banner(@_); + close $fh; +} + +sub t_server_log_error_is_expected { t_server_log_is_expected("error", @_);} +sub t_server_log_warn_is_expected { t_server_log_is_expected("warn", @_); } +sub t_client_log_error_is_expected { t_client_log_is_expected("error", @_);} +sub t_client_log_warn_is_expected { t_client_log_is_expected("warn", @_); } + +END { + # remove files that were created via this package + for (grep {-e $_ && -f _ } keys %{ $CLEAN{files} } ) { + t_debug("removing file: $_"); + unlink $_; + } + + # remove dirs that were created via this package + for (grep {-e $_ && -d _ } keys %{ $CLEAN{dirs} } ) { + t_debug("removing dir tree: $_"); + t_rmtree($_); + } +} + +# essentially File::Spec->catfile, but on Win32 +# returns the long path name, if the file is absolute +sub t_catfile { + my $f = catfile(@_); + return $f unless file_name_is_absolute($f); + return Apache::TestConfig::WIN32 && -e $f ? + Win32::GetLongPathName($f) : $f; +} + +# Apache uses a Unix-style specification for files, with +# forward slashes for directory separators. This is +# essentially File::Spec::Unix->catfile, but on Win32 +# returns the long path name, if the file is absolute +sub t_catfile_apache { + my $f = File::Spec::Unix->catfile(@_); + return $f unless file_name_is_absolute($f); + return Apache::TestConfig::WIN32 && -e $f ? + Win32::GetLongPathName($f) : $f; +} + +1; +__END__ + +=encoding utf8 + +=head1 NAME + +Apache::TestUtil - Utility functions for writing tests + +=head1 SYNOPSIS + + use Apache::Test; + use Apache::TestUtil; + + ok t_cmp("foo", "foo", "sanity check"); + t_write_file("filename", @content); + my $fh = t_open_file($filename); + t_mkdir("/foo/bar"); + t_rmtree("/foo/bar"); + t_is_equal($a, $b); + +=head1 DESCRIPTION + +C<Apache::TestUtil> automatically exports a number of functions useful +in writing tests. + +All the files and directories created using the functions from this +package will be automatically destroyed at the end of the program +execution (via END block). You should not use these functions other +than from within tests which should cleanup all the created +directories and files at the end of the test. + +=head1 FUNCTIONS + +=over + +=item t_cmp() + + t_cmp($received, $expected, $comment); + +t_cmp() prints the values of I<$comment>, I<$expected> and +I<$received>. e.g.: + + t_cmp(1, 1, "1 == 1?"); + +prints: + + # testing : 1 == 1? + # expected: 1 + # received: 1 + +then it returns the result of comparison of the I<$expected> and the +I<$received> variables. Usually, the return value of this function is +fed directly to the ok() function, like this: + + ok t_cmp(1, 1, "1 == 1?"); + +the third argument (I<$comment>) is optional, mostly useful for +telling what the comparison is trying to do. + +It is valid to use C<undef> as an expected value. Therefore: + + my $foo; + t_cmp(undef, $foo, "undef == undef?"); + +will return a I<true> value. + +You can compare any two data-structures with t_cmp(). Just make sure +that if you pass non-scalars, you have to pass their references. The +datastructures can be deeply nested. For example you can compare: + + t_cmp({1 => [2..3,{5..8}], 4 => [5..6]}, + {1 => [2..3,{5..8}], 4 => [5..6]}, + "hash of array of hashes"); + +You can also compare the second argument against the first as a +regex. Use the C<qr//> function in the second argument. For example: + + t_cmp("abcd", qr/^abc/, "regex compare"); + +will do: + + "abcd" =~ /^abc/; + +This function is exported by default. + +=item t_filepath_cmp() + +This function is used to compare two filepaths via t_cmp(). +For non-Win32, it simply uses t_cmp() for the comparison, +but for Win32, Win32::GetLongPathName() is invoked to convert +the first two arguments to their DOS long pathname. This is useful +when there is a possibility the two paths being compared +are not both represented by their long or short pathname. + +This function is exported by default. + +=item t_debug() + + t_debug("testing feature foo"); + t_debug("test", [1..3], 5, {a=>[1..5]}); + +t_debug() prints out any datastructure while prepending C<#> at the +beginning of each line, to make the debug printouts comply with +C<Test::Harness>'s requirements. This function should be always used +for debug prints, since if in the future the debug printing will +change (e.g. redirected into a file) your tests won't need to be +changed. + +the special global variable $Apache::TestUtil::DEBUG_OUTPUT can +be used to redirect the output from t_debug() and related calls +such as t_write_file(). for example, from a server-side test +you would probably need to redirect it to STDERR: + + sub handler { + plan $r, tests => 1; + + local $Apache::TestUtil::DEBUG_OUTPUT = \*STDERR; + + t_write_file('/tmp/foo', 'bar'); + ... + } + +left to its own devices, t_debug() will collide with the standard +HTTP protocol during server-side tests, resulting in a situation +both confusing difficult to debug. but STDOUT is left as the +default, since you probably don't want debug output under normal +circumstances unless running under verbose mode. + +This function is exported by default. + +=item t_write_test_lib() + + t_write_test_lib($filename, @lines) + +t_write_test_lib() creates a new file at I<$filename> or overwrites +the existing file with the content passed in I<@lines>. The file +is created in a temporary directory which is added to @INC at +test configuration time. It is intended to be used for creating +temporary packages for testing which can be modified at run time, +see the Apache::Reload unit tests for an example. + +=item t_write_file() + + t_write_file($filename, @lines); + +t_write_file() creates a new file at I<$filename> or overwrites the +existing file with the content passed in I<@lines>. If only the +I<$filename> is passed, an empty file will be created. + +If parent directories of C<$filename> don't exist they will be +automagically created. + +The generated file will be automatically deleted at the end of the +program's execution. + +This function is exported by default. + +=item t_append_file() + + t_append_file($filename, @lines); + +t_append_file() is similar to t_write_file(), but it doesn't clobber +existing files and appends C<@lines> to the end of the file. If the +file doesn't exist it will create it. + +If parent directories of C<$filename> don't exist they will be +automagically created. + +The generated file will be registered to be automatically deleted at +the end of the program's execution, only if the file was created by +t_append_file(). + +This function is exported by default. + +=item t_write_shell_script() + + Apache::TestUtil::t_write_shell_script($filename, @lines); + +Similar to t_write_file() but creates a portable shell/batch +script. The created filename is constructed from C<$filename> and an +appropriate extension automatically selected according to the platform +the code is running under. + +It returns the extension of the created file. + +=item t_write_perl_script() + + Apache::TestUtil::t_write_perl_script($filename, @lines); + +Similar to t_write_file() but creates a executable Perl script with +correctly set shebang line. + +=item t_open_file() + + my $fh = t_open_file($filename); + +t_open_file() opens a file I<$filename> for writing and returns the +file handle to the opened file. + +If parent directories of C<$filename> don't exist they will be +automagically created. + +The generated file will be automatically deleted at the end of the +program's execution. + +This function is exported by default. + +=item t_mkdir() + + t_mkdir($dirname); + +t_mkdir() creates a directory I<$dirname>. The operation will fail if +the parent directory doesn't exist. + +If parent directories of C<$dirname> don't exist they will be +automagically created. + +The generated directory will be automatically deleted at the end of +the program's execution. + +This function is exported by default. + +=item t_rmtree() + + t_rmtree(@dirs); + +t_rmtree() deletes the whole directories trees passed in I<@dirs>. + +This function is exported by default. + +=item t_chown() + + Apache::TestUtil::t_chown($file); + +Change ownership of $file to the test's I<User>/I<Group>. This +function is noop on platforms where chown(2) is unsupported +(e.g. Win32). + +=item t_is_equal() + + t_is_equal($a, $b); + +t_is_equal() compares any two datastructures and returns 1 if they are +exactly the same, otherwise 0. The datastructures can be nested +hashes, arrays, scalars, undefs or a combination of any of these. See +t_cmp() for an example. + +If C<$b> is a regex reference, the regex comparison C<$a =~ $b> is +performed. For example: + + t_is_equal($server_version, qr{^Apache}); + +If comparing non-scalars make sure to pass the references to the +datastructures. + +This function is exported by default. + +=item t_server_log_error_is_expected() + +If the handler's execution results in an error or a warning logged to +the I<error_log> file which is expected, it's a good idea to have a +disclaimer printed before the error itself, so one can tell real +problems with tests from expected errors. For example when testing how +the package behaves under error conditions the I<error_log> file might +be loaded with errors, most of which are expected. + +For example if a handler is about to generate a run-time error, this +function can be used as: + + use Apache::TestUtil; + ... + sub handler { + my $r = shift; + ... + t_server_log_error_is_expected(); + die "failed because ..."; + } + +After running this handler the I<error_log> file will include: + + *** The following error entry is expected and harmless *** + [Tue Apr 01 14:00:21 2003] [error] failed because ... + +When more than one entry is expected, an optional numerical argument, +indicating how many entries to expect, can be passed. For example: + + t_server_log_error_is_expected(2); + +will generate: + + *** The following 2 error entries are expected and harmless *** + +If the error is generated at compile time, the logging must be done in +the BEGIN block at the very beginning of the file: + + BEGIN { + use Apache::TestUtil; + t_server_log_error_is_expected(); + } + use DOES_NOT_exist; + +After attempting to run this handler the I<error_log> file will +include: + + *** The following error entry is expected and harmless *** + [Tue Apr 01 14:04:49 2003] [error] Can't locate "DOES_NOT_exist.pm" + in @INC (@INC contains: ... + +Also see C<t_server_log_warn_is_expected()> which is similar but used +for warnings. + +This function is exported by default. + +=item t_server_log_warn_is_expected() + +C<t_server_log_warn_is_expected()> generates a disclaimer for expected +warnings. + +See the explanation for C<t_server_log_error_is_expected()> for more +details. + +This function is exported by default. + +=item t_client_log_error_is_expected() + +C<t_client_log_error_is_expected()> generates a disclaimer for +expected errors. But in contrast to +C<t_server_log_error_is_expected()> called by the client side of the +script. + +See the explanation for C<t_server_log_error_is_expected()> for more +details. + +For example the following client script fails to find the handler: + + use Apache::Test; + use Apache::TestUtil; + use Apache::TestRequest qw(GET); + + plan tests => 1; + + t_client_log_error_is_expected(); + my $url = "/error_document/cannot_be_found"; + my $res = GET($url); + ok t_cmp(404, $res->code, "test 404"); + +After running this test the I<error_log> file will include an entry +similar to the following snippet: + + *** The following error entry is expected and harmless *** + [Tue Apr 01 14:02:55 2003] [error] [client 127.0.0.1] + File does not exist: /tmp/test/t/htdocs/error + +When more than one entry is expected, an optional numerical argument, +indicating how many entries to expect, can be passed. For example: + + t_client_log_error_is_expected(2); + +will generate: + + *** The following 2 error entries are expected and harmless *** + +This function is exported by default. + +=item t_client_log_warn_is_expected() + +C<t_client_log_warn_is_expected()> generates a disclaimer for expected +warnings on the client side. + +See the explanation for C<t_client_log_error_is_expected()> for more +details. + +This function is exported by default. + +=item t_catfile('a', 'b', 'c') + +This function is essentially C<File::Spec-E<gt>catfile>, but +on Win32 will use C<Win32::GetLongpathName()> to convert the +result to a long path name (if the result is an absolute file). +The function is not exported by default. + +=item t_catfile_apache('a', 'b', 'c') + +This function is essentially C<File::Spec::Unix-E<gt>catfile>, but +on Win32 will use C<Win32::GetLongpathName()> to convert the +result to a long path name (if the result is an absolute file). +It is useful when comparing something to that returned by Apache, +which uses a Unix-style specification with forward slashes for +directory separators. The function is not exported by default. + +=item t_start_error_log_watch(), t_finish_error_log_watch() + +This pair of functions provides an easy interface for checking +the presence or absense of any particular message or messages +in the httpd error_log that were generated by the httpd daemon +as part of a test suite. It is likely, that you should proceed +this with a call to one of the t_*_is_expected() functions. + + t_start_error_log_watch(); + do_it; + ok grep {...} t_finish_error_log_watch(); + +Another usage case could be a handler that emits some debugging messages +to the error_log. Now, if this handler is called in a series of other +test cases it can be hard to find the relevant messages manually. In such +cases the following sequence in the test file may help: + + t_start_error_log_watch(); + GET '/this/or/that'; + t_debug t_finish_error_log_watch(); + +=item t_start_file_watch() + + Apache::TestUtil::t_start_file_watch('access_log'); + +This function is similar to C<t_start_error_log_watch()> but allows for +other files than C<error_log> to be watched. It opens the given file +and positions the file pointer at its end. Subsequent calls to +C<t_read_file_watch()> or C<t_finish_file_watch()> will read lines that +have been appended after this call. + +A file name can be passed as parameter. If omitted +or undefined the C<error_log> is opened. Relative file name are +evaluated relative to the directory containing C<error_log>. + +If the specified file does not exist (yet) no error is returned. It is +assumed that it will appear soon. In this case C<t_{read,finish}_file_watch()> +will open the file silently and read from the beginning. + +=item t_read_file_watch(), t_finish_file_watch() + + local $/ = "\n"; + $line1=Apache::TestUtil::t_read_file_watch('access_log'); + $line2=Apache::TestUtil::t_read_file_watch('access_log'); + + @lines=Apache::TestUtil::t_finish_file_watch('access_log'); + +This pair of functions reads the file opened by C<t_start_error_log_watch()>. + +As does the core C<readline> function, they return one line if called in +scalar context, otherwise all lines until end of file. + +Before calling C<readline> these functions do not set C<$/> as does +C<t_finish_error_log_watch>. So, if the file has for example a fixed +record length use this: + + { + local $/=\$record_length; + @lines=t_finish_file_watch($name); + } + +=item t_file_watch_for() + + @lines=Apache::TestUtil::t_file_watch_for('access_log', + qr/condition/, + $timeout); + +This function reads the file from the current position and looks for the +first line that matches C<qr/condition/>. If no such line could be found +until end of file the function pauses and retries until either such a line +is found or the timeout (in seconds) is reached. + +In scalar or void context only the matching line is returned. In list +context all read lines are returned with the matching one in last position. + +The function uses C<\n> and end-of-line marker and waits for complete lines. + +The timeout although it can be specified with sub-second precision is not very +accurate. It is simply multiplied by 10. The result is used as a maximum loop +count. For the intented purpose this should be good enough. + +Use this function to check for logfile entries when you cannot be sure that +they are already written when the test program reaches the point, for example +to check for messages that are written in a PerlCleanupHandler or a +PerlLogHandler. + + ok t_file_watch_for 'access_log', qr/expected log entry/, 2; + +This call reads the C<access_log> and waits for maximum 2 seconds for the +expected entry to appear. + +=back + +=head1 AUTHOR + +Stas Bekman <stas@stason.org>, +Torsten Förtsch <torsten.foertsch@gmx.net> + +=head1 SEE ALSO + +perl(1) + +=cut + diff --git a/debian/perl-framework/Apache-Test/lib/Bundle/ApacheTest.pm b/debian/perl-framework/Apache-Test/lib/Bundle/ApacheTest.pm new file mode 100644 index 0000000..4c5b78c --- /dev/null +++ b/debian/perl-framework/Apache-Test/lib/Bundle/ApacheTest.pm @@ -0,0 +1,64 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Bundle::ApacheTest; + +$VERSION = '0.02'; + +1; + +__END__ + +=head1 NAME + +Bundle::ApacheTest - A bundle to install all Apache-Test related modules + +=head1 SYNOPSIS + + perl -MCPAN -e 'install Bundle::ApacheTest' + +=head1 CONTENTS + +Crypt::SSLeay - For https support + +Devel::CoreStack - For getting core stack info + +Devel::Symdump - For, uh, dumping symbols + +Digest::MD5 - Needed for Digest authentication + +URI - There are URIs everywhere + +Net::Cmd - For libnet + +MIME::Base64 - Used in authentication headers + +HTML::Tagset - Needed by HTML::Parser + +HTML::Parser - Need by HTML::HeadParser + +HTML::HeadParser - To get the correct $res->base + +LWP - For libwww-perl + +LWP::Protocol::https - LWP plug-in for the https protocol + +IPC::Run3 - Used in Apache::TestSmoke + +=head1 DESCRIPTION + +This bundle lists all the CPAN modules used by Apache-Test. + +=cut diff --git a/debian/perl-framework/Apache-Test/t/TEST.PL b/debian/perl-framework/Apache-Test/t/TEST.PL new file mode 100644 index 0000000..bbdc93e --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/TEST.PL @@ -0,0 +1,42 @@ +use strict; + +use lib qw(lib ../lib); + +use warnings FATAL => 'all'; + +use Apache::TestRun (); + +package MyTest; + +use vars qw(@ISA); +@ISA = qw(Apache::TestRun); + +#subclass new_test_config to add some config vars which will +#be replaced in generated config, see t/conf/extra.conf.in + +#'make test' runs -clean by default, so to actually see the replacements: +#perl t/TEST apxs ... +#cat t/conf/extra.conf +#perl t/TEST -clean + +sub new_test_config { + my $self = shift; + + $self->{conf_opts}->{authname} = 'gold club'; + $self->{conf_opts}->{allowed_users} = 'dougm sterling'; + + return $self->SUPER::new_test_config; +} + +sub bug_report { + my $self = shift; + + print <<EOI; ++-----------------------------------------------------+ +| To report problems please refer to the SUPPORT file | ++-----------------------------------------------------+ +EOI +} + +MyTest->new->run(@ARGV); + diff --git a/debian/perl-framework/Apache-Test/t/alltest/01bang.t b/debian/perl-framework/Apache-Test/t/alltest/01bang.t new file mode 100644 index 0000000..3782ade --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/alltest/01bang.t @@ -0,0 +1,5 @@ +use Apache::Test; + +plan tests => 1; + +ok (0, 'this test should never run'); diff --git a/debian/perl-framework/Apache-Test/t/alltest/all.t b/debian/perl-framework/Apache-Test/t/alltest/all.t new file mode 100644 index 0000000..ef0033c --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/alltest/all.t @@ -0,0 +1,8 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +plan tests => 1, skip_reason('testing all.t'); + +ok 1; diff --git a/debian/perl-framework/Apache-Test/t/alltest2/01bang.t b/debian/perl-framework/Apache-Test/t/alltest2/01bang.t new file mode 100644 index 0000000..3782ade --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/alltest2/01bang.t @@ -0,0 +1,5 @@ +use Apache::Test; + +plan tests => 1; + +ok (0, 'this test should never run'); diff --git a/debian/perl-framework/Apache-Test/t/alltest2/all.t b/debian/perl-framework/Apache-Test/t/alltest2/all.t new file mode 100644 index 0000000..0393608 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/alltest2/all.t @@ -0,0 +1,8 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +plan tests => 1, skip_reason('testing more than one all.t'); + +ok 1; diff --git a/debian/perl-framework/Apache-Test/t/bad_coding.t b/debian/perl-framework/Apache-Test/t/bad_coding.t new file mode 100644 index 0000000..4e445a1 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/bad_coding.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +# This test tests how good Apache-Test deals with bad coding practices +# of its users + +plan tests => 1; + +{ + # passing $_ to a non-core function inside a foreach loop or + # similar, may affect $_ on return -- badly breaking things and + # making it hard to figure out where the problem is coming from. + # + # have_* macros localize $_ for these bad programming cases + # let's test that: + my @list = ('mod_dir'); + my %modules = map { $_, have_module($_) } @list; + ok 1; +} diff --git a/debian/perl-framework/Apache-Test/t/cgi-bin/cookies.pl.PL b/debian/perl-framework/Apache-Test/t/cgi-bin/cookies.pl.PL new file mode 100644 index 0000000..b409448 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/cgi-bin/cookies.pl.PL @@ -0,0 +1,16 @@ +#!perl -wT + +use strict; + +use CGI; +use CGI::Cookie; + +my %cookies = CGI::Cookie->fetch; +my $name = 'ApacheTest'; +my $c = ! exists $cookies{$name} + ? CGI::Cookie->new(-name=>$name, -value=>time) + : ''; + +print "Set-Cookie: $c\n" if $c; +print "Content-Type: text/plain\n\n"; +print ($c ? 'new' : 'exists'), "\n"; diff --git a/debian/perl-framework/Apache-Test/t/cgi-bin/next_available_port.pl.PL b/debian/perl-framework/Apache-Test/t/cgi-bin/next_available_port.pl.PL new file mode 100644 index 0000000..855b45b --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/cgi-bin/next_available_port.pl.PL @@ -0,0 +1,4 @@ +use strict; + +print "Content-Type: text/plain\n\n"; +print $ENV{NextAvailablePort} || ''; diff --git a/debian/perl-framework/Apache-Test/t/conf/extra.conf.in b/debian/perl-framework/Apache-Test/t/conf/extra.conf.in new file mode 100644 index 0000000..5d3a611 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/conf/extra.conf.in @@ -0,0 +1,46 @@ +#this file will be Include-d by @ServerRoot@/httpd.conf + +#the subclass inside t/TEST added the authname and allowed_users variables +<IfModule mod_alias.c> + Redirect /redirect http://@ServerName@/redirected/ +</IfModule> + +<IfModule mod_perl.c> + + <Location /TestMore__testpm> + SetHandler perl-script + <IfDefine APACHE2> + PerlResponseHandler TestMore::testpm + </IfDefine> + <IfDefine APACHE1> + PerlHandler TestMore::testpm + </IfDefine> + </Location> + + <Location /TestMore__testmorepm> + SetHandler perl-script + <IfDefine APACHE2> + PerlResponseHandler TestMore::testmorepm + </IfDefine> + <IfDefine APACHE1> + PerlHandler TestMore::testmorepm + </IfDefine> + </Location> +</IfModule> + + +<IfModule @CGI_MODULE@> + ScriptAlias /cgi-bin/ "@ServerRoot@/cgi-bin/" + + <Directory "@ServerRoot@/cgi-bin/"> + AllowOverride None + Options +ExecCGI + </Directory> + + # t/next_available_port.t + <IfModule mod_env.c> + SetEnv NextAvailablePort @NextAvailablePort@ + </IfModule> + +</IfModule> + diff --git a/debian/perl-framework/Apache-Test/t/conf/modperl_extra.pl.in b/debian/perl-framework/Apache-Test/t/conf/modperl_extra.pl.in new file mode 100644 index 0000000..e856cb5 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/conf/modperl_extra.pl.in @@ -0,0 +1,13 @@ +use strict; +use warnings FATAL => qw(all); + +use File::Spec (); + +use lib (); # empty so we can calculate the lib to use + +my @libs = (File::Spec->catfile('@ServerRoot@', 'response'), + File::Spec->catfile('@ServerRoot@', qw(.. lib))); + +lib->import(@libs); + +1; diff --git a/debian/perl-framework/Apache-Test/t/cookies.t b/debian/perl-framework/Apache-Test/t/cookies.t new file mode 100644 index 0000000..63f2a4d --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/cookies.t @@ -0,0 +1,18 @@ +# this test tests how a cookie jar can be passed (needs lwp) + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, need [qw(CGI CGI::Cookie)], + need_cgi, need_lwp, need need_module('mod_alias.c'); + +Apache::TestRequest::user_agent( cookie_jar => {} ); + +my $url = '/cgi-bin/cookies.pl'; + +ok t_cmp GET_BODY($url), 'new', "new cookie"; +ok t_cmp GET_BODY($url), 'exists', "existing cookie"; diff --git a/debian/perl-framework/Apache-Test/t/import.t b/debian/perl-framework/Apache-Test/t/import.t new file mode 100644 index 0000000..1dbd747 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/import.t @@ -0,0 +1,145 @@ +#!perl + +use strict; +use warnings FATAL=>'all'; +use Test (); + +Test::plan tests=>47; + +sub t { + my $p=$_[0]; + no strict 'refs'; + Test::ok defined &{$p."::ok"} && \&{$p."::ok"}==\&Test::ok, + 1, "$p - ok"; + Test::ok defined &{$p."::need"} && \&{$p."::need"}==\&Apache::Test::need, + 1, "$p - need"; + Test::ok defined &{$p."::plan"} && \&{$p."::plan"}==\&Apache::Test::plan, + 1, "$p - plan"; +} + +sub tm { + my $p=$_[0]; + no strict 'refs'; + Test::ok defined &{$p."::ok"} && \&{$p."::ok"}==\&Test::More::ok, + 1, "$p - ok"; + Test::ok defined &{$p."::need"} && \&{$p."::need"}==\&Apache::Test::need, + 1, "$p - need"; + Test::ok defined &{$p."::plan"} && \&{$p."::plan"}==\&Apache::Test::plan, + 1, "$p - plan"; +} + +{package X0; use Apache::Test;} +{package Y0; use Apache::Test qw/-withtestmore/;} + +t 'X0'; +tm 'Y0'; + +{package X1; use Apache::Test qw/:DEFAULT/;} +{package Y1; use Apache::Test qw/-withtestmore :DEFAULT/;} + +t 'X1'; +tm 'Y1'; + +{package X2; use Apache::Test qw/!:DEFAULT/;} +{package Y2; use Apache::Test qw/-withtestmore !:DEFAULT/;} + +Test::ok !defined &X2::ok, 1, '!defined &X2::ok'; +Test::ok !defined &X2::need, 1, '!defined &X2::need'; +Test::ok !defined &X2::plan, 1, '!defined &X2::plan'; +Test::ok !defined &Y2::ok, 1, '!defined &Y2::ok'; +Test::ok !defined &Y2::need, 1, '!defined &Y2::need'; +Test::ok !defined &Y2::plan, 1, '!defined &Y2::plan'; + +{package X3; use Apache::Test qw/plan/;} +{package Y3; use Apache::Test qw/-withtestmore plan/;} + +Test::ok !defined &X3::ok, 1, '!defined &X3::ok'; +Test::ok !defined &X3::need, 1, '!defined &X3::need'; +Test::ok defined &X3::plan && \&X3::plan==\&Apache::Test::plan, 1, "X3 - plan"; +Test::ok !defined &Y3::ok, 1, '!defined &Y3::ok'; +Test::ok !defined &Y3::need, 1, '!defined &Y3::need'; +Test::ok defined &Y3::plan && \&Y3::plan==\&Apache::Test::plan, 1, "Y3 - plan"; + +{package X4; use Apache::Test qw/need/;} +{package Y4; use Apache::Test qw/-withtestmore need/;} + +Test::ok !defined &X4::ok, 1, '!defined &X4::ok'; +Test::ok defined &X4::need && \&X4::need==\&Apache::Test::need, 1, "X4 - need"; +Test::ok !defined &X4::plan, 1, '!defined &X4::plan'; +Test::ok !defined &Y4::ok, 1, '!defined &Y4::ok'; +Test::ok defined &Y4::need && \&Y4::need==\&Apache::Test::need, 1, "Y4 - need"; +Test::ok !defined &Y4::plan, 1, '!defined &Y4::plan'; + +{package X5; use Apache::Test qw/ok/;} +{package Y5; use Apache::Test qw/-withtestmore ok/;} + +Test::ok defined &X5::ok && \&X5::ok==\&Test::ok, 1, "X5 - ok"; +Test::ok !defined &X5::need, 1, '!defined &X5::need'; +Test::ok !defined &X5::plan, 1, '!defined &X5::plan'; +Test::ok defined &Y5::ok && \&Y5::ok==\&Test::More::ok, 1, "Y5 - ok"; +Test::ok !defined &Y5::need, 1, '!defined &Y5::need'; +Test::ok !defined &Y5::plan, 1, '!defined &Y5::plan'; + +{package X6; use Apache::Test qw/ok need/;} +{package Y6; use Apache::Test qw/-withtestmore ok need/;} + +Test::ok defined &X6::ok && \&X6::ok==\&Test::ok, 1, "X6 - ok"; +Test::ok defined &X6::need && \&X6::need==\&Apache::Test::need, 1, "X6 - need"; +Test::ok !defined &X6::plan, 1, '!defined &X6::plan'; +Test::ok defined &Y6::ok && \&Y6::ok==\&Test::More::ok, 1, "Y6 - ok"; +Test::ok defined &Y6::need && \&Y6::need==\&Apache::Test::need, 1, "Y6 - need"; +Test::ok !defined &Y6::plan, 1, '!defined &Y6::plan'; + +my $warning; +{ + local $SIG{__WARN__}=sub {$warning=join '', @_}; + eval <<'EVAL'; +package Z0; +use Apache::Test qw/:withtestmore/; +EVAL +} +Test::ok $warning, qr/^Ignoring import spec :withtestmore at/, + "Ignore import warning"; + +undef $warning; +{ + local $SIG{__WARN__}=sub {$warning=join '', @_}; + eval <<'EVAL'; +package X0; +use Apache::Test qw/-withtestmore/; +EVAL +} +Test::ok $warning, qr/^Ignoring -withtestmore due to a previous call /, + "Ignore -withtestmore warning"; + +use Config (); +my $pio=$Config::Config{useperlio} ? '' : 'need perlio'; +my $output; +Test::skip $pio, sub { + my @res; + { + local $Test::ntest=-19; + local $Test::planned=-42; + package Y2; # uses Apache::Test qw/-withtestmore !:DEFAULT/ + # so nothing is exported + + local *STDOUT; + open STDOUT, '>', \$output; + { + # suppress an 'uninitialized' warning in older perl versions + local $SIG{__WARN__}=sub { + warn $_[0] + unless $_[0]=~m!uninitialized\svalue\sin\sopen\b.+ + Test/Builder\.pm!x; + }; + Apache::Test::plan tests=>17; + } + Test::More::isnt "hugo", "erwin", "hugo is not erwin"; + @res=($Test::ntest, $Test::planned); + Test::Builder->new->reset; + } + return "@res"; +}, '-19 -42', '$Test::ntest, $Test::planned did not change'; + +Test::skip $pio, $output=~/^1\.\.17$/m; +Test::skip $pio, $output=~/^ok 1 - hugo is not erwin$/m; diff --git a/debian/perl-framework/Apache-Test/t/log_watch.t b/debian/perl-framework/Apache-Test/t/log_watch.t new file mode 100644 index 0000000..7a69f3f --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/log_watch.t @@ -0,0 +1,76 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil qw/t_start_file_watch + t_read_file_watch + t_finish_file_watch + t_write_file + t_append_file + t_catfile + t_cmp/; + +plan tests => 11; + +my $fn=t_catfile(Apache::Test::vars->{t_logs}, 'watch'); +unlink $fn; + +t_start_file_watch 'watch'; + +t_write_file $fn, "1\n2\n"; + +ok t_cmp [t_read_file_watch 'watch'], ["1\n", "2\n"], + "t_read_file_watch on previously non-existing file"; + +t_append_file $fn, "3\n4\n"; + +ok t_cmp [t_read_file_watch 'watch'], ["3\n", "4\n"], + "subsequent t_read_file_watch"; + +t_append_file $fn, "5\n6\n"; + +ok t_cmp [t_finish_file_watch 'watch'], ["5\n", "6\n"], + "subsequent t_finish_file_watch"; + +ok t_cmp [t_finish_file_watch 'watch'], ["1\n","2\n","3\n","4\n","5\n","6\n"], + "t_finish_file_watch w/o start"; + +ok t_cmp [t_read_file_watch 'watch'], ["1\n","2\n","3\n","4\n","5\n","6\n"], + "t_read_file_watch w/o start"; + +ok t_cmp [t_read_file_watch 'watch'], [], + "subsequent t_read_file_watch"; + +t_append_file $fn, "7\n8\n"; +unlink $fn; + +ok t_cmp [t_read_file_watch 'watch'], ["7\n","8\n"], + "subsequent t_read_file_watch file unlinked"; + +t_write_file $fn, "1\n2\n3\n4\n5\n6\n7\n8\n"; + +ok t_cmp [t_finish_file_watch 'watch'], [], + "subsequent t_finish_file_watch - new file exists but fh is cached"; + +t_start_file_watch 'watch'; + +ok t_cmp [t_read_file_watch 'watch'], [], + "t_read_file_watch at EOF"; + +# Make sure the file is closed before deleting it on Windows. +t_finish_file_watch 'watch' if $^O eq 'MSWin32'; + +unlink $fn; +t_start_file_watch 'watch'; + +t_write_file $fn, "1\n2\n3\n4\n5\n6\n7\n8\n"; + +{ + local $/=\4; + + ok t_cmp [scalar t_read_file_watch 'watch'], ["1\n2\n"], + "t_read_file_watch fixed record length / scalar context"; + + ok t_cmp [t_finish_file_watch 'watch'], ["3\n4\n","5\n6\n","7\n8\n"], + "t_finish_file_watch fixed record length"; +} diff --git a/debian/perl-framework/Apache-Test/t/log_watch_for_broken_lines.t b/debian/perl-framework/Apache-Test/t/log_watch_for_broken_lines.t new file mode 100644 index 0000000..108e10c --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/log_watch_for_broken_lines.t @@ -0,0 +1,40 @@ +#!perl + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil qw/t_start_file_watch t_file_watch_for + t_cmp t_catfile t_append_file/; + +plan tests => 5, need_fork; + +my $fn=t_catfile(Apache::Test::vars->{t_logs}, 'watch'); +unlink $fn; + +t_start_file_watch 'watch'; + +my $pid; +select undef, undef, undef, 0.1 until defined($pid=fork); +unless ($pid) { # child + t_append_file $fn, "\nhuhu\n4 5 6 \nblabla\n"; + for(1..3) { + select undef, undef, undef, 0.3; + t_append_file $fn, "$_ "; + } + t_append_file $fn, "\nhuhu\n4 5 6 \nblabla"; + exit 0; +} + +ok t_cmp t_file_watch_for('watch', qr/^1 2 3 $/, 2), + "1 2 3 \n", 'incomplete line'; + +my @lines=t_file_watch_for('watch', qr/^\d \d \d $/, 2); +ok t_cmp @lines, 2, '2 lines'; +ok t_cmp $lines[0], "huhu\n", '1st line'; +ok t_cmp $lines[1], "4 5 6 \n", 'found it'; + +ok t_cmp t_file_watch_for('watch', qr/^\d \d \d $/, 0.3), + undef, 'timeout'; + +waitpid $pid, 0; diff --git a/debian/perl-framework/Apache-Test/t/more/01testpm.t b/debian/perl-framework/Apache-Test/t/more/01testpm.t new file mode 100644 index 0000000..0883e92 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/more/01testpm.t @@ -0,0 +1,8 @@ +# see the description in t/more/all.t + +use strict; +use warnings FATAL => qw(all); + +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/TestMore__testpm"; + diff --git a/debian/perl-framework/Apache-Test/t/more/02testmore.t b/debian/perl-framework/Apache-Test/t/more/02testmore.t new file mode 100644 index 0000000..440f39c --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/more/02testmore.t @@ -0,0 +1,8 @@ +# see the description in t/more/all.t + +use strict; +use warnings FATAL => qw(all); + +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/TestMore__testmorepm"; + diff --git a/debian/perl-framework/Apache-Test/t/more/03testpm.t b/debian/perl-framework/Apache-Test/t/more/03testpm.t new file mode 100644 index 0000000..0883e92 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/more/03testpm.t @@ -0,0 +1,8 @@ +# see the description in t/more/all.t + +use strict; +use warnings FATAL => qw(all); + +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/TestMore__testpm"; + diff --git a/debian/perl-framework/Apache-Test/t/more/04testmore.t b/debian/perl-framework/Apache-Test/t/more/04testmore.t new file mode 100644 index 0000000..440f39c --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/more/04testmore.t @@ -0,0 +1,8 @@ +# see the description in t/more/all.t + +use strict; +use warnings FATAL => qw(all); + +use Apache::TestRequest 'GET_BODY_ASSERT'; +print GET_BODY_ASSERT "/TestMore__testmorepm"; + diff --git a/debian/perl-framework/Apache-Test/t/more/all.t b/debian/perl-framework/Apache-Test/t/more/all.t new file mode 100644 index 0000000..c36a2dc --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/more/all.t @@ -0,0 +1,28 @@ +# skip all the Test::More tests if Test::More is +# not of a sufficient version; + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +plan tests => 1, need need_min_module_version(qw(Test::More 0.48_01)), + need_module('mod_perl.c'); + +ok 1; + + +# the t/more/ directory is testing a few things. +# +# first, it is testing that the special +# Apache::Test qw(-withtestmore); +# import works, which allows Apache::Test to use +# Test::More as the backend (in place of Test.pm) +# for server-side tests. +# +# secondly, it is testing that we can intermix +# scripts that use Test.pm and Test::More as the +# backend, which was a bug that needed to be worked +# around in early implementations of -withtestmore. +# hence the reason for the specific ordering of the +# tests in t/more/. diff --git a/debian/perl-framework/Apache-Test/t/next_available_port.t b/debian/perl-framework/Apache-Test/t/next_available_port.t new file mode 100644 index 0000000..1eff85d --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/next_available_port.t @@ -0,0 +1,16 @@ +# this test tests how a cookie jar can be passed (needs lwp) + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, need need_cgi, + need_module('mod_env.c'); + +my $url = '/cgi-bin/next_available_port.pl'; + +my $port = GET_BODY($url) || ''; +ok $port, qr/^\d+$/, "next available port number"; diff --git a/debian/perl-framework/Apache-Test/t/ping.t b/debian/perl-framework/Apache-Test/t/ping.t new file mode 100644 index 0000000..a84bf95 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/ping.t @@ -0,0 +1,17 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +plan tests => 3; + +my $config = Apache::Test::config(); + +ok $config; + +my $server = $config->server; + +ok $server; + +ok $server->ping; + diff --git a/debian/perl-framework/Apache-Test/t/redirect.t b/debian/perl-framework/Apache-Test/t/redirect.t new file mode 100644 index 0000000..6df2ef4 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/redirect.t @@ -0,0 +1,23 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 6, need need_module('mod_alias.c'), need_lwp; + +my $url = '/redirect'; + +# Allow request to be redirected. +ok my $res = GET $url; +ok ! $res->is_redirect; + +# Don't let request be redirected. +ok $res = GET($url, redirect_ok => 0); +ok $res->is_redirect; + +# Allow no more requests to be redirected. +Apache::TestRequest::user_agent(reset => 1, + requests_redirectable => 0); +ok $res = GET $url; +ok $res->is_redirect; diff --git a/debian/perl-framework/Apache-Test/t/request.t b/debian/perl-framework/Apache-Test/t/request.t new file mode 100644 index 0000000..63be945 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/request.t @@ -0,0 +1,28 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 9, \&need_lwp; + +my $url = '/index.html'; + +ok GET_OK $url; +ok GET_RC $url; +ok GET_STR $url; +ok GET_BODY $url; + +ok HEAD_OK $url; +ok HEAD_RC $url; +ok HEAD_STR $url; + +ok GET_OK $url, username => 'dougm', password => 'XXXX'; #e.g. for auth + +ok GET_OK $url, Referer => $0; #add headers + +#post a string +#ok POST_OK $url, content => 'post body data'; + +#or key/value pairs (see HTTP::Request::Common +#ok POST_OK $url, [university => 'arizona', team => 'wildcats'] diff --git a/debian/perl-framework/Apache-Test/t/response/TestMore/testmorepm.pm b/debian/perl-framework/Apache-Test/t/response/TestMore/testmorepm.pm new file mode 100644 index 0000000..12cb491 --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/response/TestMore/testmorepm.pm @@ -0,0 +1,21 @@ +package TestMore::testmorepm; + +use strict; +use warnings FATAL => qw(all); + +use Test::More; +use Apache::Test qw(-withtestmore); + +sub handler { + + plan shift, tests => 2; + + is (1, 1, 'called Test::More::is()'); + + like ('wow', qr/wow/, 'called Test::More::like()'); + + 0; + +} + +1; diff --git a/debian/perl-framework/Apache-Test/t/response/TestMore/testpm.pm b/debian/perl-framework/Apache-Test/t/response/TestMore/testpm.pm new file mode 100644 index 0000000..8c550ed --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/response/TestMore/testpm.pm @@ -0,0 +1,18 @@ +package TestMore::testpm; + +use strict; +use warnings FATAL => qw(all); + +use Apache::Test; +use Apache::TestUtil; + +sub handler { + + plan shift, tests => 1; + + ok t_cmp(1, 1, 'called Apache::Test::ok()'); + + 0; +} + +1; diff --git a/debian/perl-framework/Apache-Test/t/sok.t b/debian/perl-framework/Apache-Test/t/sok.t new file mode 100644 index 0000000..cb7efdb --- /dev/null +++ b/debian/perl-framework/Apache-Test/t/sok.t @@ -0,0 +1,168 @@ +#!perl + +use strict; +use warnings FATAL=>'all'; + +use Test (); +use Config (); +unless ($Config::Config{useperlio}) { + print "1..0 # need perlio\n"; + exit 0; +} + +Test::plan tests=>8; + +my $output; +{ + package X0; + use Apache::Test; + + local ($Test::planned, $Test::ntest, %Test::todo); + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}=""; + + plan tests=>3; + + sok {1}; + sok {1}; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2$/m && + $output=~/^ok 3$/m; + +{ + package Y0; + use Apache::Test qw/-withtestmore/; + + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}=""; + + plan tests=>3; + + sok {1}; + sok {1}; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2$/m && + $output=~/^ok 3$/m; + +{ + package X0; + + local ($Test::planned, $Test::ntest, %Test::todo); + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}="1 3"; + + plan tests=>3; + + sok {1}; + sok {1}; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2 # skip skipping this subtest$/mi && + $output=~/^ok 3$/m; + +{ + package Y0; + + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}="1 3"; + + plan tests=>3; + + sok {1}; + sok {1}; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2 # skip skipping this subtest$/mi && + $output=~/^ok 3$/m; + +{ + package X0; + + local ($Test::planned, $Test::ntest, %Test::todo); + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}=""; + + plan tests=>4; + + sok {1}; + sok {ok 1; 1} 2; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2$/m && + $output=~/^ok 3$/m && + $output=~/^ok 4$/m; + +{ + package Y0; + + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}=""; + + plan tests=>4; + + sok {1}; + sok {ok 1, "erwin"} 2; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2 - erwin$/m && + $output=~/^ok 3$/m && + $output=~/^ok 4$/m; + +{ + package X0; + + local ($Test::planned, $Test::ntest, %Test::todo); + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}="1 4"; + + plan tests=>4; + + sok {1}; + sok {ok 1; 1} 2; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2 # skip skipping this subtest$/mi && + $output=~/^ok 3 # skip skipping this subtest$/mi && + $output=~/^ok 4$/m; + +{ + package Y0; + + local *STDOUT; + open STDOUT, '>', \$output; + + local $ENV{HTTPD_TEST_SUBTESTS}="1 4"; + + plan tests=>4; + + sok {1}; + sok {ok 1} 2; + sok {1}; +} +Test::ok $output=~/^ok 1$/m && + $output=~/^ok 2 # skip skipping this subtest$/mi && + $output=~/^ok 3 # skip skipping this subtest$/mi && + $output=~/^ok 4$/m; diff --git a/debian/perl-framework/LICENSE b/debian/perl-framework/LICENSE new file mode 100644 index 0000000..9fc6203 --- /dev/null +++ b/debian/perl-framework/LICENSE @@ -0,0 +1,204 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + diff --git a/debian/perl-framework/Makefile.PL b/debian/perl-framework/Makefile.PL new file mode 100644 index 0000000..ece2205 --- /dev/null +++ b/debian/perl-framework/Makefile.PL @@ -0,0 +1,58 @@ +use ExtUtils::MakeMaker; + +use 5.005; + +use lib qw(Apache-Test/lib); + +use Apache::Test5005compat; + +use Apache::TestMM qw(test clean); +use Apache::TestReport (); +use Apache::TestSmoke (); +use Apache::TestRun (); + +use File::Find qw(finddepth); + +my @scripts = (); + +finddepth(sub { + return unless /^(?!.#)(.*?\.pl)\.PL$/; + push @scripts, "$File::Find::dir/$1"; +}, '.'); + +Apache::TestMM::filter_args(); + +# Temporary workaround to allow passing +# arguments to "perl Makefile.PL" +# that should go to t/TEST but are not yet +# supported in an Apache::Test release. +# Code borrowed from Apache::TestMM::filter_args(). +my %local_args = ( + limitrequestline => 'Value for LimitRequestLine', + limitrequestlinex2 => 'Twice the value for LimitRequestLine', +); +my($argv, $args_vars) = Apache::TestConfig::filter_args(\@ARGV, \%local_args); +@ARGV = @$argv; +# Merge given vars with default values +my %local_vars = ( + limitrequestline => '128', + limitrequestlinex2 => '256', +); +map {$local_vars{$_} = $args_vars->{$_}} keys %$args_vars; + +push(@Apache::TestMM::Argv, %local_vars); + +for my $script (@scripts) { + Apache::TestMM::generate_script($script); +} + +for my $util (qw(Report Smoke Run)) { + my $class = "Apache::Test${util}"; + $class->generate_script; +} + +WriteMakefile( + NAME => 'httpd-test', + VERSION => '0.01', + clean => { FILES => "@scripts" }, +); diff --git a/debian/perl-framework/Misc.pm b/debian/perl-framework/Misc.pm new file mode 100644 index 0000000..d00cdde --- /dev/null +++ b/debian/perl-framework/Misc.pm @@ -0,0 +1,49 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +package Misc; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); +use Time::HiRes qw(usleep); + +use strict; +use warnings FATAL => 'all'; + +BEGIN { + # Just a bunch of useful subs +} + +sub cwait +{ + my $condition = shift; + my $wait = shift || 2; + my $inc = shift || 50; + my $timer = time() + $wait; + while (! eval $condition) { + usleep($inc); + last if (time() >= $timer); + } + if ( eval $condition ) { + return 1; + } else { + return 0; + } +} + +1; +__END__
\ No newline at end of file diff --git a/debian/perl-framework/NOTICE b/debian/perl-framework/NOTICE new file mode 100644 index 0000000..b823d44 --- /dev/null +++ b/debian/perl-framework/NOTICE @@ -0,0 +1,6 @@ +Apache HTTP Server Test Framework +Copyright 2020 The Apache Software Foundation. + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + diff --git a/debian/perl-framework/README b/debian/perl-framework/README new file mode 100644 index 0000000..a7ff46c --- /dev/null +++ b/debian/perl-framework/README @@ -0,0 +1,243 @@ + + Testing Apache with the Perl Test Harness +Prerequisites +------------- +These two modules must first be installed; + +- perl-ExtUtils-MakeMaker +- perl-Test + +You'll need to install the CPAN modules listed in: +Apache-Test/lib/Bundle/ApacheTest.pm +All you have to do to install them all in one shot is: +perl -MCPAN -e 'install Bundle::ApacheTest' + +Which are also available in one tarball here: +http://perl.apache.org/~dougm/httpd-test-bundle-0.02.tar.gz + +Note: Crypt::SSLeay requires OpenSSL to be installed (only required +for t/TEST -ssl): http://www.openssl.org/ +More accurate results may be obtained by using the same openssl command +line and libraries as consumed by APR-util and mod_ssl, due to X509 +formatting behavior differences. + +For an extensive documentation see +http://perl.apache.org/docs/general/testing/testing.html + or +http://svn.apache.org/viewvc/perl/modperl/docs/trunk/src/docs/general/testing/testing.pod + +To run the tests for all Apache web server modules, some additional +CPAN modules will be required. If the tests don't work, make sure +that you have up to date versions of each of these perl modules: + +``` +cpan App::cpanminus +cpanm Bundle::ApacheTest \ + HTTP::DAV DateTime Time::HiRes \ + Test::Harness Crypt::SSLeay Net::SSLeay IO::Socket::SSL \ + IO::Socket::IP IO::Select LWP::Protocol::https AnyEvent \ + AnyEvent::WebSocket::Client FCGI +``` + + +Quick Start +----------- + +If you don't care how it works and just want to run the tests, here's +how you go about doing that. + +1. You need an installation of Apache. (1.3.x thru trunk) +2. Any DSOs you wish to use should be configured in that Apache's + httpd.conf (the test harness will pick this configuration up) +3. Setup: + perl Makefile.PL -apxs /path/to/apache/bin/apxs +4. Run the tests: + t/TEST +5. Evaluate test output. + +Getting a little deeper +----------------------- + +The test harness will run every .t file under the t/ directory. So +let's say you only want to run the tests for PHP. Do this: + t/TEST -httpd /path/to/apache/bin/httpd t/php + +That will start the test server, run the .t tests under t/php and shut +down the test server. You can also control each of these steps. + +This will start the test server: + t/TEST -httpd /path/to/apache/bin/httpd -start + +This will run the PHP tests in the test environment: + t/TEST t/php + +This will stop the test server: + t/TEST -stop + +This will run the server under gdb (using -X): + t/TEST -d gdb + +Note: At this point, you have a working test environment. You can +look in t/conf for the test server configuration files. These are +generated by the test harness. Once you have a working test +environment, you do not need to specify 'httpd' on the t/TEST command +line. For instance, to start the server up again, the command + t/TEST -start +would be sufficient. + +Running Regression Tests +------------------------ +For a full regression test, you should have all modules loaded. Build the server +with + configure --enable-modules=reallyall --enable-load-all-modules ... +among other things. Edit the generated httpd.conf and comment all mpm modules +that you do not want. Run "t/TEST -clean" again. + +You will see some + skipped: cannot find module 'XXX' +as not all modules are in every apache release (but the tests run for all). + +All in all, some >4k tests will run and the result needs to be: PASS + +Trouble Shooting +---------------- +If you have a "PASS" at the end of "t/TEST", congratulations! If not, this +sections gives some advise in order to find the cause. Feel free to expand +this to make life easier for others. + +0. If your test startup hangs forever in "waiting for server to warm up", but + the test server is reachable under port 8529, you might be the victim of + ipv4/6 confusion. The default servername configured is "localhost" and + some operating systems define 127.0.0.1 *as well as* ::1 in /etc/hosts. + If the test server listens only on 0.0.0.0 it might not answer requests to + ::1 and that causes the test startup to hang. + Solution: comment the ::1 line in /etc/hosts and see if that improves matters. +1. Run "t/TEST -clean" every time you change something in your Apache + configuration. The test suite picks up certain things from your installed + httpd.conf (such as LoadModule statements) and will not see your changes + unless you clean it. +2. Failures in proxy.t may originate from the fact that the test script cannot + open the specified port. This happens on some machines if you abort a test + run and the socket is not properly shut down. Check if the error goes + away after a reboot. (proxy.t tests are slow, so chances you interrupt tests + at that point are good.) +3. Failures in access.t may result from reverse lookups not working or giving + other answers than expected. In the cause 0 above, if the test client + connects via 127.0.0.1, a "Grant for localhost" might resolve to "::1" + and therefore will not match the access rules of the tests. + Solution: check that your servername is 'localhost' (which is + the default) and that it *always* resolves to 127.0.0.1. +4. If some ssl test cases fail, especially when t/ssl/proxy.t fails, the + reason can be mismatches between your installed SSL library and the one + httpd uses. The "openssl" binary found in your $PATH is used to create + binary setup files by t/TEST. If another version of openssl then tries + to read these from your Apache server process, it might fail. + Try the following: + > t/TEST -clean + > PATH=<bin dir of correct openssl>:$PATH t/TEST + If a lot of ssl tests fail, check in the error log for the presence of + a certificate validation error. If you find it, check the expiration date + of the TLS/SSL certificates used by the tests, they might be expired. + Running TEST -clean should delete the old ssl certificates, so they'll be + regenerated during the next run. +5. If you see failures in the modules/h2.t test cases, please notify the dev + mailing list with a description of your setup. These tests are quite young, + currently only valid in 2.4.x and later and interact with quite some other + modules as well as Openssl versions installed. Some tests require mod_ssl + so make sure to load it in the httpd conf. +6. Segmentation faults and core dumps occurring while executing the test suite + might indicate a real problem but always run again the tests after + a clean make install to avoid inconsistencies from old objects. +7. If you see error messages like "Parse errors: Bad plan. + You planned X tests but ran Y." it usually means that you are missing + a perl module or the tested httpd module depends on another one + not loaded in the httpd config. +8. If you see SSL certificate errors, remove t/conf/ssl/ca prior to + t/TEST -clean +9. perl 5.28 in MacOS homebrew seems to hang the test suite. Invoking + /usr/bin/perl Makefile.PL -apxs ... will cause an older perl to be used. + +Smoking Tests +------------- + +Sometimes it's possible that the test is passing properly for the +first time, when it's run for the first time in the thread. But when +you run it again, the test might fail. It's important to run the +repetition smoke testing. For example to repeat the tests 5 times you +can run: + + t/SMOKE -times=5 + +It's also possible that a test will pass when it's run after a +particular test, but if moved to run after a different state it may +fail. For this reason by default the tests run in random order. + +Since it's important to be able to reproduce the problem with the +random testing, whenever -order=random is used, the used seed is +printed to STDERR. Which can be then fed into the future tests with: +via APACHE_TEST_SEED environment variable. + +By adding the option -order=repeat, the tests will be run in +alphabetical order. + +Combining these two important smoke testing techniques, one can run +tests with: + + t/SMOKE -times=N -order=(repeat|random) + +For example, to run the mod_rewrite tests 5 times, one would: + + t/SMOKE -times=5 -verbose t/modules/rewrite.t + +So the tests can be repeated N times, and run in the following three +modes: + +- randomize all tests +- repeat the whole tests suite N times + +For configuration options and default settings run: + + t/SMOKE -help + +For more information refer to the Apache::TestSmoke manpage. + + +Test Environment Configuration +------------------------------ + +The test server is configured with conf files like any normal Apache +server. The tricky part is those conf files are generated by the +harness just prior to starting the server. t/conf/httpd.conf is +generated by t/conf/httpd.conf.in. If that does not exist, the +harness will generate a working configuration and will include +LoadModule (and AddModule for Apache 1.3) directives from the +httpd.conf associated with the httpd binary you are using for testing. +If t/conf/extra.conf.in exists, t/conf/extra.conf will be generated +from that, and an Include directive for that file will be put in the +generated t/conf/httpd.conf. t/conf/apache_test_config.pm is +generated from the test configuration. It contains all the +information about the configuration of your test server. You can +access this information in test scripts by: + my $env = Apache::TestConfig->thaw; +Apache::TestConfig access apache_test_config.pm and returns a hash +reference with all the information. Look through +apache_test_config.pm, it's a lot of stuff. Once these conf files are +generated, you have a working test environment, and they must be +'cleaned' if you wish to make changes to them. To clean the +environment: + t/TEST -clean +(Now you will have to specify your httpd binary when starting back up +again.) + + +More Information +---------------- + +For more information on using the test harness and writing tests, see +the README in Apache-Test and the examples in Apache-Test/t. + +The test harness was originally written by Doug MacEachern and is +discussed on the httpd dev mailing list (dev@httpd.apache.org). + +It is also included in modperl-2.0 source along with tests for +modperl-2.0. diff --git a/debian/perl-framework/STATUS b/debian/perl-framework/STATUS new file mode 100644 index 0000000..add2641 --- /dev/null +++ b/debian/perl-framework/STATUS @@ -0,0 +1,33 @@ +httpd-test/perl-framework STATUS: -*-text-*- +Last modified at [$Date$] + +Stuff to do: + * finish the t/TEST exit code issue (ORed with 0x2C if + framework failed) + + * change existing tests that frob the DocumentRoot (e.g., + t/modules/access.t) to *not* do that; instead, have + Makefile.PL prepare appropriate subdirectory configs + for them. Why? So t/TEST can be used to test a + remote server. + + * problems with -d perl mode, doesn't work as documented + Message-ID: <3BD10479.2020506@stason.org> + Date: Sat, 20 Oct 2001 12:58:33 +0800 + Subject: Re: perldb + +Tests to be written: + + * t/apache + - simulations of network failures (incomplete POST bodies, + chunked and unchunked; missing POST bodies; slooow + client connexions, such as taking 1 minute to send + 1KiB; ...) + + * t/modules/autoindex + - something seems possibly broken with inheritance on 2.0 + + * t/ssl + - SSLPassPhraseDialog exec: + - SSLRandomSeed exec: + diff --git a/debian/perl-framework/build/config.pl b/debian/perl-framework/build/config.pl new file mode 100644 index 0000000..b7de368 --- /dev/null +++ b/debian/perl-framework/build/config.pl @@ -0,0 +1,9 @@ +#!/usr/bin/perl -w + +use strict; +use FindBin qw($Bin); +use lib "$Bin/../Apache-Test/lib"; + +use Apache::TestConfig (); + +print Apache::TestConfig::as_string(); diff --git a/debian/perl-framework/c-modules/authany/mod_authany.c b/debian/perl-framework/c-modules/authany/mod_authany.c new file mode 100644 index 0000000..a5e146c --- /dev/null +++ b/debian/perl-framework/c-modules/authany/mod_authany.c @@ -0,0 +1,172 @@ +#if CONFIG_FOR_HTTPD_TEST + +Alias /authany @DocumentRoot@ +<Location /authany> + require user any-user + AuthType Basic + AuthName authany + <IfDefine !APACHE1> + <IfVersion >= 2.3> + AuthBasicProvider any + </IfVersion> + </IfDefine> +</Location> + +#endif + +#include "ap_mmn.h" + +/* do not accept empty "" strings */ +#define strtrue(s) (s && *s) + +#if AP_MODULE_MAGIC_AT_LEAST(20060110, 0) + +#include "ap_provider.h" +#include "mod_auth.h" + +static authn_status authn_check_password(request_rec *r, const char *user, + const char *password) +{ + return strtrue(r->user) && strcmp(r->user, "guest") == 0 + ? AUTH_GRANTED : AUTH_DENIED; +} + +static const authn_provider authn_any_provider = +{ + &authn_check_password +}; + +static authz_status any_check_authorization(request_rec *r, + const char *requirement, + const void *dummy) +{ +#if AP_MODULE_MAGIC_AT_LEAST(20100714,0) + if (!r->user) + return AUTHZ_DENIED_NO_USER; +#endif + + return strtrue(r->user) && strcmp(requirement, "any-user") == 0 + ? AUTHZ_GRANTED : AUTHZ_DENIED; +} + +static const authz_provider authz_any_provider = +{ + &any_check_authorization +}; + +static void extra_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AUTHN_PROVIDER_GROUP, + "any", "0", &authn_any_provider); + ap_register_provider(p, AUTHZ_PROVIDER_GROUP, + "user", "0", &authz_any_provider); +} + +#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks + +#include "apache_httpd_test.h" + +#else /* < 2.3 */ + +#ifdef APACHE2 + +#include "apr_pools.h" + +static void extra_hooks(apr_pool_t *); + +#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks + +#else + +#define APACHE_HTTPD_TEST_HOOK_ORDER APR_HOOK_FIRST +#define APACHE_HTTPD_TEST_CHECK_USER_ID authany_handler +#define APACHE_HTTPD_TEST_AUTH_CHECKER require_any_user + +#endif + +#include "apache_httpd_test.h" + +static int require_any_user(request_rec *r) +{ + const apr_array_header_t *requires = ap_requires(r); + require_line *rq; + int x; + + if (!requires) { + return DECLINED; + } + + rq = (require_line *) requires->elts; + + for (x = 0; x < requires->nelts; x++) { + const char *line, *requirement; + + line = rq[x].requirement; + requirement = ap_getword(r->pool, &line, ' '); + + if ((strcmp(requirement, "user") == 0) && + (strcmp(line, "any-user") == 0)) + { + return OK; + } + } + + return DECLINED; +} + +static int authany_handler(request_rec *r) +{ + const char *sent_pw; + int rc = ap_get_basic_auth_pw(r, &sent_pw); + char *user; + + if (rc != OK) { + return rc; + } + + if (require_any_user(r) != OK) { + return DECLINED; + } + +#ifdef APACHE1 + user = r->connection->user; +#endif +#ifdef APACHE2 + user = r->user; +#endif + + if (!(strtrue(user) && strtrue(sent_pw))) { + ap_note_basic_auth_failure(r); +#ifdef APACHE1 + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, + "Both a username and password must be provided"); +#endif +#ifdef APACHE2 + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, + "Both a username and password must be provided"); +#endif + return HTTP_UNAUTHORIZED; + } + + return OK; +} + +#ifdef APACHE2 +static void extra_hooks(apr_pool_t *p) +{ + /* mod_authany and mod_ssl both specify APR_HOOK_FIRST as the + * ordering of their check-user-id hooks. + * mod_ssl's must run before mod_authany because it may need to + * generate the Basic auth information based on the certificate. + */ + static const char * const modssl_runs_before[] = {"mod_ssl.c", NULL}; + + ap_hook_check_user_id(authany_handler, modssl_runs_before, NULL, + APR_HOOK_FIRST); + ap_hook_auth_checker(require_any_user, NULL, NULL, APR_HOOK_FIRST); +} +#endif + +#endif + +APACHE_HTTPD_TEST_MODULE(authany); diff --git a/debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c b/debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c new file mode 100644 index 0000000..ce5ef99 --- /dev/null +++ b/debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c @@ -0,0 +1,54 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "ap_config.h" + +/* + * in real life we'd never allow the client to configure filters. + * the purpose of this module is to let .t tests configure filters + * this allows to test non-filtered and filtered requests without + * duplicating lots of test configuration + */ + +static int client_add_filter_header(void *data, + const char *key, + const char *val) +{ + request_rec *r = (request_rec *)data; + + if (strcasecmp(key, "X-AddInputFilter") == 0) { + ap_add_input_filter(val, NULL, r, r->connection); + } + else if (strcasecmp(key, "X-AddOutputFilter") == 0) { + ap_add_output_filter(val, NULL, r, r->connection); + } + + return 1; +} + +static void client_add_filter_insert(request_rec *r) +{ + apr_table_do(client_add_filter_header, (void*)r, + r->headers_in, NULL); +} + +static void client_add_filter_register_hooks(apr_pool_t *p) +{ + ap_hook_insert_filter(client_add_filter_insert, + NULL, NULL, APR_HOOK_LAST); +} + +module AP_MODULE_DECLARE_DATA client_add_filter_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + NULL, /* table of config file commands */ + client_add_filter_register_hooks /* register hooks */ +}; + diff --git a/debian/perl-framework/c-modules/eat_post/mod_eat_post.c b/debian/perl-framework/c-modules/eat_post/mod_eat_post.c new file mode 100644 index 0000000..560ba19 --- /dev/null +++ b/debian/perl-framework/c-modules/eat_post/mod_eat_post.c @@ -0,0 +1,61 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /eat_post> + SetHandler eat_post +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER eat_post_handler + +#include "apache_httpd_test.h" + +/* like mod_echo_post.c but does not echo back the data, + * just sends back the number of bytes read + */ +static int eat_post_handler(request_rec *r) +{ + int rc; + long nrd, total = 0; +#ifdef APACHE1 + char buff[IOBUFSIZE]; +#else + char buff[AP_IOBUFSIZE]; +#endif + + if (strcmp(r->handler, "eat_post")) { + return DECLINED; + } + if ((r->method_number != M_POST) && (r->method_number != M_PUT)) { + return DECLINED; + } + + if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) { +#ifdef APACHE1 + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server, + "[mod_eat_post] ap_setup_client_block failed: %d", rc); +#else + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server, + "[mod_eat_post] ap_setup_client_block failed: %d", rc); +#endif /* APACHE1 */ + return rc; + } + + if (!ap_should_client_block(r)) { + return OK; + } + +#ifdef APACHE1 + ap_send_http_header(r); +#endif + + while ((nrd = ap_get_client_block(r, buff, sizeof(buff))) > 0) { + total += nrd; + } + + ap_rprintf(r, "%ld\n", total); + + return OK; +} + +APACHE_HTTPD_TEST_MODULE(eat_post); diff --git a/debian/perl-framework/c-modules/echo_post/mod_echo_post.c b/debian/perl-framework/c-modules/echo_post/mod_echo_post.c new file mode 100644 index 0000000..ebda4d5 --- /dev/null +++ b/debian/perl-framework/c-modules/echo_post/mod_echo_post.c @@ -0,0 +1,102 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /echo_post> + SetHandler echo_post +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER echo_post_handler + +#include "apache_httpd_test.h" + +static int echo_post_handler(request_rec *r) +{ + int rc; + long nrd, total = 0; + char buff[BUFSIZ]; + + if (strcmp(r->handler, "echo_post")) { + return DECLINED; + } + if (r->method_number != M_POST) { + return DECLINED; + } + + if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) { +#ifdef APACHE1 + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server, + "[mod_echo_post] ap_setup_client_block failed: %d", rc); +#else + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server, + "[mod_echo_post] ap_setup_client_block failed: %d", rc); +#endif /* APACHE1 */ + return 0; + } + + if (!ap_should_client_block(r)) { + return OK; + } + +#ifdef APACHE1 + ap_send_http_header(r); +#endif + + if (r->args) { +#ifdef APACHE1 + ap_rprintf(r, "%ld:", r->remaining); +#else + ap_rprintf(r, "%" APR_OFF_T_FMT ":", r->remaining); +#endif /* APACHE1 */ + } + +#ifdef APACHE1 + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "[mod_echo_post] going to echo %ld bytes", + r->remaining); +#else + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "[mod_echo_post] going to echo %" APR_OFF_T_FMT " bytes", + r->remaining); +#endif /* APACHE1 */ + + while ((nrd = ap_get_client_block(r, buff, sizeof(buff))) > 0) { +#ifdef APACHE1 + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "[mod_echo_post] read %ld bytes (wanted %d, remaining=%ld)", + nrd, sizeof(buff), r->remaining); +#else + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, + "[mod_echo_post] read %ld bytes (wanted %" APR_SIZE_T_FMT + ", remaining=%" APR_OFF_T_FMT ")", + nrd, sizeof(buff), r->remaining); +#endif /* APACHE1 */ + ap_rwrite(buff, nrd, r); + total += nrd; + } + + if (nrd < 0) { + ap_rputs("!!!ERROR!!!", r); +#ifdef APACHE1 + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "[mod_echo_post] ap_get_client_block got error"); +#else + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "[mod_echo_post] ap_get_client_block got error"); +#endif /* APACHE1 */ + } + +#ifdef APACHE1 + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "[mod_echo_post] done reading %ld bytes, %ld bytes remain", + total, r->remaining); +#else + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "[mod_echo_post] done reading %ld bytes, %" APR_OFF_T_FMT " bytes remain", + total, r->remaining); +#endif /* APACHE1 */ + + return OK; +} + +APACHE_HTTPD_TEST_MODULE(echo_post); diff --git a/debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c b/debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c new file mode 100644 index 0000000..98cc4e1 --- /dev/null +++ b/debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c @@ -0,0 +1,93 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /echo_post_chunk> + SetHandler echo_post_chunk +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER echo_post_chunk_handler + +#include "apache_httpd_test.h" + +static int echo_post_chunk_handler(request_rec *r) +{ + int rc; + long nrd, total = 0; + char buff[BUFSIZ]; + const char *trailer_header; + + if (strcmp(r->handler, "echo_post_chunk")) { + return DECLINED; + } + if (r->method_number != M_POST) { + return DECLINED; + } + + if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) { +#ifdef APACHE1 + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server, + "[mod_echo_post_chunk] ap_setup_client_block failed: %d", rc); +#else + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server, + "[mod_echo_post_chunk] ap_setup_client_block failed: %d", rc); +#endif /* APACHE1 */ + return 0; + } + + if (!ap_should_client_block(r)) { + return OK; + } + + if (r->args) { + ap_rprintf(r, "%" APR_OFF_T_FMT ":", r->remaining); + } + + fprintf(stderr, "[mod_echo_post_chunk] going to echo " + "%" APR_OFF_T_FMT " bytes\n", + r->remaining); + + while ((nrd = ap_get_client_block(r, buff, sizeof(buff))) > 0) { + fprintf(stderr, + "[mod_echo_post_chunk] read %ld bytes " + "(wanted %" APR_SIZE_T_FMT ", remaining=%" APR_OFF_T_FMT ")\n", + nrd, sizeof(buff), r->remaining); + total += nrd; + } + + /* nrd < 0 is an error condition. Either the chunk size overflowed or the buffer + * size was insufficient. We can only deduce that the request is in error. + */ + if (nrd < 0) { + return HTTP_BAD_REQUEST; + } +#ifdef APACHE1 + ap_send_http_header(r); +#endif + +#ifdef APACHE1 + trailer_header = ap_table_get(r->headers_in, "X-Chunk-Trailer"); +#elif (MODULE_MAGIC_COOKIE >= 0x41503235UL) && AP_MODULE_MAGIC_AT_LEAST(20140627,5) + trailer_header = apr_table_get(r->trailers_in, "X-Chunk-Trailer"); +#elif (MODULE_MAGIC_COOKIE == 0x41503234UL) && AP_MODULE_MAGIC_AT_LEAST(20120211,37) + trailer_header = apr_table_get(r->trailers_in, "X-Chunk-Trailer"); +#elif (MODULE_MAGIC_COOKIE == 0x41503232UL) && AP_MODULE_MAGIC_AT_LEAST(20051115,36) + trailer_header = apr_table_get(r->trailers_in, "X-Chunk-Trailer"); +#else + trailer_header = apr_table_get(r->headers_in, "X-Chunk-Trailer"); +#endif + if (!trailer_header) { + trailer_header = "No chunked trailer available!"; + } + + ap_rputs(trailer_header, r); + + fprintf(stderr, + "[mod_echo_post_chunk] done reading %ld bytes, " + "%" APR_OFF_T_FMT " bytes remain\n", + total, r->remaining); + + return OK; +} + +APACHE_HTTPD_TEST_MODULE(echo_post_chunk); diff --git a/debian/perl-framework/c-modules/fold/mod_fold.c b/debian/perl-framework/c-modules/fold/mod_fold.c new file mode 100644 index 0000000..548cb67 --- /dev/null +++ b/debian/perl-framework/c-modules/fold/mod_fold.c @@ -0,0 +1,33 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /fold> + SetHandler fold +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER fold_handler + +#include "apache_httpd_test.h" + +static int fold_handler(request_rec *r) +{ + + if (!r->handler || strcasecmp(r->handler, "fold")) { + return DECLINED; + } + + if (r->args) { + ap_set_content_type(r, r->args); + } + else { + ap_set_content_type(r, "text/html"); + } + + /* This doesn't work with CGI or asis, hence the tiny module */ + apr_table_set(r->err_headers_out, "Foo", "Bar\r\n Baz"); + + return OK; +} + +APACHE_HTTPD_TEST_MODULE(fold); diff --git a/debian/perl-framework/c-modules/httpd_test_util.c b/debian/perl-framework/c-modules/httpd_test_util.c new file mode 100644 index 0000000..bc8e608 --- /dev/null +++ b/debian/perl-framework/c-modules/httpd_test_util.c @@ -0,0 +1,44 @@ +/* poor man's optional functions + * if we didn't need to support 1.x we could use optional functions. + * just hack in this util functions with #define/#include/static for now. + * + * tho we could create our own version optional functions using + * the 1.3/2.0 dlsym-ish function to lookup function pointers given a + * mod_httpd_test_util.so and httpd_test_util.dynamic_load_handle + * but thats more trouble than it is worth at the moment. + */ + +#ifdef WANT_HTTPD_TEST_SPLIT_QS_NUMBERS + +/* split query string in the form of GET /foo?1024,5000 */ + +static int httpd_test_split_qs_numbers(request_rec *r, ...) +{ + va_list va; + char *endptr, *args = r->args; + + if (!args) { + return 0; + } + + va_start(va, r); + + while (1) { + apr_size_t *s = va_arg(va, apr_size_t *); + if (!s) { + break; + } + *s = strtol(args, &endptr, 0); + if (endptr && (*endptr == ',')) { + ++endptr; + args = endptr; + } + } + + va_end(va); + + return 1; +} + +#endif /* WANT_HTTPD_TEST_SPLIT_QS_NUMBERS */ + diff --git a/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c b/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c new file mode 100644 index 0000000..1a47341 --- /dev/null +++ b/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c @@ -0,0 +1,184 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +#if CONFIG_FOR_HTTPD_TEST + +<Location /input_body_filter> + SetHandler input-body-filter + InputBodyFilter On +</Location> + +#endif + +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "ap_config.h" +#include "util_filter.h" +#include "apr_buckets.h" +#include "apr_strings.h" + +module AP_MODULE_DECLARE_DATA input_body_filter_module; + +#define INPUT_BODY_FILTER_NAME "INPUT_BODY_FILTER" + +typedef struct { + int enabled; +} input_body_filter_dcfg_t; + +static void *input_body_filter_dcfg_create(apr_pool_t *p, char *dummy) +{ + input_body_filter_dcfg_t *dcfg = + (input_body_filter_dcfg_t *)apr_pcalloc(p, sizeof(*dcfg)); + + return dcfg; +} + +static int input_body_filter_fixup_handler(request_rec *r) +{ + if ((r->method_number == M_POST) && r->handler && + !strcmp(r->handler, "input-body-filter")) + { + r->handler = "echo_post"; + } + + return OK; +} + +static int input_body_filter_response_handler(request_rec *r) +{ + if (strcmp(r->handler, "echo_post")) { + return DECLINED; + } + + if (r->method_number != M_POST) { + ap_rputs("1..1\nok 1\n", r); + return OK; + } + else { + return DECLINED; + } +} + +static void reverse_string(char *string, int len) +{ + register char *up, *down; + register unsigned char tmp; + + up = string; + down = string + len - 1; + + while (down > up) { + tmp = *up; + *up++ = *down; + *down-- = tmp; + } +} + +typedef struct input_body_ctx_t { + apr_bucket_brigade *b; +} input_body_ctx_t; + +static int input_body_filter_handler(ap_filter_t *f, apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + apr_status_t rv; + input_body_ctx_t *ctx = f->ctx; + + if (!ctx) { + f->ctx = ctx = apr_pcalloc(r->pool, sizeof(*ctx)); + ctx->b = apr_brigade_create(r->pool, c->bucket_alloc); + } + + if (APR_BRIGADE_EMPTY(ctx->b)) + { + if ((rv = ap_get_brigade(f->next, ctx->b, mode, block, + readbytes)) != APR_SUCCESS) { + return rv; + } + } + + while (!APR_BRIGADE_EMPTY(ctx->b)) { + const char *data; + apr_size_t len; + apr_bucket *bucket; + + bucket = APR_BRIGADE_FIRST(ctx->b); + + if (APR_BUCKET_IS_EOS(bucket)) { + APR_BUCKET_REMOVE(bucket); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + break; + } + + rv = apr_bucket_read(bucket, &data, &len, block); + + if (rv != APR_SUCCESS) { + return rv; + } + + APR_BUCKET_REMOVE(bucket); + + if (len) { + char *reversed = apr_pstrndup(r->pool, data, len); + reverse_string(reversed, len); + bucket = apr_bucket_pool_create(reversed, len, r->pool, + c->bucket_alloc); + } + + APR_BRIGADE_INSERT_TAIL(bb, bucket); + } + + return OK; +} + +static void input_body_filter_insert_filter(request_rec *r) +{ + input_body_filter_dcfg_t *dcfg = + ap_get_module_config(r->per_dir_config, + &input_body_filter_module); + + if (dcfg->enabled) { + ap_add_input_filter(INPUT_BODY_FILTER_NAME, NULL, r, r->connection); + } +} + +static void input_body_filter_register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(input_body_filter_fixup_handler, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_handler(input_body_filter_response_handler, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_insert_filter(input_body_filter_insert_filter, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_register_input_filter(INPUT_BODY_FILTER_NAME, + input_body_filter_handler, + NULL, + AP_FTYPE_RESOURCE); +} + +static const command_rec input_body_filter_cmds[] = { + AP_INIT_FLAG("InputBodyFilter", ap_set_flag_slot, + (void *)APR_OFFSETOF(input_body_filter_dcfg_t, enabled), + OR_ALL, "Enable input body filter"), + { NULL } +}; + +module AP_MODULE_DECLARE_DATA input_body_filter_module = { + STANDARD20_MODULE_STUFF, + input_body_filter_dcfg_create, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + input_body_filter_cmds, /* table of config file commands */ + input_body_filter_register_hooks /* register hooks */ +}; + diff --git a/debian/perl-framework/c-modules/list_modules/mod_list_modules.c b/debian/perl-framework/c-modules/list_modules/mod_list_modules.c new file mode 100644 index 0000000..40738a1 --- /dev/null +++ b/debian/perl-framework/c-modules/list_modules/mod_list_modules.c @@ -0,0 +1,38 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /list_modules> + SetHandler list_modules +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER list_modules_handler + +#define CORE_PRIVATE /* for ap_top_module */ +#include "apache_httpd_test.h" + +static int list_modules_handler(request_rec *r) +{ + module *modp; + + if (strcmp(r->handler, "list_modules")) { + return DECLINED; + } + if (r->method_number != M_GET) { + return DECLINED; + } + +#ifdef APACHE1 +#define ap_top_module top_module + ap_send_http_header(r); +#endif + + for (modp = ap_top_module; modp; modp = modp->next) { + ap_rvputs(r, modp->name, "\n", NULL); + } + + return OK; +} + +APACHE_HTTPD_TEST_MODULE(list_modules); + diff --git a/debian/perl-framework/c-modules/memory_track/mod_memory_track.c b/debian/perl-framework/c-modules/memory_track/mod_memory_track.c new file mode 100644 index 0000000..25d11ca --- /dev/null +++ b/debian/perl-framework/c-modules/memory_track/mod_memory_track.c @@ -0,0 +1,45 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /memory_track> + SetHandler memory-track +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER memory_track_handler + +#include "apache_httpd_test.h" +#include "ap_mpm.h" + +static int memory_track_handler(request_rec *r) +{ + int result; + + if (strcmp(r->handler, "memory-track")) { + return DECLINED; + } + if (r->method_number != M_GET) { + return DECLINED; + } + + /* t/apache/leaks.t not reliable with event. */ + if (!ap_mpm_query(AP_MPMQ_IS_ASYNC, &result) && result) { + return HTTP_SERVICE_UNAVAILABLE; + } + +#if APR_POOL_DEBUG + { + conn_rec *c = r->connection; + apr_size_t n = apr_pool_num_bytes(c->pool, 1); + + ap_rprintf(r, "connection,%ld,%lu\n", c->id, n); + } + + return OK; +#else + return HTTP_NOT_IMPLEMENTED; +#endif +} + +APACHE_HTTPD_TEST_MODULE(memory_track); + diff --git a/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c b/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c new file mode 100644 index 0000000..0fad8ce --- /dev/null +++ b/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c @@ -0,0 +1,181 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +/* + * purpose of this module is to test protocol modules that need to + * send data to the client before reading any request data. + * in this case, mod_ssl needs to handshake before sending data to the client. + * t/protocol/nntp-like.t tests both with and without ssl + * to make sure the protocol code works in both cases. + */ + +#if CONFIG_FOR_HTTPD_TEST + +<VirtualHost mod_nntp_like> + NNTPLike On +</VirtualHost> + +<IfModule @ssl_module@> + <VirtualHost mod_nntp_like_ssl> + NNTPLike On + SSLEngine On + </VirtualHost> +</IfModule> + +#endif + +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_connection.h" +#include "http_request.h" +#include "http_log.h" +#include "ap_config.h" +#include "util_filter.h" +#include "apr_buckets.h" +#include "apr_strings.h" + +module AP_MODULE_DECLARE_DATA nntp_like_module; + +typedef struct { + int enabled; +} nntp_like_srv_cfg_t; + +static void *nntp_like_srv_cfg_create(apr_pool_t *p, server_rec *s) +{ + nntp_like_srv_cfg_t *cfg = apr_palloc(p, sizeof(*cfg)); + + cfg->enabled = 0; + + return cfg; +} + +static const char *nntp_like_cmd_enable(cmd_parms *cmd, void *dummy, int arg) +{ + nntp_like_srv_cfg_t *cfg = + ap_get_module_config(cmd->server->module_config, + &nntp_like_module); + cfg->enabled = arg; + + return NULL; +} + +/* this function just triggers the SSL handshake. + * normally that would happen in a protocol such as HTTP when + * the client request is read. however, with certain protocols + * such as NNTP, the server sends a response before the client + * sends a request + * + * if SSL is not enabled, this function is a noop + */ +static apr_status_t nntp_like_init_connection(conn_rec *c) +{ + apr_bucket_brigade *bb; + apr_status_t rv; + + bb = apr_brigade_create(c->pool, c->bucket_alloc); + + rv = ap_get_brigade(c->input_filters, bb, AP_MODE_INIT, + APR_BLOCK_READ, 0); + + apr_brigade_destroy(bb); + + return rv; +} + +static apr_status_t nntp_like_send_welcome(conn_rec *c) +{ + apr_bucket *bucket; + apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc); + +#define NNTP_LIKE_WELCOME \ + "200 localhost - ready\r\n" + + bucket = apr_bucket_immortal_create(NNTP_LIKE_WELCOME, + sizeof(NNTP_LIKE_WELCOME)-1, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc)); + + return ap_pass_brigade(c->output_filters, bb); +} + +static int nntp_like_pre_connection(conn_rec *c, void *csd) +{ + nntp_like_srv_cfg_t *cfg = + ap_get_module_config(c->base_server->module_config, + &nntp_like_module); + + if (cfg->enabled) { + apr_socket_timeout_set(csd, c->base_server->keep_alive_timeout); + } + + return DECLINED; +} + +static int nntp_like_process_connection(conn_rec *c) +{ + apr_bucket_brigade *bb; + apr_status_t rv; + nntp_like_srv_cfg_t *cfg = + ap_get_module_config(c->base_server->module_config, + &nntp_like_module); + + if (!cfg->enabled) { + return DECLINED; + } + + /* handshake if talking over SSL */ + if ((rv = nntp_like_init_connection(c)) != APR_SUCCESS) { + return rv; + } + + /* send the welcome message */ + if ((rv = nntp_like_send_welcome(c)) != APR_SUCCESS) { + return rv; + } + + do { + bb = apr_brigade_create(c->pool, c->bucket_alloc); + + if ((rv = ap_get_brigade(c->input_filters, bb, + AP_MODE_GETLINE, + APR_BLOCK_READ, 0)) != APR_SUCCESS || + APR_BRIGADE_EMPTY(bb)) + { + apr_brigade_destroy(bb); + break; + } + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc)); + + rv = ap_pass_brigade(c->output_filters, bb); + } while (rv == APR_SUCCESS); + + return OK; +} + +static void nntp_like_register_hooks(apr_pool_t *p) +{ + ap_hook_pre_connection(nntp_like_pre_connection, NULL, NULL, + APR_HOOK_MIDDLE); + ap_hook_process_connection(nntp_like_process_connection, + NULL, NULL, + APR_HOOK_MIDDLE); +} + +static const command_rec nntp_like_cmds[] = +{ + AP_INIT_FLAG("NNTPLike", nntp_like_cmd_enable, NULL, RSRC_CONF, + "enable nntp like protocol on this host"), + { NULL } +}; + +module AP_MODULE_DECLARE_DATA nntp_like_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + nntp_like_srv_cfg_create, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + nntp_like_cmds, /* table of config file commands */ + nntp_like_register_hooks /* register hooks */ +}; diff --git a/debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c b/debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c new file mode 100644 index 0000000..01da3e0 --- /dev/null +++ b/debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c @@ -0,0 +1,182 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /random_chunk> + SetHandler random_chunk +</Location> + +#endif + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2004 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + * Portions of this software are based upon public domain software + * originally written at the National Center for Supercomputing Applications, + * University of Illinois, Urbana-Champaign. + */ + +/* + * This module is intended to be used for testing chunked encoding. It + * generates a whole whack of output using ap_bputc() and ap_bputs(). It + * also exercises start_chunk() and end_chunk() in buff.c. To use it + * you should use a tool like netcat and the src/test/check_chunked + * tool. Add something like this to your access.conf file: + * + * <Location /rndchunk> + * SetHandler rndchunk + * </Location> + * + * Then fake requests such as: + * + * GET /rndchunk?0,1000000 HTTP/1.1 + * Host: localhost + * + * The first arg is the random seed, the second is the number of + * "things" to do. You should try a few seeds. + * + * You should also edit main/buff.c and change DEFAULT_BUFSIZE (and + * CHUNK_HEADER_SIZE). Small values are particularly useful for + * finding bugs. Try a few different values. + * + * -djg + */ + +#define APACHE_HTTPD_TEST_HANDLER random_chunk_handler + +#include "apache_httpd_test.h" + +#define MAX_SEGMENT 32 +#define ONE_WEIGHT (256-32) + +#define WANT_HTTPD_TEST_SPLIT_QS_NUMBERS +#include "httpd_test_util.c" + +static int random_chunk_handler(request_rec *r) +{ + apr_size_t seed = 0; + apr_size_t count = 0; + int i; + char buf[MAX_SEGMENT + 1]; + unsigned int len; + apr_size_t total = 0; + + if (strcmp(r->handler, "random_chunk")) { + return DECLINED; + } + + if (r->proto_num < HTTP_VERSION(1,1)) { + return DECLINED; + } + + r->allowed |= (AP_METHOD_BIT << M_GET); + + if (r->method_number != M_GET) { + return DECLINED; + } + + r->content_type = "text/html"; + +#ifdef APACHE1 + ap_send_http_header(r); +#endif + if (r->header_only) { + return OK; + } + + httpd_test_split_qs_numbers(r, &seed, &count, NULL); + + if (!count) { + ap_rputs("Must include args! ... " + "of the form <code>?seed,count</code>", r); + return 0; + } + +#ifdef WIN32 + srand(seed); /* XXX: apr-ize */ +#else + srandom(seed); /* XXX: apr-ize */ +#endif + + for (i = 0; i < count; ++i) { +#ifdef WIN32 + len = rand() % (MAX_SEGMENT + ONE_WEIGHT); +#else + len = random() % (MAX_SEGMENT + ONE_WEIGHT); +#endif + + if (len >= MAX_SEGMENT) { + ap_rputc((i & 1) ? '0' : '1', r); + total += 1; + } + else if (len == 0) { + /* 1.x version used to do this; but chunk_filter does now */ +#if 0 + ap_bsetflag(r->connection->client, B_CHUNK, 0); + ap_bsetflag(r->connection->client, B_CHUNK, 1); +#endif + } + else { + memset(buf, '2' + len, len); + buf[len] = 0; + total += ap_rputs(buf, r); + } + } + + ap_rprintf(r, "__END__:%" APR_SIZE_T_FMT, total); + + fprintf(stderr, "[mod_random_chunk] sent %" APR_SIZE_T_FMT "bytes\n", + total); + + return 0; +} + +APACHE_HTTPD_TEST_MODULE(random_chunk); diff --git a/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c b/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c new file mode 100644 index 0000000..195e1ba --- /dev/null +++ b/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c @@ -0,0 +1,354 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +#if CONFIG_FOR_HTTPD_TEST + +<Location /test_apr_uri> + SetHandler test-apr-uri +</Location> + +#endif + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2004 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + * Portions of this software are based upon public domain software + * originally written at the National Center for Supercomputing Applications, + * University of Illinois, Urbana-Champaign. + */ + +/* + * This module is intended to test the apr_uri routines by parsing a + * bunch of urls and comparing the results with what we expect to + * see. + * + * Usage: + * + * <Location /test-apr-uri> + * SetHandler test-apr-uri + * </Location> + * + * Then make a request to /test-apr-uri. An html apr_table_t of errors will + * be output... and a total count of errors. + */ + +#include "httpd.h" +#include "http_protocol.h" +#include "http_config.h" +#include "http_main.h" + +typedef struct { + const char *scheme; + const char *user; + const char *password; + const char *hostname; + const char *port_str; + const char *path; + const char *query; + const char *fragment; +} test_uri_t; + +#define T_scheme 0x01 +#define T_user 0x02 +#define T_password 0x04 +#define T_hostname 0x08 +#define T_port_str 0x10 +#define T_path 0x20 +#define T_query 0x40 +#define T_fragment 0x80 +#define T_MAX 0x100 + +/* The idea is that we list here a bunch of url pieces that we want + * stitched together in every way that's valid. + */ +static const test_uri_t uri_tests[] = { + { "http", "userid", "passwd", "hostname.goes.here", "80", "/path/goes/here", "query-here", "frag-here" }, + { "http", "", "passwd", "hostname.goes.here", "80", "/path/goes/here", "query-here", "frag-here" }, + { "http", "userid", "", "hostname.goes.here", "80", "/path/goes/here", "query-here", "frag-here" }, + { "http", "userid", "passwd", "", "80", "/path/goes/here", "query-here", "frag-here" }, + { "http", "userid", "passwd", "hostname.goes.here", "", "/path/goes/here", "query-here", "frag-here" }, +#if 0 + /* An empty path means two different things depending on whether this is a + * relative or an absolute uri... consider <a href="#frag"> versus "GET + * http://hostname HTTP/1.1". So this is why parse_uri_components returns + * a NULL for path when it doesn't find one, instead of returning an empty + * string. + * + * We don't really need to test it explicitly since path has no explicit + * character that indicates its presence, and so we test empty paths all + * the time by varying T_path in the loop. It would just cost us extra + * code to special case the empty path string... + */ + { "http", "userid", "passwd", "hostname.goes.here", "80", "", "query-here", "frag-here" }, +#endif + { "http", "userid", "passwd", "hostname.goes.here", "80", "/path/goes/here", "", "frag-here" }, + { "http", "userid", "passwd", "hostname.goes.here", "80", "/path/goes/here", "query-here", "" }, + { "https", "user@d", "pa:swd", "hostname.goes.here.", "", "/~path/goes/here", "query&query?crud", "frag-here?baby" } + +}; + +static char *my_stpcpy(char *d, const char *s) +{ + while((*d = *s)) { + ++d; + ++s; + } + return d; +} + +/* return the number of failures */ +static unsigned iterate_pieces(request_rec *r, const test_uri_t *pieces, int row) +{ + unsigned u; + apr_pool_t *sub; + char *input_uri; + char *strp; + apr_uri_t result; + unsigned expect; + int status; + unsigned failures; + + failures = 0; + + input_uri = apr_palloc(r->pool, + strlen(pieces->scheme) + 3 + + strlen(pieces->user) + 1 + + strlen(pieces->password) + 1 + + strlen(pieces->hostname) + 1 + + strlen(pieces->port_str) + 1 + + strlen(pieces->path) + + + strlen(pieces->query) + 1 + + strlen(pieces->fragment) + 1 + + 1); + + for (u = 0; u < T_MAX; ++u) { + strp = input_uri; + expect = 0; + + /* a scheme requires a hostinfo and vice versa */ + /* a hostinfo requires a hostname */ + if (u & (T_scheme|T_user|T_password|T_hostname|T_port_str)) { + expect |= T_scheme; + strp = my_stpcpy(strp, pieces->scheme); + *strp++ = ':'; + *strp++ = '/'; + *strp++ = '/'; + /* can't have password without user */ + if (u & (T_user|T_password)) { + expect |= T_user; + strp = my_stpcpy(strp, pieces->user); + if (u & T_password) { + expect |= T_password; + *strp++ = ':'; + strp = my_stpcpy(strp, pieces->password); + } + *strp++ = '@'; + } + expect |= T_hostname; + strp = my_stpcpy(strp, pieces->hostname); + if (u & T_port_str) { + expect |= T_port_str; + *strp++ = ':'; + strp = my_stpcpy(strp, pieces->port_str); + } + } + if (u & T_path) { + expect |= T_path; + strp = my_stpcpy(strp, pieces->path); + } + if (u & T_query) { + expect |= T_query; + *strp++ = '?'; + strp = my_stpcpy(strp, pieces->query); + } + if (u & T_fragment) { + expect |= T_fragment; + *strp++ = '#'; + strp = my_stpcpy(strp, pieces->fragment); + } + *strp = 0; + + apr_pool_create_ex(&sub, r->pool, NULL, NULL); + status = apr_uri_parse(sub, input_uri, &result); + if (status == APR_SUCCESS) { +#define CHECK(f) \ + if ((expect & T_##f) \ + && (result.f == NULL || strcmp(result.f, pieces->f))) { \ + status = HTTP_INTERNAL_SERVER_ERROR; \ + } \ + else if (!(expect & T_##f) && result.f != NULL) { \ + status = HTTP_INTERNAL_SERVER_ERROR; \ + } + CHECK(scheme) + CHECK(user) + CHECK(password) + CHECK(hostname) + CHECK(port_str) + CHECK(path) + CHECK(query) + CHECK(fragment) +#undef CHECK + } + if (status != APR_SUCCESS) { + ap_rprintf(r, "<tr><td>%d</td><td>0x%02x</td><td>0x%02x</td><td>%d</td><td>\"%s\"</td>", row, u, expect, status, input_uri); +#define DUMP(f) \ + if (result.f) { \ + ap_rvputs(r, "<td>\"", result.f, "\"<br>", NULL); \ + } \ + else { \ + ap_rputs("<td>NULL<br>", r); \ + } \ + if (expect & T_##f) { \ + ap_rvputs(r, "\"", pieces->f, "\"</td>", NULL); \ + } \ + else { \ + ap_rputs("NULL</td>", r); \ + } + DUMP(scheme); + DUMP(user); + DUMP(password); + DUMP(hostname); + DUMP(port_str); + DUMP(path); + DUMP(query); + DUMP(fragment); +#undef DUMP + ap_rputs("</tr>\n", r); + ++failures; + } + apr_pool_destroy(sub); + } + return failures; +} + +static int test_apr_uri_handler(request_rec *r) +{ + unsigned total_failures; + int i; + + r->allowed |= (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) + return DECLINED; + + if (strcmp(r->handler, "test-apr-uri")) { + return DECLINED; + } + + r->content_type = "text/html"; + + ap_rputs( +DOCTYPE_HTML_2_0 "\n\ +<html><body>\n\ +<p>Key:\n\ +<dl>\n\ +<dt>row\n\ +<dd>entry number in the uri_tests array\n\ +<dt>u\n\ +<dd>fields under test\n\ +<dt>expected\n\ +<dd>fields expected in the result\n\ +<dt>status\n\ +<dd>response from parse_uri_components, or 500 if unexpected results\n\ +<dt>input uri\n\ +<dd>the uri given to parse_uri_components\n\ +</dl>\n\ +<p>The remaining fields are the pieces returned from parse_uri_components, and\n\ +the values we expected for each piece (resp.).\n\ +<p>Only failures are displayed.\n\ +<p>\n\ +<table><tr><th>row</th><th>u</th><th>expect</th><th>status</th><th>input uri</th>", r); +#define HEADER(f) ap_rprintf(r, "<th>" #f "<br>0x%02x</th>", T_##f) + HEADER(scheme); + HEADER(user); + HEADER(password); + HEADER(hostname); + HEADER(port_str); + HEADER(path); + HEADER(query); + HEADER(fragment); +#undef HEADER + + if (r->args) { + i = atoi(r->args); + total_failures = iterate_pieces(r, &uri_tests[i], i); + } + else { + total_failures = 0; + for (i = 0; i < sizeof(uri_tests) / sizeof(uri_tests[0]); ++i) { + total_failures += iterate_pieces(r, &uri_tests[i], i); + if (total_failures > 256) { + ap_rprintf(r, "</table>\n<b>Stopped early to save your browser " + "from certain death!</b>\nTOTAL FAILURES = %u\n", + total_failures); + return OK; + } + } + } + ap_rprintf(r, "</table>\nTOTAL FAILURES = %u\n", total_failures); + + return OK; +} + +static void test_apr_uri_register_hooks(apr_pool_t *p) +{ + ap_hook_handler(test_apr_uri_handler, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA test_apr_uri_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + NULL, /* table of config file commands */ + test_apr_uri_register_hooks /* register hooks */ +}; diff --git a/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c b/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c new file mode 100644 index 0000000..99bc95a --- /dev/null +++ b/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c @@ -0,0 +1,104 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +#if CONFIG_FOR_HTTPD_TEST + +<Location /test_pass_brigade> + SetHandler test_pass_brigade +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER test_pass_brigade_handler + +#include "apache_httpd_test.h" + +#include "apr_buckets.h" + +#define WANT_HTTPD_TEST_SPLIT_QS_NUMBERS +#include "httpd_test_util.c" + +/* + * mainly for testing / researching core_output_filter buffering + */ + +static int test_pass_brigade_handler(request_rec *r) +{ + conn_rec *c = r->connection; + size_t total=0, remaining=1; + char *buff; + size_t buff_size = 8192; + apr_bucket_brigade *bb; + + if (strcmp(r->handler, "test_pass_brigade")) { + return DECLINED; + } + if (r->method_number != M_GET) { + return DECLINED; + } + + httpd_test_split_qs_numbers(r, &buff_size, &remaining, NULL); + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "going to echo %" APR_SIZE_T_FMT " bytes with " + "buffer size=%" APR_SIZE_T_FMT "", + remaining, buff_size); + + buff = malloc(buff_size); + memset(buff, 'a', buff_size); + bb = apr_brigade_create(r->pool, c->bucket_alloc); + + while (total < remaining) { + int left = (remaining - total); + int len = left <= buff_size ? left : buff_size; + apr_bucket *bucket = apr_bucket_transient_create(buff, len, + c->bucket_alloc); + apr_status_t status; + + apr_brigade_cleanup(bb); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + if (len + total == remaining) { + bucket = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + +#if 0 + /* ###### A FLUSH should not be strictly necessary here + * but inserting one apears to work around intermittent + * failures when running t/apache/pass_brigade.t under + * worker. */ + bucket = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); +#endif + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_pass_brigade] sending EOS"); + } + + status = ap_pass_brigade(r->output_filters->next, bb); + + if (status != APR_SUCCESS) { + apr_brigade_destroy(bb); + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "[mod_test_pass_brigade] ap_pass_brigade failed"); + free(buff); + return HTTP_INTERNAL_SERVER_ERROR; + } + + total += len; + + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, + "[mod_test_pass_brigade] wrote %d of %d bytes", + len, len); + } + + apr_brigade_destroy(bb); + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_pass_brigade] done writing %" APR_SIZE_T_FMT + " of %" APR_SIZE_T_FMT " bytes", + total, remaining); + + free(buff); + return OK; +} + +APACHE_HTTPD_TEST_MODULE(test_pass_brigade); + diff --git a/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c b/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c new file mode 100644 index 0000000..64f1542 --- /dev/null +++ b/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c @@ -0,0 +1,66 @@ +#if CONFIG_FOR_HTTPD_TEST + +<Location /test_rwrite> + SetHandler test_rwrite +</Location> + +#endif + +#define APACHE_HTTPD_TEST_HANDLER test_rwrite_handler + +#include "apache_httpd_test.h" + +#define WANT_HTTPD_TEST_SPLIT_QS_NUMBERS +#include "httpd_test_util.c" + +static int test_rwrite_handler(request_rec *r) +{ + size_t total=0, remaining=1; + char *buff; + size_t buff_size = 8192; + + if (strcmp(r->handler, "test_rwrite")) { + return DECLINED; + } + if (r->method_number != M_GET) { + return DECLINED; + } + + if (r->args) { + remaining = atol(r->args); + } + +#ifdef APACHE1 + ap_send_http_header(r); +#endif + + httpd_test_split_qs_numbers(r, &buff_size, &remaining, NULL); + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_rwrite] going to echo %" APR_SIZE_T_FMT " bytes", + remaining); + + buff = malloc(buff_size); + memset(buff, 'a', buff_size); + + while (total < remaining) { + int left = (remaining - total); + int len = left <= buff_size ? left : buff_size; + long nrd = ap_rwrite(buff, len, r); + total += nrd; + + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, + "[mod_test_rwrite] wrote %ld of %d bytes", nrd, len); + } + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_rwrite] done writing %" APR_SIZE_T_FMT + " of %" APR_SIZE_T_FMT " bytes", + total, remaining); + + free(buff); + return OK; +} + +APACHE_HTTPD_TEST_MODULE(test_rwrite); + diff --git a/debian/perl-framework/c-modules/test_session/mod_test_session.c b/debian/perl-framework/c-modules/test_session/mod_test_session.c new file mode 100644 index 0000000..4099cbe --- /dev/null +++ b/debian/perl-framework/c-modules/test_session/mod_test_session.c @@ -0,0 +1,348 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2.3 + +#if CONFIG_FOR_HTTPD_TEST + +<IfModule mod_session.c> + <Location /sessiontest> + Session Off + TestSession On + SetHandler test-session-handler + </Location> + <Location /sessiontest/on> + Session On + SessionHeader X-Test-Session-Override + </Location> + <Location /sessiontest/on/encode> + TestSessionEncoder On + </Location> + <IfModule mod_include.c> + Alias /sessiontest/on/env/on @DocumentRoot@/modules/session + <Directory @DocumentRoot@/modules/session> + Session On + SessionEnv Off + TestSession On + Options +IncludesNOEXEC + </Directory> + <Location /sessiontest/on/env> + SetHandler None + </Location> + <Location /sessiontest/on/env/on> + SessionEnv On + </Location> + </IfModule> + <Location /sessiontest/on/expire> + SessionMaxAge 100 + </Location> + <IfModule mod_version.c> + <IfVersion >= 2.4.41> + <Location /sessiontest/on/expire/cache> + SessionExpiryUpdateInterval 50 + </Location> + </IfVersion> + </IfModule> + <Location /sessiontest/on/include> + SessionInclude /sessiontest/on/include/yes + SessionExclude /sessiontest/on/include/yes/no + </Location> +</IfModule> + +#endif + +#include "apr_strings.h" +#include "mod_session.h" + +#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks +#define APACHE_HTTPD_TEST_CHILD_INIT test_session_init +#define APACHE_HTTPD_TEST_HANDLER test_session_handler +#define APACHE_HTTPD_TEST_COMMANDS test_session_cmds +#define APACHE_HTTPD_TEST_PER_DIR_CREATE test_session_dcfg_create +#define APACHE_HTTPD_TEST_PER_DIR_MERGE test_session_dcfg_merge + +#include "apache_httpd_test.h" + +#define TEST_SESSION_HANDLER "test-session-handler" +#define TEST_SESSION_ENCODER "test-session-encoder" +#define TEST_SESSION_NOTE "mod_test_session" +#define TEST_SESSION_HEADER "X-Test-Session-Override" +#define TEST_SESSION_ENCODING_PREFIX "TestEncoded:" + +typedef struct { + int session; + int session_set; + int encoder; + int encoder_set; +} test_session_dcfg_t; + +typedef enum { + TEST_SESSION_ACTION_NONE, + TEST_SESSION_ACTION_GET, + TEST_SESSION_ACTION_SET +} TestSessionAction; + +module AP_MODULE_DECLARE_DATA test_session_module; + +static APR_OPTIONAL_FN_TYPE(ap_session_get) *ap_session_get_fn = NULL; +static APR_OPTIONAL_FN_TYPE(ap_session_set) *ap_session_set_fn = NULL; +static APR_OPTIONAL_FN_TYPE(ap_session_load) *ap_session_load_fn = NULL; +static APR_OPTIONAL_FN_TYPE(ap_session_save) *ap_session_save_fn = NULL; + +static void test_session_init(apr_pool_t *p, server_rec *s) +{ + ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get); + ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set); + ap_session_save_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_save); + ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load); +} + +static apr_status_t test_session_load(request_rec * r, session_rec ** z) +{ + session_rec *zz; + test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config, + &test_session_module); + if (!dconf || !dconf->session) + return DECLINED; + + zz = (session_rec *)apr_table_get(r->notes, TEST_SESSION_NOTE); + + if (!zz) { + /* Create the session using the query string as the data. */ + char *data = apr_pstrdup(r->pool, r->args); + + if (data) { + int result = ap_unescape_urlencoded(data); + if (result) + return result; + } + + zz = (session_rec *)apr_pcalloc(r->pool, sizeof(session_rec)); + zz->pool = r->pool; + zz->entries = apr_table_make(r->pool, 10); + zz->encoded = data; + apr_table_setn(r->notes, TEST_SESSION_NOTE, (char *)zz); + } + + *z = zz; + return OK; +} + +static apr_status_t test_session_save(request_rec * r, session_rec * z) +{ + test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config, + &test_session_module); + if (!dconf || !dconf->session) + return DECLINED; + + /* Save the session into headers. */ + apr_table_setn(r->headers_out, "X-Test-Session-Dirty", + z->dirty ? "1" : "0"); + + apr_table_set(r->headers_out, "X-Test-Session", z->encoded); + + return OK; +} + +static apr_status_t test_session_encode(request_rec * r, session_rec * z) +{ + test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config, + &test_session_module); + if (!dconf || !dconf->encoder) + return DECLINED; + + /* Simple encoding by adding a prefix. */ + z->encoded = apr_pstrcat(r->pool, TEST_SESSION_ENCODING_PREFIX, + z->encoded, NULL); + return OK; +} + +static apr_status_t test_session_decode(request_rec * r, session_rec * z) +{ + const size_t prefix_len = strlen(TEST_SESSION_ENCODING_PREFIX); + test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config, + &test_session_module); + if (!dconf || !dconf->encoder || !z->encoded) + return DECLINED; + + /* Simple decoding by removing a prefix. */ + if (!strncmp(z->encoded, TEST_SESSION_ENCODING_PREFIX, prefix_len)) { + z->encoded += prefix_len; + return OK; + } + + return HTTP_BAD_REQUEST; +} + +static int test_session_get(request_rec *r, char *name) +{ + session_rec *z = NULL; + const char *value = NULL; + apr_status_t result = ap_session_load_fn(r, &z); + + if (result == OK) + result = ap_session_get_fn(r, z, name, &value); + + if (result == OK) { + if (value) + result = ap_rputs(value, r) > 0 ? OK : HTTP_INTERNAL_SERVER_ERROR; + else + result = HTTP_NOT_FOUND; + } + + return result; +} + +static int test_session_set(request_rec *r, char *name, char *value) +{ + session_rec *z = NULL; + apr_status_t result = ap_session_load_fn(r, &z); + + if (result == OK) + result = ap_session_set_fn(r, z, name, value); + + return result; +} + +static int test_session_handler(request_rec *r) +{ + const char *overrides = NULL; + + if (strcmp(r->handler, TEST_SESSION_HANDLER)) + return DECLINED; + + /* Copy the header for SessionHeader from the request to the response. */ + if ((overrides = apr_table_get(r->headers_in, TEST_SESSION_HEADER))) + apr_table_setn(r->headers_out, TEST_SESSION_HEADER, overrides); + + /* Additional commands to test the session API via POST. */ + if (r->method_number == M_POST) { + char *fieldName = NULL; + char *fieldValue = NULL; + apr_array_header_t *pairs = NULL; + apr_status_t result; + TestSessionAction action; + + if (!ap_session_get_fn || !ap_session_set_fn || + !ap_session_load_fn || !ap_session_save_fn) + return HTTP_INTERNAL_SERVER_ERROR; + + action = TEST_SESSION_ACTION_NONE; + result = ap_parse_form_data(r, NULL, &pairs, 3, 1024); + + if (result != OK) + return result; + + while (pairs && !apr_is_empty_array(pairs)) { + ap_form_pair_t *pair = (ap_form_pair_t *)apr_array_pop(pairs); + if (!strcmp(pair->name, "action")) { + apr_size_t len; + char *value = NULL; + result = apr_brigade_pflatten(pair->value, &value, &len, + r->pool); + if (result == OK && !strncmp(value, "get", len)) + action = TEST_SESSION_ACTION_GET; + else if (result == OK && !strncmp(value, "set", len)) + action = TEST_SESSION_ACTION_SET; + else + return HTTP_BAD_REQUEST; + } + else if (!strcmp(pair->name, "name")) { + apr_off_t off; + apr_size_t len; + apr_brigade_length(pair->value, 1, &off); + len = (apr_size_t)off; + fieldName = apr_pcalloc(r->pool, sizeof(char) * len + 1); + result = apr_brigade_flatten(pair->value, fieldName, &len); + } + else if (!strcmp(pair->name, "value")) { + apr_off_t off; + apr_size_t len; + apr_brigade_length(pair->value, 1, &off); + len = (apr_size_t)off; + fieldValue = apr_pcalloc(r->pool, sizeof(char) * len + 1); + result = apr_brigade_flatten(pair->value, fieldValue, &len); + } + else { + return HTTP_BAD_REQUEST; + } + + if (result != OK) + return result; + } + + switch (action) { + case TEST_SESSION_ACTION_GET: + return test_session_get(r, fieldName); + + case TEST_SESSION_ACTION_SET: + return test_session_set(r, fieldName, fieldValue); + + default: + return HTTP_BAD_REQUEST; + } + } + + return OK; +} + +static void *test_session_dcfg_create(apr_pool_t *p, char *dummy) +{ + return apr_pcalloc(p, sizeof(test_session_dcfg_t)); +} + +static void *test_session_dcfg_merge(apr_pool_t * p, void *basev, void *addv) +{ + test_session_dcfg_t *add = addv; + test_session_dcfg_t *base = basev; + test_session_dcfg_t *new = apr_pcalloc(p, sizeof(test_session_dcfg_t)); + + new->session = (add->session_set == 0) ? base->session : add->session; + new->session_set = add->session_set || base->session_set; + new->encoder = (add->encoder_set == 0) ? base->encoder : add->encoder; + new->encoder_set = add->encoder_set || base->encoder_set; + + return new; +} + +static const char *set_session_enable(cmd_parms * parms, void *dconf, int flag) +{ + test_session_dcfg_t *conf = dconf; + + conf->session = flag; + conf->session_set = 1; + + return NULL; +} + +static const char *set_encoder_enable(cmd_parms * parms, void *dconf, int flag) +{ + test_session_dcfg_t *conf = dconf; + + conf->encoder = flag; + conf->encoder_set = 1; + + return NULL; +} + +static const command_rec test_session_cmds[] = { + AP_INIT_FLAG("TestSession", set_session_enable, NULL, OR_ALL, + "Enable test sessions"), + AP_INIT_FLAG("TestSessionEncoder", set_encoder_enable, NULL, OR_ALL, + "Enable test session encoding"), + { NULL } +}; + +static void extra_hooks(apr_pool_t *pool) +{ + ap_hook_session_load(test_session_load, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_session_save(test_session_save, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_session_encode(test_session_encode, + NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_session_decode(test_session_decode, + NULL, NULL, APR_HOOK_MIDDLE); +} + +APACHE_HTTPD_TEST_MODULE(test_session); diff --git a/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c b/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c new file mode 100644 index 0000000..c9bc762 --- /dev/null +++ b/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c @@ -0,0 +1,171 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +#if CONFIG_FOR_HTTPD_TEST + +<IfModule @ssl_module@> + <Location /test_ssl_var_lookup> + SetHandler test-ssl-var-lookup + SSLVerifyClient require + SSLVerifyDepth 10 + </Location> + + <Location /test_ssl_ext_lookup> + SetHandler test-ssl-ext-lookup + SSLVerifyClient require + SSLVerifyDepth 10 + </Location> +</IfModule> + +#endif + +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_log.h" +#include "ap_config.h" +#include "apr_optional.h" + +#if AP_MODULE_MAGIC_AT_LEAST(20040425, 0) /* simply include mod_ssl.h if using >= 2.1.0 */ + +#include "mod_ssl.h" + +#if MODULE_MAGIC_COOKIE > 0x41503234UL || \ + (MODULE_MAGIC_COOKIE == 0x41503234UL \ + && AP_MODULE_MAGIC_AT_LEAST(20050919, 0)) /* ssl_ext_list() only in 2.4.x */ +#define HAVE_SSL_EXT_LIST +static APR_OPTIONAL_FN_TYPE(ssl_ext_list) *ext_list; +#elif AP_MODULE_MAGIC_AT_LEAST(20050127, 0) /* approx. when ssl_ext_lookup was added */ +#define HAVE_SSL_EXT_LOOKUP +static APR_OPTIONAL_FN_TYPE(ssl_ext_lookup) *ext_lookup; +#endif + +#else +/* For use of < 2.0.x, inline the declaration: */ + +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, + (apr_pool_t *, server_rec *, + conn_rec *, request_rec *, + char *)); + +#endif + +static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *var_lookup; + +static void import_ssl_var_lookup(void) +{ + var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); +#ifdef HAVE_SSL_EXT_LOOKUP + ext_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_ext_lookup); +#endif +#ifdef HAVE_SSL_EXT_LIST + ext_list = APR_RETRIEVE_OPTIONAL_FN(ssl_ext_list); +#endif +} + +#if defined(HAVE_SSL_EXT_LOOKUP) || defined(HAVE_SSL_EXT_LIST) +static int test_ssl_ext_lookup(request_rec *r) +{ + const char *value; + + if (strcmp(r->handler, "test-ssl-ext-lookup") + || r->method_number != M_GET) { + return DECLINED; + } + + if (!r->args) { + ap_rputs("no query", r); + return OK; + } + +#ifdef HAVE_SSL_EXT_LOOKUP + if (!ext_lookup) { + ap_rputs("ssl_ext_lookup not available", r); + return OK; + } + + value = ext_lookup(r->pool, r->connection, 1, r->args); +#else + if (!ext_list) { + ap_rputs("ssl_ext_list not available", r); + return OK; + } + + { + apr_array_header_t *vals = ext_list(r->pool, r->connection, 1, + r->args); + + if (vals) { + value = *(const char **)apr_array_pop(vals); + } + else { + value = NULL; + } + } +#endif + + if (!value) value = "NULL"; + + ap_rputs(value, r); + + return OK; +} + +#endif + +static int test_ssl_var_lookup(request_rec *r) +{ + const char *value; + + if (strcmp(r->handler, "test-ssl-var-lookup")) { + return DECLINED; + } + + if (r->method_number != M_GET) { + return DECLINED; + } + + if (!r->args) { + ap_rputs("no query", r); + return OK; + } + + apr_table_setn(r->subprocess_env, "THE_ARGS", r->args); + + if (!var_lookup) { + ap_rputs("ssl_var_lookup is not available", r); + return OK; + } + + value = var_lookup(r->pool, r->server, + r->connection, r, r->args); + + if (value && *value) { + ap_rputs(value, r); + } + else { + ap_rputs("NULL", r); + } + + return OK; +} + +static void test_ssl_register_hooks(apr_pool_t *p) +{ + ap_hook_handler(test_ssl_var_lookup, NULL, NULL, APR_HOOK_MIDDLE); +#if defined(HAVE_SSL_EXT_LOOKUP) || defined(HAVE_SSL_EXT_LIST) + ap_hook_handler(test_ssl_ext_lookup, NULL, NULL, APR_HOOK_MIDDLE); +#endif + ap_hook_optional_fn_retrieve(import_ssl_var_lookup, + NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA test_ssl_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + NULL, /* table of config file commands */ + test_ssl_register_hooks /* register hooks */ +}; + diff --git a/debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c b/debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c new file mode 100644 index 0000000..5236585 --- /dev/null +++ b/debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c @@ -0,0 +1,48 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2.4 + +/** + * This module provides utility functions for other tests; it doesn't provide + * test cases of its own. + */ + +#define APACHE_HTTPD_TEST_EXTRA_HOOKS util_register_hooks +#include "apache_httpd_test.h" + +#include "apr_strings.h" +#include "ap_expr.h" + +/** + * The util_strlen() ap_expr function simply returns the length of its string + * argument as a decimal string. + */ +static const char *util_strlen_func(ap_expr_eval_ctx_t *ctx, const void *data, + const char *arg) +{ + if (!arg) { + return NULL; + } + + return apr_psprintf(ctx->p, "%" APR_SIZE_T_FMT, strlen(arg)); +} + +static int util_expr_lookup(ap_expr_lookup_parms *parms) +{ + switch (parms->type) { + case AP_EXPR_FUNC_STRING: + if (!strcasecmp(parms->name, "util_strlen")) { + *parms->func = util_strlen_func; + *parms->data = "dummy"; + return OK; + } + break; + } + + return DECLINED; +} + +static void util_register_hooks(apr_pool_t *p) +{ + ap_hook_expr_lookup(util_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE); +} + +APACHE_HTTPD_TEST_MODULE(test_utilities); diff --git a/debian/perl-framework/scripts/fcgi.pl b/debian/perl-framework/scripts/fcgi.pl new file mode 100755 index 0000000..930b030 --- /dev/null +++ b/debian/perl-framework/scripts/fcgi.pl @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +use FCGI; +use Socket; +use FCGI::ProcManager; +use Data::Dumper; + +$num_args = $#ARGV + 1; +if ($num_args != 1) { + print "\nUsage: fcgi.pl <socket>\n"; + exit 1; +} + +$proc_manager = FCGI::ProcManager->new( {n_processes => 1} ); +$socket = FCGI::OpenSocket( $ARGV[0], 10 ); +$request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, +$socket, &FCGI::FAIL_ACCEPT_ON_INTR ); +$proc_manager->pm_manage(); +if ($request) { + while ( $request->Accept() >= 0 ) { + $proc_manager->pm_pre_dispatch(); + print("Content-type: text/plain\r\n\r\n"); + print Dumper(\%req_params); + } +} +FCGI::CloseSocket($socket); diff --git a/debian/perl-framework/scripts/fpm.sh b/debian/perl-framework/scripts/fpm.sh new file mode 100755 index 0000000..ccd83e5 --- /dev/null +++ b/debian/perl-framework/scripts/fpm.sh @@ -0,0 +1 @@ +php-fpm70 -p /usr/local2/php-fpm diff --git a/debian/perl-framework/scripts/httpd-sub.ldif b/debian/perl-framework/scripts/httpd-sub.ldif new file mode 100644 index 0000000..7908cb6 --- /dev/null +++ b/debian/perl-framework/scripts/httpd-sub.ldif @@ -0,0 +1,15 @@ +dn: cn=httpd,dc=example,dc=com +objectClass: applicationProcess +objectClass: simpleSecurityObject +cn: httpd +description: Service Account for httpd +userPassword: mod_authnz_ldap + +dn: ou=dept,dc=example,dc=com +ou: dept +objectClass: organizationalUnit + +# Group +dn: cn=Subgroup,ou=dept,dc=example,dc=com +objectClass: groupOfUniqueNames +uniqueMember: uid=beta,dc=example,dc=com diff --git a/debian/perl-framework/scripts/httpd.ldif b/debian/perl-framework/scripts/httpd.ldif new file mode 100644 index 0000000..b9211ee --- /dev/null +++ b/debian/perl-framework/scripts/httpd.ldif @@ -0,0 +1,56 @@ +dn: cn=httpd,dc=example,dc=com +objectClass: applicationProcess +objectClass: simpleSecurityObject +cn: httpd +description: Service Account for httpd +userPassword: mod_authnz_ldap + +dn: uid=alpha,dc=example,dc=com +objectClass: inetOrgPerson +cn: Alpha Person +givenName: Alpha +sn: Person +uid: alpha +roomnumber: 42 +userPassword: Alpha + +dn: uid=beta,dc=example,dc=com +objectClass: inetOrgPerson +cn: Beta Person +givenName: Beta +sn: Person +uid: beta +roomnumber: 41 +userPassword: Beta + +dn: uid=gamma,dc=example,dc=com +objectClass: inetOrgPerson +cn: Gamma Person +givenName: Gamma +sn: Person +uid: gamma +roomnumber: 101 +userPassword: Gamma + +dn: uid=delta,dc=example,dc=com +objectClass: inetOrgPerson +cn: Delta Person +givenName: Delta +sn: Person +uid: delta +roomnumber: 43 +userPassword: Delta + +# Group +dn: cn=Group One, dc=example,dc=com +objectClass: groupOfUniqueNames +uniqueMember: uid=alpha,dc=example,dc=com +uniqueMember: uid=beta,dc=example,dc=com +uniqueMember: uid=delta,dc=example,dc=com + +# Referral +dn: ou=dept,dc=example,dc=com +objectClass: referral +objectClass: extensibleObject +ou: dept +ref: ldap://localhost:8390/ou=dept,dc=example,dc=com diff --git a/debian/perl-framework/scripts/ldap-init.sh b/debian/perl-framework/scripts/ldap-init.sh new file mode 100755 index 0000000..148a9d0 --- /dev/null +++ b/debian/perl-framework/scripts/ldap-init.sh @@ -0,0 +1,28 @@ +#!/bin/bash -ex +DOCKER=${DOCKER:-`which docker 2>/dev/null || which podman 2>/dev/null`} +cid1=`${DOCKER} run -d -p 8389:389 httpd_ldap` +cid2=`${DOCKER} run -d -p 8390:389 httpd_ldap` +sleep 5 + +# For the CentOS slapd configuration, load some default schema: +if ${DOCKER} exec -i $cid1 test -f /etc/centos-release; then + ${DOCKER} exec -i $cid1 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/slapd-config.ldif + ${DOCKER} exec -i $cid2 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/slapd-config.ldif + + for sc in cosine inetorgperson nis; do + fn=/etc/openldap/schema/${sc}.ldif + ${DOCKER} exec -i $cid1 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// -f ${fn} + ${DOCKER} exec -i $cid2 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// -f ${fn} + done + + ldapadd -x -H ldap://localhost:8390 -D cn=admin,dc=example,dc=com -w travis < scripts/suffix.ldif + ldapadd -x -H ldap://localhost:8389 -D cn=admin,dc=example,dc=com -w travis < scripts/suffix.ldif +fi + +# Disable anonymous bind; must be done as an authenticated local user +# hence via ldapadd -Y EXTERNAL within the container. +${DOCKER} exec -i $cid1 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/non-anon.ldif +${DOCKER} exec -i $cid2 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/non-anon.ldif + +ldapadd -x -H ldap://localhost:8389 -D cn=admin,dc=example,dc=com -w travis < scripts/httpd.ldif +ldapadd -x -H ldap://localhost:8390 -D cn=admin,dc=example,dc=com -w travis < scripts/httpd-sub.ldif diff --git a/debian/perl-framework/scripts/memcached-init.sh b/debian/perl-framework/scripts/memcached-init.sh new file mode 100755 index 0000000..f90f055 --- /dev/null +++ b/debian/perl-framework/scripts/memcached-init.sh @@ -0,0 +1,8 @@ +#!/bin/bash -ex +DOCKER=${DOCKER:-`which docker 2>/dev/null || which podman 2>/dev/null`} +${DOCKER} build -t httpd_memcached - <<EOF +FROM quay.io/centos/centos:stream8 +RUN yum install -y memcached +CMD /usr/bin/memcached -u memcached -v +EOF +${DOCKER} run -d -p 11211:11211 httpd_memcached diff --git a/debian/perl-framework/scripts/non-anon.ldif b/debian/perl-framework/scripts/non-anon.ldif new file mode 100644 index 0000000..535312c --- /dev/null +++ b/debian/perl-framework/scripts/non-anon.ldif @@ -0,0 +1,14 @@ +dn: cn=config +changetype: modify +add: olcDisallows +olcDisallows: bind_anon + +dn: cn=config +changetype: modify +add: olcRequires +olcRequires: authc + +dn: olcDatabase={-1}frontend,cn=config +changetype: modify +add: olcRequires +olcRequires: authc diff --git a/debian/perl-framework/scripts/redis-init.sh b/debian/perl-framework/scripts/redis-init.sh new file mode 100755 index 0000000..f950138 --- /dev/null +++ b/debian/perl-framework/scripts/redis-init.sh @@ -0,0 +1,8 @@ +#!/bin/bash -ex +DOCKER=${DOCKER:-`which docker 2>/dev/null || which podman 2>/dev/null`} +${DOCKER} build -t httpd_redis - <<EOF +FROM quay.io/centos/centos:stream8 +RUN yum install -y redis +CMD /usr/bin/redis-server +EOF +${DOCKER} run -d -p 6379:6379 httpd_redis diff --git a/debian/perl-framework/scripts/slapd-config.ldif b/debian/perl-framework/scripts/slapd-config.ldif new file mode 100644 index 0000000..fa9763e --- /dev/null +++ b/debian/perl-framework/scripts/slapd-config.ldif @@ -0,0 +1,10 @@ +dn: olcDatabase={2}hdb,cn=config +changetype: modify +replace: olcSuffix +olcSuffix: dc=example,dc=com +- +replace: olcRootDN +olcRootDN: cn=admin,dc=example,dc=com +- +add: olcRootPW +olcRootPW: travis diff --git a/debian/perl-framework/scripts/suffix.ldif b/debian/perl-framework/scripts/suffix.ldif new file mode 100644 index 0000000..bf5cbdb --- /dev/null +++ b/debian/perl-framework/scripts/suffix.ldif @@ -0,0 +1,5 @@ +dn: dc=example,dc=com +objectClass: organization +objectClass: dcObject +dc: example +o: Example Organization diff --git a/debian/perl-framework/t/ab/base.t b/debian/perl-framework/t/ab/base.t new file mode 100644 index 0000000..fe565f6 --- /dev/null +++ b/debian/perl-framework/t/ab/base.t @@ -0,0 +1,46 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestConfig; +use Apache::TestUtil qw(t_debug); +use IPC::Open3; +use Symbol; +use File::Spec::Functions qw(catfile); +use Data::Dumper; + +my $vars = Apache::Test::vars(); + +plan tests => ($vars->{ssl_module_name} ? 5 : 2); + +sub run_and_gather_output { + my $command = shift; + t_debug "# running: ", $command, "\n"; + my ($cin, $cout, $cerr); + $cerr = gensym(); + my $pid = open3($cin, $cout, $cerr, $command); + waitpid( $pid, 0 ); + my $status = $? >> 8; + my @cstdout = <$cout>; + my @cstderr = <$cerr>; + return { status => $status, stdout => \@cstdout, stderr => \@cstderr }; +} + +my $ab_path = catfile $vars->{bindir}, "ab"; + +my $http_url = Apache::TestRequest::module2url("core", {scheme => 'http', path => '/'}); +my $http_results = run_and_gather_output("ASAN_OPTIONS='detect_leaks=0' $ab_path -B 127.0.0.1 -q -n 10 $http_url"); +ok $http_results->{status}, 0; +ok scalar(@{$http_results->{stderr}}), 0; + +if ($vars->{ssl_module_name}) { + my $https_url = Apache::TestRequest::module2url($vars->{ssl_module_name}, {scheme => 'https', path => '/'}); + my $https_results = run_and_gather_output("ASAN_OPTIONS='detect_leaks=0' $ab_path -B 127.0.0.1 -q -n 10 $https_url"); + ok $https_results->{status}, 0; + ok (scalar(@{$https_results->{stderr}}), 0, + "https had stderr output:" . Dumper $https_results->{stderr}); + + #XXX: For some reason, stderr is getting pushed into stdout. This test will at least catch known SSL failures + ok (scalar(grep(/SSL.*(fail|err)/i, @{$https_results->{stdout}})), 0, + "https stdout had some possibly alarming content:" . Dumper $https_results->{stdout} ); +} diff --git a/debian/perl-framework/t/apache/404.t b/debian/perl-framework/t/apache/404.t new file mode 100644 index 0000000..83e9c06 --- /dev/null +++ b/debian/perl-framework/t/apache/404.t @@ -0,0 +1,16 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 2; + +my $four_oh_four = GET_STR "/404/not/found/test"; + +print "# GET_STR Response:\n# ", + join("\n# ", split(/\n/, $four_oh_four)), "\n"; + +ok (($four_oh_four =~ /HTTP\/1\.[01] 404 Not Found/) + || ($four_oh_four =~ /RC:\s+404.*Message:\s+Not Found/s)); +ok ($four_oh_four =~ /Content-Type: text\/html/); diff --git a/debian/perl-framework/t/apache/acceptpathinfo.t b/debian/perl-framework/t/apache/acceptpathinfo.t new file mode 100644 index 0000000..b42093c --- /dev/null +++ b/debian/perl-framework/t/apache/acceptpathinfo.t @@ -0,0 +1,86 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $havecgi = have_cgi(); + +my $pathinfo = "/foo/bar"; + +## +## mode path, filerc, filebody, cgirc, cgibody +## +my %tests = ( + default => [ "", "404","Not Found", "200","_${pathinfo}_" ], + on => [ "/on", "200","_${pathinfo}_","200","_${pathinfo}_" ], + off => [ "/off","404","Not Found", "404","Not Found" ] + ); + + +my @files = ("", "/index.shtml"); +push @files, "/test.sh" if ($havecgi); + +my $numtests = ((scalar keys %tests) * (scalar @files) * 4); +plan tests => $numtests, need need_apache(2), need_module('include'), need_lwp; + +my $loc = "/apache/acceptpathinfo"; + +foreach my $mode (keys %tests) { + foreach my $file (@files) { + + foreach my $pinf ("","$pathinfo") { + + my ($expectedrc, $expectedbody); + + if ($pinf eq "") { + $expectedrc = "200"; + $expectedbody = "_\\(none\\)_"; + } + else { + if ($file eq "") { + $expectedrc = "404"; + $expectedbody = "Not Found"; + } + elsif ($file eq "/index.shtml") { + $expectedrc = $tests{$mode}[1]; + $expectedbody = $tests{$mode}[2]; + } + else { + $expectedrc = $tests{$mode}[3]; + $expectedbody = $tests{$mode}[4]; + } + } + + + my $req = $loc.$tests{$mode}[0].$file.$pinf; + + my $resp = GET $req; + + ok t_cmp($resp->code, + $expectedrc, + "AcceptPathInfo $mode return code for $req" + ); + + my $actual = super_chomp($resp->content); + ok t_cmp($actual, + qr/$expectedbody/, + "AcceptPathInfo $mode body for $req" + ); + } + } +} + +sub super_chomp { + my ($body) = shift; + + ## super chomp - all leading and trailing \n (and \r for win32) + $body =~ s/^[\n\r]*//; + $body =~ s/[\n\r]*$//; + ## and all the rest change to spaces + $body =~ s/\n/ /g; + $body =~ s/\r//g; #rip out all remaining \r's + + $body; +} diff --git a/debian/perl-framework/t/apache/byterange.t b/debian/perl-framework/t/apache/byterange.t new file mode 100644 index 0000000..e439d1d --- /dev/null +++ b/debian/perl-framework/t/apache/byterange.t @@ -0,0 +1,57 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest (); +use Apache::TestCommon (); + +Apache::TestCommon::run_files_test(\&verify, 1); + +sub verify { + my($ua, $url, $file) = @_; + my $debug = $Apache::TestRequest::DebugLWP; + + $url = Apache::TestRequest::resolve_url($url); + my $req = HTTP::Request->new(GET => $url); + + my $total = 0; + my $chunk_size = 8192; + + my $wanted = -s $file; + + while ($total < $wanted) { + my $end = $total + $chunk_size; + if ($end > $wanted) { + $end = $wanted; + } + + my $range = "bytes=$total-$end"; + $req->header(Range => $range); + + print $req->as_string if $debug; + + my $res = $ua->request($req); + my $content_range = $res->header('Content-Range') || 'NONE'; + + $res->content("") if $debug and $debug == 1; + print $res->as_string if $debug; + + if ($content_range =~ m:^bytes\s+(\d+)-(\d+)/(\d+):) { + my($start, $end, $total_bytes) = ($1, $2, $3); + $total += ($end - $start) + 1; + } + elsif ($total == 0 && $end == $wanted && + $content_range eq 'NONE' && $res->code == 200) { + $total += $wanted; + } + else { + print "Range: $range\n"; + print "Content-Range: $content_range\n"; + last; + } + } + + print "downloaded $total bytes, file is $wanted bytes\n"; + + ok $total == $wanted; +} diff --git a/debian/perl-framework/t/apache/byterange2.t b/debian/perl-framework/t/apache/byterange2.t new file mode 100644 index 0000000..f0dcc1e --- /dev/null +++ b/debian/perl-framework/t/apache/byterange2.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1, need need_min_apache_version('2.0.51'), need_cgi; + +my $resp; + +$resp = GET_BODY "/modules/cgi/ranged.pl", + Range => 'bytes=5-10/10'; + +ok t_cmp($resp, "hello\n", "return correct content"); diff --git a/debian/perl-framework/t/apache/byterange3.t b/debian/perl-framework/t/apache/byterange3.t new file mode 100644 index 0000000..56932f1 --- /dev/null +++ b/debian/perl-framework/t/apache/byterange3.t @@ -0,0 +1,73 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest (); +use Apache::TestCommon (); + +# test merging of byte ranges + +if (Apache::Test::need_min_apache_version("2.3.15")) { + Apache::TestCommon::run_files_test(\&verify, 1); +} +else { + plan tests => 0; +} + +sub verify { + my($ua, $url, $file) = @_; + my $debug = $Apache::TestRequest::DebugLWP; + + $url = Apache::TestRequest::resolve_url($url); + my $req = HTTP::Request->new(GET => $url); + + my $total = 0; + my $chunk_size = 8192; + + my $wanted = -s $file; + + while ($total < $wanted) { + my $end = $total + $chunk_size; + if ($end > $wanted) { + $end = $wanted; + } + + my $t1 = $total+1; + my $t10 = $total+5; + my $e1 = $end-1; + my $e20 = $end-10; + #my $range = "bytes=$total-$end"; + my $range = "bytes=$t10-$end,$total-$e1,$t10-$e20,$total-$e1"; + if ($end - $total < 15) { + # make sure to not send invalid ranges with start > end + $range = "bytes=$total-$end"; + } + $req->header(Range => $range); + + print $req->as_string if $debug; + + my $res = $ua->request($req); + my $content_range = $res->header('Content-Range') || 'NONE'; + + $res->content("") if $debug and $debug == 1; + print $res->as_string if $debug; + + if ($content_range =~ m:^bytes\s+(\d+)-(\d+)/(\d+):) { + my($start, $end, $total_bytes) = ($1, $2, $3); + $total += ($end - $start) + 1; + } + elsif ($total == 0 && $end == $wanted && + $content_range eq 'NONE' && $res->code == 200) { + $total += $wanted; + } + else { + print "Range: $range\n"; + print "Content-Range: $content_range\n"; + last; + } + } + + print "downloaded $total bytes, file is $wanted bytes\n"; + + ok $total == $wanted; +} diff --git a/debian/perl-framework/t/apache/byterange4.t b/debian/perl-framework/t/apache/byterange4.t new file mode 100644 index 0000000..73572d7 --- /dev/null +++ b/debian/perl-framework/t/apache/byterange4.t @@ -0,0 +1,52 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); + +# test byteranges if range boundaries are near bucket boundaries + +my $url = "/apache/chunked/byteranges.txt"; +my $file = Apache::Test::vars('serverroot') . "/htdocs$url"; + +my $content = ""; +$content .= sprintf("%04d", $_) for (1 .. 2000); +my $clen = length($content); + +# make mod_bucketeer create buckets of size 200 from our 4000 bytes +my $blen = 200; +my $B = chr(0x02); +my @buckets = ($content =~ /(.{1,$blen})/g); +my $file_content = join($B, @buckets); +t_write_file($file, $file_content); + + +my @range_boundaries = ( + 0, 1, 2, + $blen-2, $blen-1, $blen, $blen+1, + 3*$blen-2, 3*$blen-1, 3*$blen, 3*$blen+1, + $clen-$blen-2, $clen-$blen-1, $clen-$blen, $clen-$blen+1, + $clen-2, $clen-1, +); +my @test_cases; +for my $start (@range_boundaries) { + for my $end (@range_boundaries) { + push @test_cases, [$start, $end] unless ($end < $start); + } +} + +plan tests => scalar(@test_cases), need need_lwp, + need_module('mod_bucketeer'); + +foreach my $test (@test_cases) { + my ($start, $end) = @$test; + my $r = "$start-$end"; + print "range: $r\n"; + my $result = GET $url, "Range" => "bytes=$r"; + my $expect = substr($content, $start, $end - $start + 1); + my $got = $result->content; + print("rc " . $result->code . "\n"); + print("expect: '$expect'\ngot: '$got'\n"); + ok ($got eq $expect); +} diff --git a/debian/perl-framework/t/apache/byterange5.t b/debian/perl-framework/t/apache/byterange5.t new file mode 100644 index 0000000..d069946 --- /dev/null +++ b/debian/perl-framework/t/apache/byterange5.t @@ -0,0 +1,104 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); + +# test multi-byterange-requests while allowing re-ordering + +my $url = "/apache/chunked/byteranges.txt"; +my $file = Apache::Test::vars('serverroot') . "/htdocs$url"; + +my $content = ""; +$content .= sprintf("%04d", $_) for (1 .. 2000); +t_write_file($file, $content); +my $clen = length($content); + + +my @test_cases = ( + "0-1,1000-1001", + "1000-1100,100-200", + "1000-1100,100-200,2000-2200", + "1000-1100,100-200,2000-", + "3000-,100-200,2000-2200", +); +plan tests => scalar(@test_cases), need need_lwp; + +foreach my $test (@test_cases) { + my $result = GET $url, "Range" => "bytes=$test"; + my $boundary; + my $ctype = $result->header("Content-Type"); + if ($ctype =~ m{multipart/byteranges; boundary=(.*)}) { + $boundary = $1; + } + else { + print "Wrong Content-Type: $ctype\n"; + ok(0); + next; + } + + my @want = split(",", $test); + foreach my $w (@want) { + $w =~ /(\d*)-(\d*)/ or die; + if (defined $1 eq "") { + $w = [ $clen - $2, $clen - 1 ]; + } + elsif ($2 eq "") { + $w = [ $1, $clen - 1 ]; + } + else { + $w = [ $1, $2 ]; + } + } + + my @got; + my $rcontent = $result->content; + my $error; + while ($rcontent =~ s{^[\n\s]*--$boundary\s*?\n(.+?)\r\n\r\n}{}s ) { + my $headers = $1; + my ($from, $to); + if ($headers =~ m{^Content-range: bytes (\d+)-(\d+)/\d*$}mi ) { + $from = $1; + $to = $2; + } + else { + print "Can't parse Content-range in '$headers'\n"; + $error = 1; + } + push @got, [$from, $to]; + my $chunk = substr($rcontent, 0, $to - $from + 1, ""); + my $expect = substr($content, $from, $to - $from + 1); + if ($chunk ne $expect) { + print "Wrong content in range. Got: \n", + $headers, $content, + "Expected:\n$expect\n"; + $error = 1; + } + } + if ($error) { + ok(0); + next; + } + if ($rcontent !~ /^[\s\n]*--${boundary}--[\s\n]*$/) { + print "error parsing final boundary: '$rcontent'\n"; + ok(0); + next; + } + foreach my $w (@want) { + my $found; + foreach my $g (@got) { + $found = 1 if ($g->[0] <= $w->[0] && $g->[1] >= $w->[1]); + } + if (!$found) { + print "Data for '$w->[0]-$w->[1]' not found in response\n"; + $error = 1; + } + } + if ($error) { + ok(0); + next; + } + + ok (1); +} diff --git a/debian/perl-framework/t/apache/byterange6.t b/debian/perl-framework/t/apache/byterange6.t new file mode 100644 index 0000000..5fae418 --- /dev/null +++ b/debian/perl-framework/t/apache/byterange6.t @@ -0,0 +1,162 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file t_debug); + +# test multi-byterange-requests with overlaps (merges) + +my $url = "/apache/chunked/byteranges.txt"; +my $file = Apache::Test::vars('serverroot') . "/htdocs$url"; + +my $content = ""; +$content .= sprintf("%04d", $_) for (1 .. 2000); +t_write_file($file, $content); +my $clen = length($content); + + +my @test_cases = ( + { h => "0-100,70-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-90,70-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-70,70-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "1-100,70-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "1-90,70-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "1-90,70-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "0-100,70-100,1000-1001,5-6", actlike => "0-100,1000-1001,5-6"}, + { h => "0-90,70-100,1000-1001,5-6", actlike => "0-100,1000-1001,5-6"}, + { h => "0-70,70-100,1000-1001,5-6", actlike => "0-100,1000-1001,5-6"}, + { h => "1-100,70-100,1000-1001,5-6", actlike => "1-100,1000-1001,5-6"}, + + { h => "1-90,70-100,1000-1001,5-6", actlike => "1-100,1000-1001,5-6"}, + { h => "1-90,70-100,1000-1001,5-6", actlike => "1-100,1000-1001,5-6"}, + { h => "1-70,70-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "1-70,71-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "1-70,69-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "1-70,0-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "0-70,72-100,1000-1001", actlike => "0-70,72-100,1000-1001"}, + { h => "1-70,0-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "1-70,1-100,1000-1001", actlike => "1-100,1000-1001"}, + { h => "1-70,2-100,1000-1001", actlike => "1-100,1000-1001"}, + + { h => "0-100,0-99,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-100,0-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-100,0-101,1000-1001", actlike => "0-101,1000-1001"}, + { h => "0-100,1-99,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-100,1-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-100,1-101,1000-1001", actlike => "0-101,1000-1001"}, + { h => "0-100,50-99,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-100,50-100,1000-1001", actlike => "0-100,1000-1001"}, + { h => "0-100,50-101,1000-1001", actlike => "0-101,1000-1001"}, + { h => "1-10,1-9,99-99", actlike => "1-10,99-99"}, + + { h => "1-10,1-10,99-99", actlike => "1-10,99-99"}, + { h => "1-10,1-11,99-99", actlike => "1-11,99-99"}, + { h => "1-10,0-9,99-99", actlike => "0-10,99-99"}, + { h => "1-10,0-10,99-99", actlike => "0-10,99-99"}, + { h => "1-10,0-11,99-99", actlike => "0-11,99-99"}, + { h => "1-10,0-12,99-99", actlike => "0-12,99-99"}, + { h => "1-10,0-13,99-99", actlike => "0-13,99-99"}, + { h => "1-10,2-11,99-99", actlike => "1-11,99-99"}, + { h => "1-10,2-12,99-99", actlike => "1-12,99-99"}, + { h => "1-10,2-13,99-99", actlike => "1-13,99-99"}, + + { h => "1-10,1-9,99-99", actlike => "1-10,99-99"}, + { h => "1-11,1-10,99-99", actlike => "1-11,99-99"}, + { h => "1-9,1-10,99-99", actlike => "1-10,99-99"}, + { h => "0-11,1-10,99-99", actlike => "0-11,99-99"}, + { h => "1-9,1-10,99-99", actlike => "1-10,99-99"}, + { h => "10-20,1-9,99-99", actlike => "1-20,99-99"}, + { h => "10-20,1-10,99-99", actlike => "1-20,99-99"}, + { h => "10-20,1-11,99-99", actlike => "1-20,99-99"}, + { h => "10-20,1-21,99-99", actlike => "1-21,99-99"}, + + { h => "5-10,11-12,99-99", actlike => "5-12,99-99"}, + { h => "5-10,1-4,99-99", actlike => "1-10,99-99"}, + { h => "5-10,1-3,99-99", actlike => "5-10,1-3,99-99"}, + + { h => "0-1,-1", actlike => "0-1,-1"}, # PR 51748 + +); +plan tests => scalar(@test_cases), need need_lwp, + need_min_apache_version('2.3.15'); + + +foreach my $test (@test_cases) { + my $result = GET $url, "Range" => "bytes=" . $test->{"h"} ; + my $boundary; + my $ctype = $result->header("Content-Type"); + if ($ctype =~ m{multipart/byteranges; boundary=(.*)}) { + $boundary = $1; + } + else { + print "Wrong Content-Type: $ctype, for ".$test->{"h"}."\n"; + ok(0); + next; + } + + my @want = split(",", $test->{"actlike"}); + foreach my $w (@want) { + $w =~ /(\d*)-(\d*)/ or die; + if ($1 eq "") { + $w = [ $clen - $2, $clen - 1 ]; + } + elsif ($2 eq "") { + $w = [ $1, $clen - 1 ]; + } + else { + $w = [ $1, $2 ]; + } + t_debug("expecting range ". $w->[0]. "-". $w->[1]); + } + + my @got; + my $rcontent = $result->content; + my $error; + while ($rcontent =~ s{^[\n\s]*--$boundary\s*?\n(.+?)\r\n\r\n}{}s ) { + my $headers = $1; + my ($from, $to); + if ($headers =~ m{^Content-range: bytes (\d+)-(\d+)/\d*$}mi ) { + $from = $1; + $to = $2; + } + else { + print "Can't parse Content-range in '$headers'\n"; + $error = 1; + } + push @got, [$from, $to]; + my $chunk = substr($rcontent, 0, $to - $from + 1, ""); + my $expect = substr($content, $from, $to - $from + 1); + if ($chunk ne $expect) { + print "Wrong content in range. Got: \n", + $headers, $content, + "Expected:\n$expect\n"; + $error = 1; + } + } + if ($error) { + ok(0); + next; + } + if ($rcontent !~ /^[\s\n]*--${boundary}--[\s\n]*$/) { + print "error parsing final boundary: '$rcontent'\n"; + ok(0); + next; + } + foreach my $w (@want) { + my $found; + foreach my $g (@got) { + $found = 1 if ($g->[0] <= $w->[0] && $g->[1] >= $w->[1]); + } + if (!$found) { + print "Data for '$w->[0]-$w->[1]' not found in response\n" . $result->content. "\n"; + $error = 1; + } + } + if ($error) { + ok(0); + next; + } + + ok (1); +} diff --git a/debian/perl-framework/t/apache/byterange7.t b/debian/perl-framework/t/apache/byterange7.t new file mode 100644 index 0000000..513dfa9 --- /dev/null +++ b/debian/perl-framework/t/apache/byterange7.t @@ -0,0 +1,119 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); + +# test content-length header in byterange-requests +# test invalid range headers + +my $url = "/apache/chunked/byteranges.txt"; +my $file = Apache::Test::vars('serverroot') . "/htdocs$url"; + +my $content = ""; +$content .= sprintf("%04d", $_) for (1 .. 10000); +t_write_file($file, $content); +my $real_clen = length($content); + + +# +# test cases +# + +# check content-length for (multi-)range responses +my @tc_ranges_cl = ( 1, 2, 10, 50, 100); +# send 200 response if range invalid +my @tc_invalid = ("", ",", "7-1", "foo", "1-4,x", "1-4,5-2", + "100000-110000,5-2"); +# send 416 if no range satisfiable +my %tc_416 = ( + "100000-110000" => 416, + "100000-110000,200000-" => 416, + "1000-200000" => 206, # should be truncated until end + "100000-110000,1000-2000" => 206, # should ignore unsatifiable range + "100000-110000,2000-1000" => 200, # invalid, should ignore whole header + ); + +plan tests => scalar(@tc_ranges_cl) + + 2 * scalar(@tc_invalid) + + scalar(keys %tc_416), + need need_lwp; + +foreach my $num (@tc_ranges_cl) { + my @ranges; + foreach my $i (0 .. ($num-1)) { + push @ranges, sprintf("%d-%d", $i * 100, $i * 100 + 1); + } + my $range = join(",", @ranges); + my $result = GET $url, "Range" => "bytes=$range"; + print_result($result); + if ($result->code != 206) { + print "did not get 206\n"; + ok(0); + next; + } + my $clen = $result->header("Content-Length"); + my $body = $result->content; + my $blen = length($body); + if ($blen == $real_clen) { + print "Did get full content, should have gotten only parts\n"; + ok(0); + next; + } + print "body length $blen\n"; + if (defined $clen) { + print "Content-Length: $clen\n"; + if ($blen != $clen) { + print "Content-Length does not match body\n"; + ok(0); + next; + } + } + ok(1); +} + +# test invalid range headers, with and without "bytes=" +my @tc_invalid2 = map { "bytes=" . $_ } @tc_invalid; +foreach my $range (@tc_invalid, @tc_invalid2) { + my $result = GET $url, "Range" => "$range"; + print_result($result); + my $code = $result->code; + if ($code == 206) { + print "got partial content response with invalid range header '$range'\n"; + ok(0); + } + elsif ($code == 200) { + my $body = $result->content; + if ($body != $content) { + print "Body did not match expected content\n"; + ok(0); + } + ok(1); + } + else { + print "Huh?\n"; + ok(0); + } +} + +# test unsatisfiable ranges headers +foreach my $range (sort keys %tc_416) { + print "Sending '$range', expecting $tc_416{$range}\n"; + my $result = GET $url, "Range" => "bytes=$range"; + print_result($result); + ok($result->code == $tc_416{$range}); +} + +sub print_result +{ + my $result = shift; + my $code = $result->code; + my $cr = $result->header("Content-Range"); + my $ct = $result->header("Content-Type"); + my $msg = "Got $code"; + $msg .= " multipart/byteranges" + if (defined $ct && $ct =~ m{^multipart/byteranges}); + $msg .= " Range: '$cr'" if defined $cr; + print "$msg\n"; +} diff --git a/debian/perl-framework/t/apache/cfg_getline.t b/debian/perl-framework/t/apache/cfg_getline.t new file mode 100644 index 0000000..08f0231 --- /dev/null +++ b/debian/perl-framework/t/apache/cfg_getline.t @@ -0,0 +1,46 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); + +use File::Spec; + +# test ap_cfg_getline / ap_varbuf_cfg_getline + +Apache::TestRequest::user_agent(keep_alive => 1); + +my $dir_foo = Apache::Test::vars('serverroot') . '/htdocs/cfg_getline'; + +# XXX: htaccess is limited to 8190 chars, would need different test +# XXX: method to test longer lines +my @test_cases = (100, 196 .. 202, 396 .. 402 , 596 .. 602 , 1016 .. 1030, + 8170 .. 8190); +plan tests => 2 * scalar(@test_cases), need need_lwp, + need_module('mod_include'), + need_module('mod_setenvif'); + +foreach my $len (@test_cases) { + my $prefix = 'SetEnvIf User-Agent ^ testvar='; + my $expect = 'a' x ($len - length($prefix)); + my $file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'htdocs', + 'apache', 'cfg_getline', '.htaccess'); + t_write_file($file, "$prefix$expect\n"); + + my $response = GET('/apache/cfg_getline/index.shtml'); + my $rc = $response->code; + print "Got rc $rc for length $len\n"; + ok($rc == 200); + + my $got = $response->content; + my $match; + if ($got =~ /^'$expect'/) { + $match = 1; + } + else { + print "Got $got\n", + "expected '$expect'\n"; + } + ok($match); +} diff --git a/debian/perl-framework/t/apache/chunkinput.t b/debian/perl-framework/t/apache/chunkinput.t new file mode 100644 index 0000000..2538585 --- /dev/null +++ b/debian/perl-framework/t/apache/chunkinput.t @@ -0,0 +1,93 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = ("0", + "A\r\n1234567890\r\n0", + "A; ext=val\r\n1234567890\r\n0", + "A \r\n1234567890\r\n0", # <10 BWS + "A :: :: :: \r\n1234567890\r\n0", # <10 BWS multiple send + "A \r\n1234567890\r\n0", # >10 BWS + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n", + "A; ext=\x7Fval\r\n1234567890\r\n0", + " A", + ); +my @req_strings = ("/echo_post_chunk", + "/i_do_not_exist_in_your_wildest_imagination"); + +# This is expanded out as these results... +my @resp_strings = ("HTTP/1.1 200 OK", # "0" + "HTTP/1.1 404 Not Found", + "HTTP/1.1 200 OK", # "A" + "HTTP/1.1 404 Not Found", + "HTTP/1.1 200 OK", # "A; ext=val" + "HTTP/1.1 404 Not Found", + "HTTP/1.1 200 OK", # "A " + "HTTP/1.1 404 Not Found", + "HTTP/1.1 200 OK", # "A " + " " + " " + " " pkts + "HTTP/1.1 404 Not Found", + "HTTP/1.1 400 Bad Request", # >10 BWS + "HTTP/1.1 400 Bad Request", + "HTTP/1.1 413 Request Entity Too Large", # Overflow size + "HTTP/1.1 413 Request Entity Too Large", + "HTTP/1.1 400 Bad Request", # Ctrl in data + "HTTP/1.1 400 Bad Request", + "HTTP/1.1 400 Bad Request", # Invalid LWS + "HTTP/1.1 400 Bad Request", + ); + +my $tests = 4 * @test_strings + 1; +my $vars = Apache::Test::vars(); +my $module = 'default'; +my $cycle = 0; + +plan tests => $tests, ['echo_post_chunk']; + +print "testing $module\n"; + +for my $data (@test_strings) { + for my $request_uri (@req_strings) { + my $sock = Apache::TestRequest::vhost_socket($module); + ok $sock; + + Apache::TestRequest::socket_trace($sock); + + my @elts = split("::", $data); + + $sock->print("POST $request_uri HTTP/1.0\r\n"); + $sock->print("Transfer-Encoding: chunked\r\n"); + $sock->print("\r\n"); + if (@elts > 1) { + for my $elt (@elts) { + $sock->print("$elt"); + sleep 0.5; + } + $sock->print("\r\n"); + } + else { + $sock->print("$data\r\n"); + } + $sock->print("X-Chunk-Trailer: $$\r\n"); + $sock->print("\r\n"); + + #Read the status line + chomp(my $response = Apache::TestRequest::getline($sock)); + $response =~ s/\s$//; + ok t_cmp($response, $resp_strings[$cycle++], "response codes"); + + do { + chomp($response = Apache::TestRequest::getline($sock)); + $response =~ s/\s$//; + } + while ($response ne ""); + + if ($cycle == 1) { + $response = Apache::TestRequest::getline($sock); + chomp($response) if (defined($response)); + ok t_cmp($response, "$$", "trailer (pid)"); + } + } +} diff --git a/debian/perl-framework/t/apache/contentlength.t b/debian/perl-framework/t/apache/contentlength.t new file mode 100644 index 0000000..f141990 --- /dev/null +++ b/debian/perl-framework/t/apache/contentlength.t @@ -0,0 +1,83 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = ("", + "0", + "0000000000000000000000000000000000", + "1000000000000000000000000000000000", + "-1", + "123abc", + ); +my @req_strings = ("/echo_post", + "/i_do_not_exist_in_your_wildest_imagination"); + +my $resp_failure; +if (have_min_apache_version('2.2.30') + && (!have_min_apache_version('2.3.0') + || have_min_apache_version('2.4.14'))) { + $resp_failure = "HTTP/1.1 400 Bad Request"; +} +else { + $resp_failure = "HTTP/1.1 413 Request Entity Too Large"; +} +# This is expanded out. +my @resp_strings = ($resp_failure, + $resp_failure, + "HTTP/1.1 200 OK", + "HTTP/1.1 404 Not Found", + "HTTP/1.1 200 OK", + "HTTP/1.1 404 Not Found", + $resp_failure, + $resp_failure, + $resp_failure, + $resp_failure, + $resp_failure, + $resp_failure, + ); + +my $tests = 4 * @test_strings; +my $vars = Apache::Test::vars(); +my $module = 'default'; +my $cycle = 0; + +plan tests => $tests, ['eat_post']; + +print "testing $module\n"; + +for my $data (@test_strings) { + for my $request_uri (@req_strings) { + my $sock = Apache::TestRequest::vhost_socket($module); + ok $sock; + + Apache::TestRequest::socket_trace($sock); + + $sock->print("POST $request_uri HTTP/1.0\r\n"); + $sock->print("Content-Length: $data\r\n"); + $sock->print("\r\n"); + $sock->print("\r\n"); + + # Read the status line + chomp(my $response = Apache::TestRequest::getline($sock) || ''); + $response =~ s/\s$//; + + # Tests with empty content-length have platform-specific behaviour + # until 2.1.0. + skip + $data eq "" && !have_min_apache_version('2.1.0') ? + "skipping tests with empty C-L for httpd < 2.1.0" : 0, + t_cmp($response, $resp_strings[$cycle], + "response codes POST for $request_uri with Content-Length: $data"); + + $cycle++; + + do { + chomp($response = Apache::TestRequest::getline($sock) || ''); + $response =~ s/\s$//; + } + while ($response ne ""); + } +} diff --git a/debian/perl-framework/t/apache/errordoc.t b/debian/perl-framework/t/apache/errordoc.t new file mode 100644 index 0000000..405924b --- /dev/null +++ b/debian/perl-framework/t/apache/errordoc.t @@ -0,0 +1,108 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +Apache::TestRequest::module('error_document'); + +plan tests => 14, need_lwp; + +# basic ErrorDocument tests + +{ + my $response = GET '/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + 'notfound.html code'); + + ok t_cmp($content, + qr'per-server 404', + 'notfound.html content'); +} + +{ + my $response = GET '/inherit/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + '/inherit/notfound.html code'); + + ok t_cmp($content, + qr'per-server 404', + '/inherit/notfound.html content'); +} + +{ + my $response = GET '/redefine/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + '/redefine/notfound.html code'); + + ok t_cmp($content, + 'per-dir 404', + '/redefine/notfound.html content'); +} + +{ + my $response = GET '/restore/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + '/redefine/notfound.html code'); + + # 1.3 requires quotes for hard-coded messages + my $expected = have_min_apache_version('2.0.51') ? qr/Not Found/ : + have_apache(2) ? 'default' : + qr/Additionally, a 500/; + + ok t_cmp($content, + $expected, + '/redefine/notfound.html content'); +} + +{ + my $response = GET '/apache/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + '/merge/notfound.html code'); + + ok t_cmp($content, + 'testing merge', + '/merge/notfound.html content'); +} + +{ + my $response = GET '/apache/etag/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + '/merge/merge2/notfound.html code'); + + ok t_cmp($content, + 'testing merge', + '/merge/merge2/notfound.html content'); +} + +{ + my $response = GET '/bounce/notfound.html'; + chomp(my $content = $response->content); + + ok t_cmp($response->code, + 404, + '/bounce/notfound.html code'); + + ok t_cmp($content, + qr!expire test!, + '/bounce/notfound.html content'); +} diff --git a/debian/perl-framework/t/apache/etags.t b/debian/perl-framework/t/apache/etags.t new file mode 100644 index 0000000..6618a88 --- /dev/null +++ b/debian/perl-framework/t/apache/etags.t @@ -0,0 +1,170 @@ +# +# Test the FileETag directive. +# +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +t_debug "Checking for existence of FileETag directive\n"; +my $resp = GET('/apache/etags/test.txt'); +my $rc = $resp->code; +t_debug "Returned $rc:"; +if ($rc == 500) { + t_debug "Feature not supported, skipping..", + " Message was:", $resp->as_string; + if (defined($resp->content)) { + t_debug $resp->content; + } + plan tests => 1..0; + exit; +} + +# +# The tests verify the inclusion of the different fields, and +# inheritance, according to the directories involved. All are +# subdirectories under /apache/etags/. The key is the path, the value +# is the pattern the ETag response header field needs to match, +# and the comment is the keywords on the FileETag directive in +# the directory's .htaccess file. A pattern of "" means the header +# field is expected to be absent. +# +# The things we want to test are: +# +# 1. That the 'All' and 'None' keywords work. +# 2. That the 'MTime', 'INode', and 'Size' keywords work, +# alone and in combination. +# 3. That '+MTime', '+INode', and '+Size' work, alone and +# in combination. +# 4. That '-MTime', '-INode', and '-Size' work, alone and +# in combination. +# 5. That relative keywords work in combination with non-relative +# ones. +# 6. That inheritance works properly. +# +my $x = '[0-9a-fA-F]+'; +my $tokens_1 = "^\"$x\"\$"; +my $tokens_2 = "^\"$x-$x\"\$"; +my $tokens_3 = "^\"$x-$x-$x\"\$"; +my %expect = ($tokens_1 => "one component in ETag field", + $tokens_2 => "two components in ETag field", + $tokens_3 => "three components in ETag field", + "" => "field to be absent" + ); +my $tokens_default = have_min_apache_version("2.3.15") ? $tokens_2 : $tokens_3; +my %tests = ( + '/default/' => $tokens_default, + # + # First, the absolute settings in various combinations, + # disregarding inheritance. + # + '/m/' => $tokens_1, # MTime + '/i/' => $tokens_1, # INode + '/s/' => $tokens_1, # Size + '/mi/' => $tokens_2, # MTime INode + '/ms/' => $tokens_2, # MTime Size + '/is/' => $tokens_2, # INode Size + '/mis/' => $tokens_3, # MTime INode Size + '/all/' => $tokens_3, # All + '/none/' => "", # None + '/all/m/' => $tokens_1, # MTime + '/all/i/' => $tokens_1, # INode + '/all/s/' => $tokens_1, # Size + '/all/mi/' => $tokens_2, # MTime INode + '/all/ms/' => $tokens_2, # MTime Size + '/all/is/' => $tokens_2, # INode Size + '/all/mis/' => $tokens_3, # MTime INode Size + '/all/inherit/' => $tokens_3, # no directive + '/none/m/' => $tokens_1, # MTime + '/none/i/' => $tokens_1, # INode + '/none/s/' => $tokens_1, # Size + '/none/mi/' => $tokens_2, # MTime INode + '/none/ms/' => $tokens_2, # MTime Size + '/none/is/' => $tokens_2, # INode Size + '/none/mis/' => $tokens_3, # MTime INode Size + '/none/inherit/' => "", # no directive + # + # Now for the relative keywords. First, subtract fields + # in a place where they all should have been inherited. + # + '/all/minus-m/' => $tokens_2, # -MTime + '/all/minus-i/' => $tokens_2, # -INode + '/all/minus-s/' => $tokens_2, # -Size + '/all/minus-mi/' => $tokens_1, # -MTime -INode + '/all/minus-ms/' => $tokens_1, # -MTime -Size + '/all/minus-is/' => $tokens_1, # -INode -Size + '/all/minus-mis/' => "", # -MTime -INode -Size + # + # Now add them in a location where they should all be absent. + # + '/none/plus-m/' => $tokens_1, # +MTime + '/none/plus-i/' => $tokens_1, # +INode + '/none/plus-s/' => $tokens_1, # +Size + '/none/plus-mi/' => $tokens_2, # +MTime +INode + '/none/plus-ms/' => $tokens_2, # +MTime +Size + '/none/plus-is/' => $tokens_2, # +INode +Size + '/none/plus-mis/' => $tokens_3, # +MTime +INode +Size + # + # Try subtracting them below where they were added. + # + '/none/plus-mis/minus-m/' => $tokens_2, # -MTime + '/none/plus-mis/minus-i/' => $tokens_2, # -INode + '/none/plus-mis/minus-s/' => $tokens_2, # -Size + '/none/plus-mis/minus-mi/' => $tokens_1, # -MTime -INode + '/none/plus-mis/minus-ms/' => $tokens_1, # -MTime -Size + '/none/plus-mis/minus-is/' => $tokens_1, # -INode -Size + '/none/plus-mis/minus-mis/' => "", # -MTime -INode -Size + # + # Now relative settings under a non-All non-None absolute + # setting location. + # + '/m/plus-m/' => $tokens_1, # +MTime + '/m/plus-i/' => $tokens_2, # +INode + '/m/plus-s/' => $tokens_2, # +Size + '/m/plus-mi/' => $tokens_2, # +MTime +INode + '/m/plus-ms/' => $tokens_2, # +MTime +Size + '/m/plus-is/' => $tokens_3, # +INode +Size + '/m/plus-mis/' => $tokens_3, # +MTime +INode +Size + '/m/minus-m/' => "", # -MTime + '/m/minus-i/' => "", # -INode + '/m/minus-s/' => "", # -Size + '/m/minus-mi/' => "", # -MTime -INode + '/m/minus-ms/' => "", # -MTime -Size + '/m/minus-is/' => "", # -INode -Size + '/m/minus-mis/' => "" # -MTime -INode -Size + ); + +my $testcount = scalar(keys(%tests)); +plan tests => $testcount; + +for my $key (keys(%tests)) { + my $uri = "/apache/etags" . $key . "test.txt"; + my $pattern = $tests{$key}; + t_debug "---", "HEAD $uri", + "Expecting " . $expect{$pattern}; + $resp = HEAD($uri); + my $etag = $resp->header("ETag"); + if (defined($etag)) { + t_debug "Received $etag"; + ok ($etag =~ /$pattern/); + } + else { + t_debug "ETag field is missing"; + if ($tests{$key} eq "") { + ok 1; + } + else { + t_debug "ETag field was expected"; + ok 0; + } + } +} + +# +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# End: +# diff --git a/debian/perl-framework/t/apache/expr.t b/debian/perl-framework/t/apache/expr.t new file mode 100644 index 0000000..7d62bc0 --- /dev/null +++ b/debian/perl-framework/t/apache/expr.t @@ -0,0 +1,327 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file t_start_error_log_watch t_finish_error_log_watch); + +use File::Spec; + +# test ap_expr + +Apache::TestRequest::user_agent(keep_alive => 1); + +my $file_foo = Apache::Test::vars('serverroot') . '/htdocs/expr/index.html'; +my $dir_foo = Apache::Test::vars('serverroot') . '/htdocs/expr'; +my $file_notexist = Apache::Test::vars('serverroot') . '/htdocs/expr/none'; +my $file_zero = Apache::Test::vars('serverroot') . '/htdocs/expr/zero'; +my $url_foo = '/apache/'; +my $url_notexist = '/apache/expr/none'; +my @test_cases = ( + [ 'true' => 1 ], + [ 'false' => 0 ], + [ 'foo' => undef ], + # integer comparison + [ '1 -eq 01' => 1 ], + [ '1 -eq 2' => 0 ], + [ '1 -ne 2' => 1 ], + [ '1 -ne 1' => 0 ], + [ '1 -lt 02' => 1 ], + [ '1 -lt 1' => 0 ], + [ '1 -le 2' => 1 ], + [ '1 -le 1' => 1 ], + [ '2 -gt 1' => 1 ], + [ '1 -gt 1' => 0 ], + [ '2 -ge 1' => 1 ], + [ '1 -ge 1' => 1 ], + [ '1 -gt -1' => 1 ], + # string comparison + [ q{'aa' == 'aa'} => 1 ], + [ q{'aa' == 'b'} => 0 ], + [ q{'aa' = 'aa'} => 1 ], + [ q{'aa' = 'b'} => 0 ], + [ q{'aa' != 'b'} => 1 ], + [ q{'aa' != 'aa'} => 0 ], + [ q{'aa' < 'b'} => 1 ], + [ q{'aa' < 'aa'} => 0 ], + [ q{'aa' <= 'b'} => 1 ], + [ q{'aa' <= 'aa'} => 1 ], + [ q{'b' > 'aa'} => 1 ], + [ q{'aa' > 'aa'} => 0 ], + [ q{'b' >= 'aa'} => 1 ], + [ q{'aa' >= 'aa'} => 1 ], + # string operations/whitespace handling + [ q{'a' . 'b' . 'c' = 'abc'} => 1 ], + [ q{'a' .'b'. 'c' = 'abc'} => 1 ], + [ q{ 'a' .'b'. 'c'='abc' } => 1 ], + [ q{'a1c' = 'a'. 1. 'c'} => 1 ], + [ q{req('foo') . 'bar' = 'bar'} => 1 ], + [ q[%{req:foo} . 'bar' = 'bar'] => 1 ], + [ q['x'.%{req:foo} . 'bar' = 'xbar'] => 1 ], + [ q[%{req:User-Agent} . 'bar' != 'bar'] => 1 ], + [ q['%{req:User-Agent}' . 'bar' != 'bar'] => 1 ], + [ q['%{TIME}' . 'bar' != 'bar'] => 1 ], + [ q[%{TIME} != ''] => 1 ], + # string lists + [ q{'a' -in { 'b', 'a' } } => 1 ], + [ q{'a' -in { 'b', 'c' } } => 0 ], + # regexps + [ q[ 'abc' =~ /bc/ ] => 1 ], + [ q[ 'abc' =~ /BC/i ] => 1 ], + [ q[ 'abc' !~ m!bc! ] => 0 ], + [ q[ 'abc' !~ m!BC!i ] => 0 ], + [ q[ $0 == '' ] => 1 ], + [ q[ $1 == '' ] => 1 ], + [ q[ $9 == '' ] => 1 ], + [ q[ '$0' == '' ] => 1 ], + [ q[ 'abc' =~ /(bc)/ && $0 == 'bc' ] => 1 ], + [ q[ 'abc' =~ /(bc)/ && $1 == 'bc' ] => 1 ], + [ q[ 'abc' =~ /b(.)/ && $1 == 'c' ] => 1 ], + # $0 .. $9 are only populated if there are capturing parens + [ q[ 'abc' =~ /bc/ && $0 == '' ] => 1 ], + [ q[ 'abc' =~ /(bc)/ && 'xy' =~ /x/ && $0 == 'bc' ] => 1 ], + # Attempt to blow up when more matches are present than 'typical' $0 .. $9 + [ q[ 'abcdefghijklm' =~ /(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)/ && $2 == 'c' ] => 1 ], + # variables + [ q[%{TIME_YEAR} =~ /^\d{4}$/] => 1 ], + [ q[%{TIME_YEAR} =~ /^\d{3}$/] => 0 ], + [ q[%{TIME_MON} -gt 0 && %{TIME_MON} -le 12 ] => 1 ], + [ q[%{TIME_DAY} -gt 0 && %{TIME_DAY} -le 31 ] => 1 ], + [ q[%{TIME_HOUR} -ge 0 && %{TIME_HOUR} -lt 24 ] => 1 ], + [ q[%{TIME_MIN} -ge 0 && %{TIME_MIN} -lt 60 ] => 1 ], + [ q[%{TIME_SEC} -ge 0 && %{TIME_SEC} -lt 60 ] => 1 ], + [ q[%{TIME} =~ /^\d{14}$/] => 1 ], + [ q[%{API_VERSION} -gt 20101001 ] => 1 ], + [ q[%{REQUEST_METHOD} == 'GET' ] => 1 ], + [ q['x%{REQUEST_METHOD}' == 'xGET' ] => 1 ], + [ q['x%{REQUEST_METHOD}y' == 'xGETy' ] => 1 ], + [ q[%{REQUEST_SCHEME} == 'http' ] => 1 ], + [ q[%{HTTPS} == 'off' ] => 1 ], + [ q[%{REQUEST_URI} == '/apache/expr/index.html' ] => 1 ], + # request headers + [ q[%{req:referer} = 'SomeReferer' ] => 1 ], + [ q[req('Referer') = 'SomeReferer' ] => 1 ], + [ q[http('Referer') = 'SomeReferer' ] => 1 ], + [ q[%{HTTP_REFERER} = 'SomeReferer' ] => 1 ], + [ q[req('User-Agent') = 'SomeAgent' ] => 1 ], + [ q[%{HTTP_USER_AGENT} = 'SomeAgent' ] => 1 ], + [ q[req('SomeHeader') = 'SomeValue' ] => 1 ], + [ q[req('SomeHeader2') = 'SomeValue' ] => 0 ], + # functions + [ q[toupper('abC12d') = 'ABC12D' ] => 1 ], + [ q[tolower('abC12d') = 'abc12d' ] => 1 ], + [ q[escape('?') = '%3f' ] => 1 ], + [ q[unescape('%3f') = '?' ] => 1 ], + [ q[toupper(escape('?')) = '%3F' ] => 1 ], + [ q[tolower(toupper(escape('?'))) = '%3f' ] => 1 ], + [ q[%{toupper:%{escape:?}} = '%3F' ] => 1 ], + [ q[file('] . $file_foo . q[') = 'foo\n' ] => 1 ], + # unary operators + [ q[-n ''] => 0 ], + [ q[-z ''] => 1 ], + [ q[-n '1'] => 1 ], + [ q[-z '1'] => 0 ], + # IP match + [ q[-R 'abc'] => undef ], + [ q[-R %{REMOTE_ADDR}] => undef ], + [ q[-R '240.0.0.0'] => 0 ], + [ q[-R '240.0.0.0/8'] => 0 ], + [ q[-R 'ff::/8'] => 0 ], + [ q[-R '127.0.0.1' || -R '::1'] => 1 ], + [ q['127.0.0.1' -ipmatch 'abc'] => undef ], + [ q['127.0.0.1' -ipmatch %{REMOTE_ADDR}] => undef ], + [ q['127.0.0.1' -ipmatch '240.0.0.0'] => 0 ], + [ q['127.0.0.1' -ipmatch '240.0.0.0/8'] => 0 ], + [ q['127.0.0.1' -ipmatch 'ff::/8'] => 0 ], + [ q['127.0.0.1' -ipmatch '127.0.0.0/8'] => 1 ], + # fn/strmatch + [ q['foo' -strmatch '*o'] => 1 ], + [ q['fo/o' -strmatch 'f*'] => 1 ], + [ q['foo' -strmatch 'F*'] => 0 ], + [ q['foo' -strcmatch 'F*'] => 1 ], + [ q['foo' -strmatch 'g*'] => 0 ], + [ q['foo' -strcmatch 'g*'] => 0 ], + [ q['a/b' -fnmatch 'a*'] => 0 ], + [ q['a/b' -fnmatch 'a/*'] => 1 ], + # error handling + [ q['%{foo:User-Agent}' != 'bar'] => undef ], + [ q[%{foo:User-Agent} != 'bar'] => undef ], + [ q[foo('bar') = 'bar'] => undef ], + [ q[%{FOO} != 'bar'] => undef ], + [ q['bar' = bar] => undef ], +); + +# +# Bool logic: +# Test all combinations with 0 to 2 '||' or '&&' operators +# +my @bool_base = ( + [ q[true] => 1 ], +); +push @bool_base, ( + [ q[-z ''] => 1 ], + [ q[-n 'x'] => 1 ], + [ q[false] => 0 ], + [ q[-n ''] => 0 ], + [ q[-z 'x'] => 0 ], +) if 0; # This produces an exessive number of tests for normal operation + +# negation function: perl's "!" returns undef for false, but we need 0 +sub neg +{ + return (shift) ? 0 : 1; +} +# also test combinations with '!' operator before each operand +@bool_base = (@bool_base, map { ["!$_->[0]" => neg($_->[1]) ] } @bool_base); +# now create the test cases +my @bool_test_cases; +foreach my $ex1 (@bool_base) { + my ($e1, $r1) = @$ex1; + push @bool_test_cases, [ $e1 => $r1 ]; + foreach my $ex2 (@bool_base) { + my ($e2, $r2) = @$ex2; + push @bool_test_cases, [ "$e1 && $e2" => ($r1 && $r2) ]; + push @bool_test_cases, [ "$e1 || $e2" => ($r1 || $r2) ]; + foreach my $ex3 (@bool_base) { + my ($e3, $r3) = @$ex3; + foreach my $op1 ("||", "&&") { + foreach my $op2 ("||", "&&") { + my $r = eval "$r1 $op1 $r2 $op2 $r3"; + push @bool_test_cases, [ "$e1 $op1 $e2 $op2 $e3" => $r]; + } + } + } + } +} +push @test_cases, @bool_test_cases; +# also test combinations with '!' operator before the whole expression +push @test_cases, map { ["!($_->[0])" => neg($_->[1]) ] } @bool_test_cases; + +if (have_min_apache_version("2.3.13")) { + push(@test_cases, ( + # functions + [ q[filesize('] . $file_foo . q[') = 4 ] => 1 ], + [ q[filesize('] . $file_notexist . q[') = 0 ] => 1 ], + [ q[filesize('] . $file_zero . q[') = 0 ] => 1 ], + # unary operators + [ qq[-d '$file_foo' ] => 0 ], + [ qq[-e '$file_foo' ] => 1 ], + [ qq[-f '$file_foo' ] => 1 ], + [ qq[-s '$file_foo' ] => 1 ], + [ qq[-d '$file_zero' ] => 0 ], + [ qq[-e '$file_zero' ] => 1 ], + [ qq[-f '$file_zero' ] => 1 ], + [ qq[-s '$file_zero' ] => 0 ], + [ qq[-d '$dir_foo' ] => 1 ], + [ qq[-e '$dir_foo' ] => 1 ], + [ qq[-f '$dir_foo' ] => 0 ], + [ qq[-s '$dir_foo' ] => 0 ], + [ qq[-d '$file_notexist' ] => 0 ], + [ qq[-e '$file_notexist' ] => 0 ], + [ qq[-f '$file_notexist' ] => 0 ], + [ qq[-s '$file_notexist' ] => 0 ], + [ qq[-F '$file_foo' ] => 1 ], + [ qq[-F '$file_notexist' ] => 0 ], + [ qq[-U '$url_foo' ] => 1 ], + [ qq[-U '$url_notexist' ] => 0 ], + )); +} + +if (have_min_apache_version("2.4.5")) { + push(@test_cases, ( + [ qq[sha1('foo') = '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33' ] => 1 ], + [ qq[md5('foo') = 'acbd18db4cc2f85cedef654fccc4a4d8' ] => 1 ], + [ qq[base64('foo') = 'Zm9v' ] => 1 ], + [ qq[unbase64('Zm9vMg==') = 'foo2' ] => 1 ], + )); +} + +if (have_min_apache_version("2.5")) { + my $SAN_one = "email:<redacted1>, email:<redacted2>, " . + "IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, " . + "IP Address:192.168.169.170"; + my $SAN_tuple = "'email:<redacted1>', 'email:<redacted2>', " . + "'IP Address:127.0.0.1', 'IP Address:0:0:0:0:0:0:0:1', " . + "'IP Address:192.168.169.170'"; + my $SAN_list_one = "{ '$SAN_one' }"; + my $SAN_list_tuple = "{ $SAN_tuple }"; + + my $SAN_split = '.*?IP Address:([^,]+)'; + + push(@test_cases, ( + [ "join {'a', 'b', 'c'} == 'abc'" => 1 ], + [ "join($SAN_list_tuple, ', ') == " . + "'email:<redacted1>, email:<redacted2>, " . + "IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, " . + "IP Address:192.168.169.170'" => 1 ], + [ "join($SAN_list_tuple, ', ') == join $SAN_list_one" => 1 ], + [ "join(split(s/$SAN_split/\$1/, $SAN_list_tuple), ', ') == " . + "'email:<redacted1>, email:<redacted2>, " . + "127.0.0.1, 0:0:0:0:0:0:0:1, 192.168.169.170'" => 1 ], + [ "join(split(s/$SAN_split/\$1/, $SAN_list_one), ', ') == " . + "'127.0.0.1, 0:0:0:0:0:0:0:1, 192.168.169.170'" => 1 ], + [ "'IP Address:192.168.169.170' -in $SAN_list_tuple" => 1 ], + [ "'192.168.169.170' -in split s/$SAN_split/\$1/, $SAN_list_tuple" => 1 ], + [ "'0:0:0:0:0:0:0:1' -in split s/$SAN_split/\$1/, $SAN_list_one" => 1 ], + [ "%{REMOTE_ADDR} -in split s/$SAN_split/\$1/, $SAN_list_one" => 1 ], + [ "'email:<redacted1>' -in split s/$SAN_split/\$1/, $SAN_list_tuple" => 1 ], + [ "'email:<redacted2>' -in split s/$SAN_split/\$1/, $SAN_list_one" => 0 ], + [ "'IP Address:%{REMOTE_ADDR}' -in split/, /, join $SAN_list_one" + => 1 ], + [ "replace(%{REQUEST_METHOD}, 'E', 'O') == 'GOT'" => 1], + [ "replace(%{REQUEST_METHOD}, 'E', 'O') == 'GET'" => 0], + )); +} + +plan tests => scalar(@test_cases) + 1, + need need_lwp, + need_module('mod_authz_core'), + need_min_apache_version('2.3.9'); + +t_start_error_log_watch(); + +my %rc_map = ( 500 => 'parse error', 403 => 'true', 200 => 'false'); +foreach my $t (@test_cases) { + my ($expr, $expect) = @{$t}; + + write_htaccess($expr); + + my $response = GET('/apache/expr/index.html', + 'SomeHeader' => 'SomeValue', + 'User-Agent' => 'SomeAgent', + 'Referer' => 'SomeReferer'); + my $rc = $response->code; + if (!defined $expect) { + print qq{Should get parse error for "$expr", got $rc_map{$rc}\n}; + ok($rc == 500); + } + elsif ($expect) { + print qq{"$expr" should evaluate to true, got $rc_map{$rc}\n}; + ok($rc == 403); + } + else { + print qq{"$expr" should evaluate to false, got $rc_map{$rc}\n}; + ok($rc == 200); + } +} + +my @loglines = t_finish_error_log_watch(); +my @evalerrors = grep { /internal evaluation error/i } @loglines; +my $num_errors = scalar @evalerrors; +print "Error log should not have 'Internal evaluation error' entries, found $num_errors\n"; +ok($num_errors == 0); + +exit 0; + +### sub routines +sub write_htaccess +{ + my $expr = shift; + my $file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'htdocs', 'apache', 'expr', '.htaccess'); + t_write_file($file, << "EOF" ); +<If "$expr"> + Require all denied +</If> +EOF +} + diff --git a/debian/perl-framework/t/apache/expr_string.t b/debian/perl-framework/t/apache/expr_string.t new file mode 100644 index 0000000..4682d4a --- /dev/null +++ b/debian/perl-framework/t/apache/expr_string.t @@ -0,0 +1,123 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file t_start_error_log_watch t_finish_error_log_watch t_cmp); + +use File::Spec; + +use Time::HiRes qw(usleep); + +# test ap_expr + +Apache::TestRequest::user_agent(keep_alive => 1); + +# The left-hand values are written into the config file as-is, i.e. +# necessary quoting for the config file parser needs to be included +# explicitly. +my @test_cases = ( + [ 'foo' => 'foo' ], + [ '%{req:SomeHeader}' => 'SomeValue' ], + [ '%{' => undef ], + [ '%' => '%' ], + [ '}' => '}' ], + [ q{\"} => q{"} ], + [ q{\'} => q{'} ], + [ q{"\%{req:SomeHeader}"} => '%{req:SomeHeader}' ], + [ '%{tolower:IDENT}' => 'ident' ], + [ '%{tolower:%{REQUEST_METHOD}}' => 'get' ], +); + +if (have_min_apache_version("2.5")) { + my $SAN_one = "email:<redacted1>, email:<redacted2>, " . + "IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, " . + "IP Address:192.168.169.170"; + my $SAN_tuple = "'email:<redacted1>', 'email:<redacted2>', " . + "'IP Address:127.0.0.1', 'IP Address:0:0:0:0:0:0:0:1', " . + "'IP Address:192.168.169.170'"; + my $SAN_list_one = "{ '$SAN_one' }"; + my $SAN_list_tuple = "{ $SAN_tuple }"; + + push(@test_cases, ( + [ qq["%{tolower:%{:toupper(%{REQUEST_METHOD}):}}"] => "get" ], + [ qq["%{: join $SAN_list_one :}"] => "$SAN_one" ], + [ qq["%{: join($SAN_list_tuple, ', ') :}"] => "$SAN_one" ], + [ qq['%{tolower:"IDENT"}'] => '"ident"' ], + [ qq["%{: 'IP Address:%{REMOTE_ADDR}' -in split/, /, join $SAN_list_one :}"] + => "true" ], + )); +} + +my $successful_expected = scalar(grep { defined $_->[1] } @test_cases); + +plan tests => scalar(@test_cases) * 2 + $successful_expected, + need need_lwp, + need_module('mod_log_debug'); +foreach my $t (@test_cases) { + my ($expr, $expect) = @{$t}; + + write_htaccess($expr); + + t_start_error_log_watch(); + my $response = GET('/apache/expr/index.html', + 'SomeHeader' => 'SomeValue', + 'User-Agent' => 'SomeAgent', + 'Referer' => 'SomeReferer'); + ### Sleep here, attempt to avoid intermittent failures. + usleep(250000); + my @loglines = t_finish_error_log_watch(); + + my @evalerrors = grep {/(?:internal evaluation error|flex scanner jammed)/i + } @loglines; + my $num_errors = scalar @evalerrors; + print "Error log should not have 'Internal evaluation error' or " . + "'flex scanner jammed' entries, found $num_errors:\n@evalerrors\n" + if $num_errors; + ok($num_errors == 0); + + my $rc = $response->code; + + if (!defined $expect) { + print qq{Should get parse error (500) for "$expr", got $rc\n}; + ok($rc == 500); + } + else { + print qq{Expected return code 200, got $rc for '$expr'\n}; + ok($rc == 200); + my @msg = grep { /log_debug:info/ } @loglines; + if (scalar @msg != 1) { + print "expected 1 message, got " . scalar @msg . ":\n@msg\n"; + ok(0); + } + elsif ($msg[0] =~ m{^(?:\[ # opening '[' + [^\]]+ # anything but a ']' + \] # closing ']' + [ ] # trailing space + ){4} # repeat 4 times (timestamp, level, pid, client IP) + (.*?) # The actual message logged by LogMessage + (,[ ]referer # either trailing referer (LogLevel info) + | # or + [ ]\(log_transaction) # trailing hook info (LogLevel debug and higher) + }x ) { + my $result = $1; + ok t_cmp($result, $expect, "log message @msg didn't match"); + } + else { + print "Can't extract expr result from log message:\n@msg\n"; + ok(0); + } + } +} + +exit 0; + +### sub routines +sub write_htaccess +{ + my $expr = shift; + my $file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'htdocs', 'apache', 'expr', '.htaccess'); + t_write_file($file, << "EOF" ); +LogMessage $expr +EOF +} diff --git a/debian/perl-framework/t/apache/getfile.t b/debian/perl-framework/t/apache/getfile.t new file mode 100644 index 0000000..3df2faf --- /dev/null +++ b/debian/perl-framework/t/apache/getfile.t @@ -0,0 +1,24 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); +use Apache::TestCommon (); + +Apache::TestCommon::run_files_test(\&verify); + +sub verify { + my($ua, $url, $file) = @_; + + my $flen = -s $file; + my $received = 0; + + $ua->do_request(GET => $url, + sub { + my($chunk, $res) = @_; + $received += length $chunk; + }); + + ok t_cmp($received, $flen, "download of $url"); +} diff --git a/debian/perl-framework/t/apache/headers.t b/debian/perl-framework/t/apache/headers.t new file mode 100644 index 0000000..2412eff --- /dev/null +++ b/debian/perl-framework/t/apache/headers.t @@ -0,0 +1,96 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my %headers; + +my $hasfix = 0; +if (have_min_apache_version("2.4.0")) { + if (have_min_apache_version("2.4.24")) { + $hasfix = 1; + } +} +elsif (have_min_apache_version("2.2.32")) { + $hasfix = 1; +} +if ($hasfix) { + %headers = ( + "Hello:World\r\n" => ["Hello", "World"], + "Hello: World\r\n" => ["Hello", "World"], + "Hello: World \r\n" => ["Hello", "World"], + "Hello: World \t \r\n" => ["Hello", "World"], + "Hello: Foo\r\n Bar\r\n" => ["Hello", "Foo Bar"], + "Hello: Foo\r\n\tBar\r\n" => ["Hello", "Foo Bar"], + "Hello: Foo\r\n Bar\r\n" => ["Hello", "Foo Bar"], + "Hello: Foo \t \r\n Bar\r\n" => ["Hello", "Foo Bar"], + "Hello: Foo\r\n \t Bar\r\n" => ["Hello", "Foo Bar"], + ); +} +else { + %headers = ( + "Hello:World\n" => ["Hello", "World"], + "Hello : World\n" => ["Hello", "World"], + "Hello : World \n" => ["Hello", "World"], + "Hello \t : World \n" => ["Hello", "World"], + "Hello: Foo\n Bar\n" => ["Hello", "Foo Bar"], + "Hello: Foo\n\tBar\n" => ["Hello", "Foo\tBar"], + "Hello: Foo\n Bar\n" => ["Hello", qr/Foo +Bar/], + "Hello: Foo \n Bar\n" => ["Hello", qr/Foo +Bar/], + ); +} + +my $uri = "/modules/cgi/env.pl"; + +plan tests => (scalar keys %headers) * 3, need_cgi; + +foreach my $key (sort keys %headers) { + + print "testing: $key"; + + my $sock = Apache::TestRequest::vhost_socket('default'); + ok $sock; + + Apache::TestRequest::socket_trace($sock); + + $sock->print("GET $uri HTTP/1.0\r\n"); + $sock->print($key); + $sock->print("\r\n"); + + # Read the status line + chomp(my $response = Apache::TestRequest::getline($sock) || ''); + $response =~ s/\s$//; + + ok t_cmp($response, qr{HTTP/1\.. 200 OK}, "response success"); + + my $line; + + do { + chomp($line = Apache::TestRequest::getline($sock) || ''); + $line =~ s/\s$//; + } + while ($line ne ""); + + my $found = 0; + + my ($name, $value) = ($headers{$key}[0], $headers{$key}[1]); + + do { + chomp($line = Apache::TestRequest::getline($sock) || ''); + $line =~ s/\r?\n?$//; + if ($line ne "" && !$found) { + my @part = split(/ = /, $line); + if (@part && $part[0] eq "HTTP_" . uc($name)) { + print "header: [".$part[1]."] vs [".$value."]\n"; + ok t_cmp $part[1], $value, "compare header $name value"; + $found = 1; + } + } + } + while ($line ne ""); + + ok 0 unless $found; +} + diff --git a/debian/perl-framework/t/apache/hostcheck.t b/debian/perl-framework/t/apache/hostcheck.t new file mode 100644 index 0000000..b9e11aa --- /dev/null +++ b/debian/perl-framework/t/apache/hostcheck.t @@ -0,0 +1,113 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use MIME::Base64; +use Data::Dumper; +use HTTP::Response; +use Socket; + +# undef: HTTPD should drop connection without error message + +my @test_cases = ( + # request, status code global, status code strict VH, msg + [ "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" => 200, 400, "ok"], + [ "GET / HTTP/1.1\r\nHost: localhost:1\r\n\r\n" => 200, 400, "port ignored"], + [ "GET / HTTP/1.1\r\nHost: notlisted\r\n\r\n" => 200, 400, "name not listed"], + [ "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n" => 200, 400, "IP not in serveralias/servername"], + [ "GET / HTTP/1.1\r\nHost: default-strict\r\n\r\n" => 200, 200, "NVH matches in default server"], + [ "GET / HTTP/1.1\r\nHost: nvh-strict\r\n\r\n" => 200, 200, "NVH matches"], + [ "GET / HTTP/1.1\r\nHost: nvh-strict:1\r\n\r\n" => 200, 200, "NVH matches port ignored"], +); +plan tests => scalar(@test_cases) * 2, need_min_apache_version('2.5.1'); + + +foreach my $vhosts ((["default" => 1], ["core" => 2])) { + my $vhost = $vhosts->[0]; + my $expect_column = $vhosts->[1]; + + foreach my $t (@test_cases) { + my $req = $t->[0]; + my $expect = $t->[$expect_column]; + my $desc = $t->[3]; + my $decoded; + + my $sock = Apache::TestRequest::vhost_socket($vhost); + if (!$sock) { + print "# failed to connect\n"; + ok(0); + next; + } + + print "# SENDING to " . peer($sock) . "\n# $req\n"; + $sock->print($req); + $sock->shutdown(1); + $req = escape($req); + + my $response_data = ""; + my $buf; + while ($sock->read($buf, 10000) > 0) { + $response_data .= $buf; + } + my $response = HTTP::Response->parse($response_data); + if ($decoded) { + $response_data =~ s/<title>.*/.../s; + my $out = escape($response_data); + $out =~ s{\\n}{\\n\n# }g; + print "# RESPONSE:\n# $out\n"; + } + if (! defined $response) { + die "HTTP::Response->parse failed"; + } + my $rc = $response->code; + if (! defined $rc) { + if (! defined $expect) { + print "# expecting dropped connection and HTTPD dropped connection\n"; + ok(1); + } + else { + print "# expecting $expect, but HTTPD dropped the connection\n"; + ok(0); + } + } + elsif ($expect > 100) { + print "# expected $expect, got " . $response->code . " for $desc\n"; + ok ($response->code, $expect, $desc ); + } + elsif ($expect == 90) { + print "# expecting headerless HTTP/0.9 body, got response\n"; + ok (1); + } + elsif ($expect) { + print "# expecting success, got ", $rc, ": $desc\n"; + ok ($rc >= 200 && $rc < 400); + } + else { + print "# expecting error, got ", $rc, ": $desc\n"; + ok ($rc >= 400); + } + } +} + +sub escape +{ + my $in = shift; + $in =~ s{\\}{\\\\}g; + $in =~ s{\r}{\\r}g; + $in =~ s{\n}{\\n}g; + $in =~ s{\t}{\\t}g; + $in =~ s{([\x00-\x1f])}{sprintf("\\x%02x", ord($1))}ge; + return $in; +} + +sub peer +{ + my $sock = shift; + my $hersockaddr = getpeername($sock); + my ($port, $iaddr) = sockaddr_in($hersockaddr); + my $herhostname = gethostbyaddr($iaddr, AF_INET); + my $herstraddr = inet_ntoa($iaddr); + return "$herstraddr:$port"; +} diff --git a/debian/perl-framework/t/apache/http_strict.t b/debian/perl-framework/t/apache/http_strict.t new file mode 100644 index 0000000..2434fc3 --- /dev/null +++ b/debian/perl-framework/t/apache/http_strict.t @@ -0,0 +1,243 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use MIME::Base64; +use Data::Dumper; +use HTTP::Response; + + +my $test_underscore = defined(&need_min_apache_fix) ? + need_min_apache_fix("2.4.34", "2.5.1") : + need_min_apache_version('2.4.34'); + +# possible expected results: +# 0: any HTTP error +# 1: any HTTP success +# 200-500: specific HTTP status code +# undef: HTTPD should drop connection without error message + +my @test_cases = ( + [ "GET / HTTP/1.0\r\n\r\n" => 1], + [ "GET / HTTP/1.0\n\n" => 1, 400], + [ "get / HTTP/1.0\r\n\r\n" => 501], + [ "G ET / HTTP/1.0\r\n\r\n" => 400], + [ "G\0ET / HTTP/1.0\r\n\r\n" => 400], + [ "G/T / HTTP/1.0\r\n\r\n" => 501, 400], + [ "GET /\0 HTTP/1.0\r\n\r\n" => 400], + [ "GET / HTTP/1.0\0\r\n\r\n" => 400], + [ "GET\f/ HTTP/1.0\r\n\r\n" => 400], + [ "GET\r/ HTTP/1.0\r\n\r\n" => 400], + [ "GET\t/ HTTP/1.0\r\n\r\n" => 400], + [ "GET / HTT/1.0\r\n\r\n" => 0], + [ "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n" => 1], + [ "GET / HTTP/2.0\r\nHost: localhost\r\n\r\n" => 1], + [ "GET / HTTP/1.2\r\nHost: localhost\r\n\r\n" => 1], + [ "GET / HTTP/1.11\r\nHost: localhost\r\n\r\n" => 400], + [ "GET / HTTP/10.0\r\nHost: localhost\r\n\r\n" => 400], + [ "GET / HTTP/1.0 \r\nHost: localhost\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0 x\r\nHost: localhost\r\n\r\n" => 400], + [ "GET / HTTP/\r\nHost: localhost\r\n\r\n" => 0], + [ "GET / HTTP/0.9\r\n\r\n" => 0], + [ "GET / HTTP/0.8\r\n\r\n" => 0], + [ "GET /\x01 HTTP/1.0\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nFoo: bar\r\n\r\n" => 200], + [ "GET / HTTP/1.0\r\nFoo:bar\r\n\r\n" => 200], + [ "GET / HTTP/1.0\r\nFoo: b\0ar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nFoo: b\x01ar\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0\r\nFoo\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nFoo bar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\n: bar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nX: bar\r\n\r\n" => 200], + [ "GET / HTTP/1.0\r\nFoo bar:bash\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nFoo :bar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\n Foo:bar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nF\x01o: bar\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0\r\nF\ro: bar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nF\to: bar\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nFo: b\tar\r\n\r\n" => 200], + [ "GET / HTTP/1.0\r\nFo: bar\r\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\r" => undef, undef], + [ "GET /\r\n" => 90, undef], + [ "GET /#frag HTTP/1.0\r\n" => 400], + [ "GET / HTTP/1.0\r\nHost: localhost\r\n" . + "Host: localhost\r\n\r\n" => 200, 400], + [ "GET http://017700000001/ HTTP/1.0\r\n\r\n" => 200, 400], + [ "GET http://0x7f.1/ HTTP/1.0\r\n\r\n" => 200, 400], + [ "GET http://127.0.0.1/ HTTP/1.0\r\n\r\n" => 200], + [ "GET http://127.01.0.1/ HTTP/1.0\r\n\r\n" => 200, 400], + [ "GET http://%3127.0.0.1/ HTTP/1.0\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0\r\nHost: localhost:80\r\n" . + "Host: localhost:80\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0\r\nHost: localhost:80 x\r\n\r" => 400], + [ "GET http://localhost:80/ HTTP/1.0\r\n\r\n" => 200], + [ "GET http://localhost:80x/ HTTP/1.0\r\n\r\n" => 400], + [ "GET http://localhost:80:80/ HTTP/1.0\r\n\r\n" => 400], + [ "GET http://localhost::80/ HTTP/1.0\r\n\r\n" => 400], + [ "GET http://foo\@localhost:80/ HTTP/1.0\r\n\r\n" => 200, 400], + [ "GET http://[::1]/ HTTP/1.0\r\n\r\n" => 1], + [ "GET http://[::1:2]/ HTTP/1.0\r\n\r\n" => 1], + [ "GET http://[4712::abcd]/ HTTP/1.0\r\n\r\n" => 1], + [ "GET http://[4712::abcd:1]/ HTTP/1.0\r\n\r\n" => 1], + [ "GET http://[4712::abcd::]/ HTTP/1.0\r\n\r\n" => 400], + [ "GET http://[4712:abcd::]/ HTTP/1.0\r\n\r\n" => 1], + [ "GET http://[4712::abcd]:8000/ HTTP/1.0\r\n\r\n" => 1], + [ "GET http://4713::abcd:8001/ HTTP/1.0\r\n\r\n" => 400], + [ "GET / HTTP/1.0\r\nHost: [::1]\r\n\r\n" => 1], + [ "GET / HTTP/1.0\r\nHost: [::1:2]\r\n\r\n" => 1], + [ "GET / HTTP/1.0\r\nHost: [4711::abcd]\r\n\r\n" => 1], + [ "GET / HTTP/1.0\r\nHost: [4711::abcd:1]\r\n\r\n" => 1], + [ "GET / HTTP/1.0\r\nHost: [4711:abcd::]\r\n\r\n" => 1], + [ "GET / HTTP/1.0\r\nHost: [4711::abcd]:8000\r\n\r\n" => 1], + [ "GET / HTTP/1.0\r\nHost: 4714::abcd:8001\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0\r\nHost: abc\xa0\r\n\r\n" => 200, 400], + [ "GET / HTTP/1.0\r\nHost: abc\\foo\r\n\r\n" => 400], + [ "GET http://foo/ HTTP/1.0\r\nHost: bar\r\n\r\n" => 200], + [ "GET http://foo:81/ HTTP/1.0\r\nHost: bar\r\n\r\n" => 200], + [ "GET http://[::1]:81/ HTTP/1.0\r\nHost: bar\r\n\r\n" => 200], + [ "GET http://10.0.0.1:81/ HTTP/1.0\r\nHost: bar\r\n\r\n" => 200], + [ "GET / HTTP/1.0\r\nHost: foo-bar.example.com\r\n\r\n" => 200], + [ "GET / HTTP/1.0\r\nHost: foo_bar.example.com\r\n\r\n" => 200, 200, $test_underscore], + [ "GET http://foo_bar/ HTTP/1.0\r\n\r\n" => 200, 200, $test_underscore], + + # + # tests for response headers + # + # Everything after the leading "R" will be sent encoded + # to .../send_hdr.pl which will decode it and include it + # in the response headers. + [ "R" . "Foo: bar" => 200 ], + [ "R" . "Foo:" => 200 ], + [ "R" . ": bar" => 500 ], + [ "R" . "F\0oo: bar" => 500 ], + [ "R" . "F\x01oo: bar" => 500 ], + [ "R" . "F\noo: bar" => 500 ], + [ "R" . "Foo: b\tar" => 200 ], + [ "R" . "Foo: b\x01ar" => 500 ], + # XXX ap_scan_script_header() eats the \r + #[ "R" . "F\roo: bar" => 500 ], + #[ "R" . "Foo: bar\rBaz: h" => 500 ], + + # + # implementation regression tests + # + # `Header always set <bad value>` followed by a <bad field name> + # should not cause a recursion loop + [ "GET /regression-header HTTP/1.1\r\nHost:localhost\r\n\r\n" => 500, 500, + have_module qw(mod_headers) ], +); + +my $test_fold = defined(&need_min_apache_fix) ? + need_min_apache_fix("2.2.33", "2.4.26", "2.5.0") : + need_min_apache_version('2.4.26'); + +plan tests => scalar(@test_cases) * 2 + $test_fold * 2, + need_min_apache_version('2.2.32'); + +foreach my $vhosts ((["http_unsafe" => 1], ["http_strict" => 2])) { + my $vhost = $vhosts->[0]; + my $expect_column = $vhosts->[1]; + + foreach my $t (@test_cases) { + my $req = $t->[0]; + my $expect = $t->[$expect_column]; + $expect = $t->[1] if (! defined $expect); + my $cond = $t->[3]; + my $decoded; + + if ($req =~ s/^R//) { + if (!have_cgi) { + skip "Skipping test without CGI module"; + next; + } + $decoded = $req; + my $q = encode_base64($decoded); + chomp $q; + $req = "GET /apache/http_strict/send_hdr.pl?$q HTTP/1.0\r\n\r\n"; + } + + if (defined $cond && not $cond) { + $req = escape($req); + print "# SKIPPING:\n# $req\n"; + skip "Test prerequisites are not met"; + next; + } + + my $sock = Apache::TestRequest::vhost_socket($vhost); + if (!$sock) { + print "# failed to connect\n"; + ok(0); + next; + } + $sock->print($req); + $sock->shutdown(1); + sleep(0.1); + $req = escape($req); + print "# SENDING:\n# $req\n"; + print "# DECODED: " . escape($decoded) . "\n" if $decoded; + + my $response_data = ""; + my $buf; + while ($sock->read($buf, 10000) > 0) { + $response_data .= $buf; + } + my $response = HTTP::Response->parse($response_data); + if ($decoded) { + $response_data =~ s/<title>.*/.../s; + my $out = escape($response_data); + $out =~ s{\\n}{\\n\n# }g; + print "# RESPONSE:\n# $out\n"; + } + if (! defined $response) { + die "HTTP::Response->parse failed"; + } + my $rc = $response->code; + if (! defined $rc) { + if (! defined $expect) { + print "# expecting dropped connection and HTTPD dropped connection\n"; + ok(1); + } + else { + print "# expecting $expect, but HTTPD dropped the connection\n"; + ok(0); + } + } + elsif ($expect > 100) { + print "# expecting $expect, got ", $rc, "\n"; + ok ($response->code == $expect); + } + elsif ($expect == 90) { + print "# expecting headerless HTTP/0.9 body, got response\n"; + ok (1); + } + elsif ($expect) { + print "# expecting success, got ", $rc, "\n"; + ok ($rc >= 200 && $rc < 400); + } + else { + print "# expecting error, got ", $rc, "\n"; + ok ($rc >= 400); + } + } +} + +if ($test_fold) { + my $resp; + my $foo; + $resp = GET("/fold"); + $foo = $resp->header("Foo"); + ok ($resp->code == 200); + ok (defined($foo) && $foo =~ /Bar Baz/); +} + +sub escape +{ + my $in = shift; + $in =~ s{\\}{\\\\}g; + $in =~ s{\r}{\\r}g; + $in =~ s{\n}{\\n}g; + $in =~ s{\t}{\\t}g; + $in =~ s{([\x00-\x1f])}{sprintf("\\x%02x", ord($1))}ge; + return $in; +} diff --git a/debian/perl-framework/t/apache/if_sections.t b/debian/perl-framework/t/apache/if_sections.t new file mode 100644 index 0000000..12d591a --- /dev/null +++ b/debian/perl-framework/t/apache/if_sections.t @@ -0,0 +1,76 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +# +# Test <If > section merging +# + +plan tests => (have_min_apache_version('2.4.26') ? 23 : 11) * 2, + need need_lwp, + need_module('mod_headers'), + need_module('mod_proxy'), + need_module('mod_proxy_http'), + need_min_apache_version('2.3.8'); + + +sub do_test +{ + my $url = shift; + my $set = shift; + my $expect = shift; + + $url = "/if_sec$url"; + + my @headers_to_set = split(/\s+/, $set); + my @headers = map { ("In-If$_" => 1) } @headers_to_set; + + my $response = GET($url, @headers); + print "# $url with '$set':\n"; + ok t_cmp($response->code, 200); + ok t_cmp($response->header("Out-Trace"), $expect); +} + +do_test('/', '', undef); +do_test('/foo.if_test', '', undef); +do_test('/foo.if_test', '1', 'global1'); + +if (have_min_apache_version('2.4.26')) { + do_test('/foo.if_test', '1 11', 'global1, nested11, nested113'); + do_test('/foo.if_test', '1 11 111', 'global1, nested11, nested111'); + do_test('/foo.if_test', '1 11 112', 'global1, nested11, nested112'); +} + +do_test('/foo.if_test', '1 2', 'global1, files2'); +do_test('/dir/foo.txt', '1 2', 'global1, dir1, dir2, dir_files1'); +do_test('/dir/', '1 2', 'global1, dir1, dir2'); + +if (have_min_apache_version('2.4.26')) { + do_test('/dir/', '1 11', 'global1, dir1, nested11, nested113'); + do_test('/dir/', '1 11 111', 'global1, dir1, nested11, nested111'); + do_test('/dir/', '1 11 112', 'global1, dir1, nested11, nested112'); +} + +do_test('/loc/', '1 2', 'global1, loc1, loc2'); +do_test('/loc/foo.txt', '1 2', 'global1, loc1, loc2'); + +if (have_min_apache_version('2.4.26')) { + do_test('/loc/', '1 11', 'global1, loc1, nested11, nested113'); + do_test('/loc/', '1 11 111', 'global1, loc1, nested11, nested111'); + do_test('/loc/', '1 11 112', 'global1, loc1, nested11, nested112'); +} + +do_test('/loc/foo.if_test', '1 2', 'global1, files2, loc1, loc2'); + +if (have_min_apache_version('2.4.26')) { + do_test('/loc/foo.if_test', '1 2 11', 'global1, files2, loc1, loc2, nested11, nested113'); + do_test('/loc/foo.if_test', '1 2 11 111', 'global1, files2, loc1, loc2, nested11, nested111'); + do_test('/loc/foo.if_test', '1 2 11 112', 'global1, files2, loc1, loc2, nested11, nested112'); +} + +do_test('/proxy/', '1 2', 'global1, locp1, locp2'); +do_test('/proxy/', '2', 'locp2'); + diff --git a/debian/perl-framework/t/apache/iffile.t b/debian/perl-framework/t/apache/iffile.t new file mode 100644 index 0000000..fab15a1 --- /dev/null +++ b/debian/perl-framework/t/apache/iffile.t @@ -0,0 +1,17 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +# Available since 2.4.34, but quoted paths in <IfFile> fixed in 2.4.35 +plan tests => 2, + need( + need_module('mod_headers'), + need_min_apache_version('2.4.35') + ); + +my $resp = GET('/apache/iffile/document'); +ok t_cmp($resp->code, 200); +ok t_cmp($resp->header('X-Out'), "success1, success2, success3, success4, success5"); diff --git a/debian/perl-framework/t/apache/leaks.t b/debian/perl-framework/t/apache/leaks.t new file mode 100644 index 0000000..bb7b329 --- /dev/null +++ b/debian/perl-framework/t/apache/leaks.t @@ -0,0 +1,63 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $url = "/memory_track"; +my $init_iters = 2000; +my $iters = 500; + +my $active = GET_RC($url) == 200; + +my $num_tests = $init_iters + $iters * 2; +plan tests => $num_tests, + need { "mod_memory_track not activated" => $active }; + +### this doesn't seem sufficient to force all requests over a single +### persistent connection any more, is there a better trick? +Apache::TestRequest::user_agent(keep_alive => 1); +Apache::TestRequest::scheme('http'); + +my $cid = -1; +my $mem; + +# initial iterations should get workers to steady-state memory use. +foreach (1..$init_iters) { + ok t_cmp(GET_RC($url), 200, "200 response"); +} + +# now test whether c->pool memory is increasing for further +# requests on a given conn_rec (matched by id)... could track them +# all with a bit more effort. +foreach (1..$iters) { + my $r = GET $url; + + print "# iter $_\n"; + + ok t_cmp($r->code, 200, "got response"); + + my $content = $r->content; + chomp $content; + my ($key, $id, $bytes) = split ',', $content; + + print "# $key, $id, $bytes\n"; + + if ($cid == -1) { + $cid = $id; + $mem = $bytes; + ok 1; + } + elsif ($cid != $id) { + skip "using wrong connection"; + } + elsif ($bytes > $mem) { + print "# error: pool memory increased from $mem to $bytes!\n"; + ok 0; + } + else { + ok 1; + } +} + diff --git a/debian/perl-framework/t/apache/limits.t b/debian/perl-framework/t/apache/limits.t new file mode 100644 index 0000000..a475f82 --- /dev/null +++ b/debian/perl-framework/t/apache/limits.t @@ -0,0 +1,217 @@ +# +# Test the LimitRequestLine, LimitRequestFieldSize, LimitRequestFields, +# and LimitRequestBody directives. +# +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +# +# These values are chosen to exceed the limits in extra.conf, namely: +# +# LimitRequestLine @limitrequestline@ +# LimitRequestFieldSize 1024 +# LimitRequestFields 32 +# <Directory @SERVERROOT@/htdocs/apache/limits> +# LimitRequestBody 65536 +# </Directory> +# + +my $limitrequestlinex2 = Apache::Test::config()->{vars}->{limitrequestlinex2}; + +my @conditions = qw(requestline fieldsize fieldcount bodysize merged_fieldsize); + +my %params = ('requestline-succeed' => "/apache/limits/", + 'requestline-fail' => ("/apache/limits/" . ('a' x $limitrequestlinex2)), + 'fieldsize-succeed' => 'short value', + 'fieldsize-fail' => ('a' x 2048), + 'fieldcount-succeed' => 1, + 'fieldcount-fail' => 64, + 'bodysize-succeed' => ('a' x 1024), + 'bodysize-fail' => ('a' x 131072), + 'merged_fieldsize-succeed' => ('a' x 500), + 'merged_fieldsize-fail' => ('a' x 600), + ); +my %xrcs = ('requestline-succeed' => 200, + 'requestline-fail' => 414, + 'fieldsize-succeed' => 200, + 'fieldsize-fail' => 400, + 'fieldcount-succeed' => 200, + 'fieldcount-fail' => 400, + 'bodysize-succeed' => 200, + 'bodysize-fail' => 413, + 'merged_fieldsize-succeed' => 200, + 'merged_fieldsize-fail' => 400, + ); + +my $res; + +if (!have_min_apache_version("2.2.32")) { + $xrcs{"merged_fieldsize-fail"} = 200; +} + +# +# Two tests for each of the conditions, plus two more for the +# chunked version of the body-too-large test IFF we have the +# appropriate level of LWP support. +# + +my $no_chunking = defined($LWP::VERSION) && $LWP::VERSION < 5.60; +if ($no_chunking) { + print "# Chunked upload tests will NOT be performed;\n", + "# LWP 5.60 or later is required and you only have ", + "$LWP::VERSION installed.\n"; +} + +my $subtests = (@conditions * 2) + 2; +plan tests => $subtests, \&need_lwp; + +use vars qw($expected_rc); + +my $testnum = 1; +foreach my $cond (@conditions) { + foreach my $goodbad (qw(succeed fail)) { + my $param = $params{"$cond-$goodbad"}; + $expected_rc = $xrcs{"$cond-$goodbad"}; + my $resp; + if ($cond eq 'fieldcount') { + my %fields; + for (my $i = 1; $i <= $param; $i++) { + $fields{"X-Field-$i"} = "Testing field $i"; + } + print "# Testing LimitRequestFields; should $goodbad\n"; + $resp = GET('/apache/limits/', %fields, 'X-Subtest' => $testnum); + ok t_cmp($resp->code, + $expected_rc, + "Test #$testnum"); + if ($resp->code != $expected_rc) { + print_response($resp); + } + $testnum++; + } + elsif ($cond eq 'bodysize') { + # + # Make sure the last situation is keepalives off.. + # + foreach my $chunked (qw(1 0)) { + print "# Testing LimitRequestBody; should $goodbad\n"; + set_chunking($chunked); + # + # Note that this tests different things depending upon + # the chunking state. The content-body will not even + # be counted if the Content-Length of an unchunked + # request exceeds the server's limit; it'll just be + # drained and discarded. + # + if ($chunked) { + if ($no_chunking) { + my $msg = 'Chunked upload not tested; ' + . 'not supported by this version of LWP'; + print "# $msg\n"; + skip $msg, 1; + } + else { + my ($req, $resp, $url); + $url = Apache::TestRequest::resolve_url('/apache/limits/'); + $req = HTTP::Request->new(GET => $url); + $req->content_type('text/plain'); + $req->header('X-Subtest' => $testnum); + $req->content(chunk_it($param)); + $resp = Apache::TestRequest::user_agent->request($req); + + # limit errors with chunked request bodies get + # 400 with 1.3, not 413 - see special chunked + # request handling in ap_get_client_block in 1.3 + + local $expected_rc = 400 if $goodbad eq 'fail' && + have_apache(1); + + ok t_cmp($resp->code, + $expected_rc, + "Test #$testnum"); + if ($resp->code != $expected_rc) { + print_response($resp); + } + } + } + else { + $resp = GET('/apache/limits/', content_type => 'text/plain', + content => $param, 'X-Subtest' => $testnum); + ok t_cmp($resp->code, + $expected_rc, + "Test #$testnum"); + if ($resp->code != $expected_rc) { + print_response($resp); + } + } + $testnum++; + } + } + elsif ($cond eq 'merged_fieldsize') { + print "# Testing LimitRequestFieldSize; should $goodbad\n"; + $resp = GET('/apache/limits/', 'X-Subtest' => $testnum, + 'X-overflow-field' => $param, + 'X-overflow-field' => $param); + ok t_cmp($resp->code, + $expected_rc, + "Test #$testnum"); + if ($resp->code != $expected_rc) { + print_response($resp); + } + $testnum++; + } + elsif ($cond eq 'fieldsize') { + print "# Testing LimitRequestFieldSize; should $goodbad\n"; + $resp = GET('/apache/limits/', 'X-Subtest' => $testnum, + 'X-overflow-field' => $param); + ok t_cmp($resp->code, + $expected_rc, + "Test #$testnum"); + if ($resp->code != $expected_rc) { + print_response($resp); + } + $testnum++; + } + elsif ($cond eq 'requestline') { + print "# Testing LimitRequestLine; should $goodbad\n"; + $resp = GET($param, 'X-Subtest' => $testnum); + ok t_cmp($resp->code, + $expected_rc, + "Test #$testnum"); + if ($resp->code != $expected_rc) { + print_response($resp); + } + $testnum++; + } + } +} + +sub chunk_it { + my $str = shift; + my $delay = shift; + + $delay = 1 unless defined $delay; + return sub { + select(undef, undef, undef, $delay) if $delay; + my $l = length($str); + return substr($str, 0, ($l > 102400 ? 102400 : $l), ""); + } +} + +sub set_chunking { + my ($setting) = @_; + $setting = $setting ? 1 : 0; + print "# Chunked transfer-encoding ", + ($setting ? "enabled" : "disabled"), "\n"; + Apache::TestRequest::user_agent(keep_alive => ($setting ? 1 : 0)); +} + +sub print_response { + my ($resp) = @_; + my $str = $resp->as_string; + $str =~ s:\n:\n# :gs; + print "# Server response:\n# $str\n"; +} diff --git a/debian/perl-framework/t/apache/loglevel.t b/debian/perl-framework/t/apache/loglevel.t new file mode 100644 index 0000000..cb542d1 --- /dev/null +++ b/debian/perl-framework/t/apache/loglevel.t @@ -0,0 +1,43 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw/t_start_error_log_watch t_finish_error_log_watch/; + +plan tests => 8, need_min_apache_version('2.3.6'); + +my $base = "/apache/loglevel"; + +t_start_error_log_watch(); + +my @error_expected =qw{ + core_info + info + crit/core_info + info/core_crit/info +}; +my @error_not_expected =qw{ + core_crit + crit + info/core_crit + crit/core_info/crit +}; + +my $dir; +foreach $dir (@error_expected) { + GET "$base/$dir/not_found_error_expected"; +} +foreach $dir (@error_not_expected) { + GET "$base/$dir/not_found_error_NOT_expected"; +} + +my @loglines = t_finish_error_log_watch(); +my $log = join("\n", @loglines); + +foreach $dir (@error_expected) { + ok($log =~ m{does not exist.*?$base/$dir/not_found_error_expected}); +} +foreach $dir (@error_not_expected) { + ok($log !~ m{does not exist.*?$base/$dir/not_found_error_NOT_expected}); +} diff --git a/debian/perl-framework/t/apache/maxranges.t b/debian/perl-framework/t/apache/maxranges.t new file mode 100644 index 0000000..015a474 --- /dev/null +++ b/debian/perl-framework/t/apache/maxranges.t @@ -0,0 +1,70 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); + +# test multi-byterange-requests with overlaps (merges) + +my $url = "/apache/chunked/byteranges.txt"; +my $file = Apache::Test::vars('serverroot') . "/htdocs$url"; + +my $content = ""; +$content .= sprintf("%04d", $_) for (1 .. 2000); +t_write_file($file, $content); +my $clen = length($content); + + +my $medrange = ""; +my $longrange = ""; +my $i; + +for (0 .. 50) { + $longrange .= "0-1,3-4,0-1,3-4,"; + if ($_ % 2) { + $medrange .= "0-1,3-4,0-1,3-4,"; + } +} + +my @test_cases = ( + { url => "/maxranges/default/byteranges.txt" , h => "0-100", status => "206"}, + { url => "/maxranges/default/byteranges.txt" , h => $medrange, status => "206"}, + { url => "/maxranges/default/byteranges.txt" , h => $longrange, status => "200"}, + + { url => "/maxranges/default-explicit/byteranges.txt" , h => "0-100", status => "206"}, + { url => "/maxranges/default-explicit/byteranges.txt" , h => $medrange, status => "206"}, + { url => "/maxranges/default-explicit/byteranges.txt" , h => $longrange, status => "200"}, + + { url => "/maxranges/none/byteranges.txt" , h => "0-100", status => "200"}, + { url => "/maxranges/none/byteranges.txt" , h => "$medrange", status => "200"}, + { url => "/maxranges/none/byteranges.txt" , h => "$longrange", status => "200"}, + + { url => "/maxranges/1/merge/none/byteranges.txt" , h => "0-100", status => "200"}, + { url => "/maxranges/1/merge/none/byteranges.txt" , h => "$medrange", status => "200"}, + { url => "/maxranges/1/merge/none/byteranges.txt" , h => "$longrange", status => "200"}, + + { url => "/maxranges/1/byteranges.txt" , h => "0-100", status => "206"}, + { url => "/maxranges/1/byteranges.txt" , h => "0-100,200-300", status => "200"}, + { url => "/maxranges/2/byteranges.txt" , h => "0-100,200-300", status => "206"}, + { url => "/maxranges/2/byteranges.txt" , h => "0-100,200-300,400-500", status => "200"}, + { url => "/maxranges/unlimited/byteranges.txt" , h => "0-100", status => "206"}, + { url => "/maxranges/unlimited/byteranges.txt" , h => "$medrange", status => "206"}, + { url => "/maxranges/unlimited/byteranges.txt" , h => "$longrange", status => "206"}, + +); +plan tests => scalar(@test_cases), need need_lwp, need_min_apache_version('2.3.15') || need_min_apache_version('2.2.21'), + need_module('mod_alias'); + + +foreach my $test (@test_cases) { + my $result = GET $test->{"url"}, "Range" => "bytes=" . $test->{"h"} ; + my $boundary; + my $ctype = $result->header("Content-Type"); + if ($test->{"status"} ne $result->code()) { + print "Wrong status code: " . $result->code() ."\n"; + ok(0); + next; + } + ok (1); +} diff --git a/debian/perl-framework/t/apache/mergeslashes.t b/debian/perl-framework/t/apache/mergeslashes.t new file mode 100644 index 0000000..850fc93 --- /dev/null +++ b/debian/perl-framework/t/apache/mergeslashes.t @@ -0,0 +1,117 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use MIME::Base64; +use Data::Dumper; +use HTTP::Response; +use Socket; + +# undef: HTTPD should drop connection without error message + +my @test_cases = ( + # request, status code global, status code 'mergeslashes off' VH, msg + [ "GET /authz_core/a/b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "exact match"], + [ "GET //authz_core/a/b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "merged even at front"], + [ "GET ///authz_core/a/b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "merged even at front"], + [ "GET /authz_core/a/b/c//index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "c// should be merged"], + [ "GET /authz_core/a//b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "a// should be merged"], + [ "GET /authz_core/a//b/c/index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 403, "a// matches locationmatch"], + [ "GET /authz_core/a/b/c//index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 200, "c// doesn't match locationmatch"], + [ "GET /authz_core/a/b/d/index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 403, "baseline failed", need_min_apache_version('2.4.47')], + [ "GET /authz_core/a/b//d/index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 403, "b//d not merged for Location with OFF",need_min_apache_version('2.4.47')], +); + +plan tests => scalar(@test_cases), need_min_apache_version('2.4.39'); + + + foreach my $t (@test_cases) { + my $req = $t->[0]; + my $expect = $t->[1]; + my $desc = $t->[2]; + my $cond = $t->[3]; + my $decoded; + + if (defined($cond) && !$cond) { + skip("n/a"); + } + + my $sock = Apache::TestRequest::vhost_socket("core"); + if (!$sock) { + print "# failed to connect\n"; + ok(0); + next; + } + + $sock->print($req); + sleep(0.1); + $req = escape($req); + print "# SENDING to " . peer($sock) . "\n# $req\n"; + + my $response_data = ""; + my $buf; + while ($sock->read($buf, 10000) > 0) { + $response_data .= $buf; + } + my $response = HTTP::Response->parse($response_data); + if ($decoded) { + $response_data =~ s/<title>.*/.../s; + my $out = escape($response_data); + $out =~ s{\\n}{\\n\n# }g; + print "# RESPONSE:\n# $out\n"; + } + if (! defined $response) { + die "HTTP::Response->parse failed"; + } + my $rc = $response->code; + if (! defined $rc) { + if (! defined $expect) { + print "# expecting dropped connection and HTTPD dropped connection\n"; + ok(1); + } + else { + print "# expecting $expect, but HTTPD dropped the connection\n"; + ok(0); + } + } + elsif ($expect > 100) { + print "# expected $expect, got " . $response->code . " for $desc\n"; + ok ($response->code, $expect, $desc ); + } + elsif ($expect == 90) { + print "# expecting headerless HTTP/0.9 body, got response\n"; + ok (1); + } + elsif ($expect) { + print "# expecting success, got ", $rc, ": $desc\n"; + ok ($rc >= 200 && $rc < 400); + } + else { + print "# expecting error, got ", $rc, ": $desc\n"; + ok ($rc >= 400); + } + } + +sub escape +{ + my $in = shift; + $in =~ s{\\}{\\\\}g; + $in =~ s{\r}{\\r}g; + $in =~ s{\n}{\\n}g; + $in =~ s{\t}{\\t}g; + $in =~ s{([\x00-\x1f])}{sprintf("\\x%02x", ord($1))}ge; + return $in; +} + +sub peer +{ + my $sock = shift; + my $hersockaddr = getpeername($sock); + return "<disconnected>" if !$hersockaddr; + my ($port, $iaddr) = sockaddr_in($hersockaddr); + my $herhostname = gethostbyaddr($iaddr, AF_INET); + my $herstraddr = inet_ntoa($iaddr); + return "$herstraddr:$port"; +} diff --git a/debian/perl-framework/t/apache/mmn.t b/debian/perl-framework/t/apache/mmn.t new file mode 100644 index 0000000..985a8e6 --- /dev/null +++ b/debian/perl-framework/t/apache/mmn.t @@ -0,0 +1,42 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +# +# check that the comment and the #define in ap_mmn.h are equal +# + +plan tests => 2, need_apache 2; + +my $config = Apache::TestConfig->thaw(); +my $filename = $config->apxs('INCLUDEDIR') . '/ap_mmn.h'; + +my $cmajor; +my $cminor; +my $major; +my $minor; +my $skip; +if (open(my $fh, "<", $filename)) { + while (defined (my $line = <$fh>)) { + if ($line =~ m/^\s+[*]\s+(\d{8})[.](\d+)\s+\([\d.]+(?:-dev)?\)\s/ ) { + $cmajor = $1; + $cminor = $2; + } + elsif ($line =~ m{^#define\s+MODULE_MAGIC_NUMBER_MAJOR\s+(\d+)(?:\s|$)}) + { + $major = $1; + } + elsif ($line =~ m{^#define\s+MODULE_MAGIC_NUMBER_MINOR\s+(\d+)(?:\s|$)}) + { + $minor = $1; + } + } + close($fh); +} +else { + $skip = "Skip if can't read $filename"; +} + +skip($skip, $major, $cmajor); +skip($skip, $minor, $cminor); diff --git a/debian/perl-framework/t/apache/options.t b/debian/perl-framework/t/apache/options.t new file mode 100644 index 0000000..93809b7 --- /dev/null +++ b/debian/perl-framework/t/apache/options.t @@ -0,0 +1,17 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @urls = qw(/); + +plan tests => @urls * 2, \&need_lwp; + +for my $url (@urls) { + my $res = OPTIONS $url; + ok t_cmp $res->code, 200, "code"; + my $allow = $res->header('Allow') || ''; + ok t_cmp $allow, qr/OPTIONS/, "OPTIONS"; +} diff --git a/debian/perl-framework/t/apache/passbrigade.t b/debian/perl-framework/t/apache/passbrigade.t new file mode 100644 index 0000000..a31f29f --- /dev/null +++ b/debian/perl-framework/t/apache/passbrigade.t @@ -0,0 +1,7 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::TestCommon (); + +Apache::TestCommon::run_write_test('test_pass_brigade'); + diff --git a/debian/perl-framework/t/apache/post.t b/debian/perl-framework/t/apache/post.t new file mode 100644 index 0000000..8c58847 --- /dev/null +++ b/debian/perl-framework/t/apache/post.t @@ -0,0 +1,12 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestCommon (); + +my $module = 'eat_post'; +my $num = Apache::TestCommon::run_post_test_sizes(); + +plan tests => $num, need need_lwp, need_module($module); + +Apache::TestCommon::run_post_test($module); diff --git a/debian/perl-framework/t/apache/pr17629.t b/debian/perl-framework/t/apache/pr17629.t new file mode 100644 index 0000000..a089e98 --- /dev/null +++ b/debian/perl-framework/t/apache/pr17629.t @@ -0,0 +1,51 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 4, need [need_cgi, qw(include deflate case_filter)]; +my $inflator = "/modules/deflate/echo_post"; + +my @deflate_headers; +push @deflate_headers, "Accept-Encoding" => "gzip"; + +my @inflate_headers; +push @inflate_headers, "Content-Encoding" => "gzip"; + +# The SSI script has the DEFLATE filter applied. +# The SSI includes a CGI script. +# The CGI script has the CASE filter applied. +# The CGI script returns a redirect to /foobar.html. +# The flat file does not have the DEFLATE filter applied. + +# The test is that the internal redirect when applied to the +# subrequest must retain the DEFLATE filter in the filter chain, but +# must lose the CASE filter. + +my $uri = "/modules/deflate/ssi/ssi.shtml"; + +my $content = GET_BODY($uri); + +my $expected = "begin-foobar-end\n"; + +ok t_cmp($content, $expected); + +my $r = GET($uri, @deflate_headers); + +ok t_cmp($r->code, 200); + +my $renc = $r->header("Content-Encoding") || ""; + +ok t_cmp($renc, "gzip", "response was gzipped"); + +if ($renc eq "gzip") { + my $deflated = POST_BODY($inflator, @inflate_headers, + content => $r->content); + + ok t_cmp($deflated, $expected); +} +else { + skip "response not gzipped"; +} diff --git a/debian/perl-framework/t/apache/pr18757.t b/debian/perl-framework/t/apache/pr18757.t new file mode 100644 index 0000000..d53262f --- /dev/null +++ b/debian/perl-framework/t/apache/pr18757.t @@ -0,0 +1,58 @@ +# +# Regression test for PR 18757. +# +# Annoyingly awkward to write because LWP is a poor excuse for an HTTP +# interface and will lie about what response headers are sent, so this +# must be yet another test which speaks TCP directly. +# + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 3, need 'proxy', need_min_apache_version('2.2.1'), need_cgi; + +Apache::TestRequest::module("mod_proxy"); + +my $path = "/index.html"; + +my $r = GET($path); + +ok t_cmp($r->code, 200, "200 response from GET"); + +my $clength = $r->content_length; + +t_debug("expected C-L is $clength"); + +my $url = Apache::TestRequest::resolve_url($path); +my $hostport = Apache::TestRequest::hostport(); +my $sock = Apache::TestRequest::vhost_socket("mod_proxy"); + +t_debug "URL via proxy is $url"; + +ok $sock; + +$sock->print("HEAD $url HTTP/1.1\r\n"); +$sock->print("Host: $hostport\r\n"); +$sock->print("\r\n"); + +my $ok = 0; +my $response; + +do { + chomp($response = Apache::TestRequest::getline($sock) || ''); + $response =~ s/\s$//; + + t_debug("line: $response"); + + if ($response =~ /Content-Length: $clength/) { + $ok = 1; + } + +} +while ($response ne ""); + +ok t_cmp($ok, 1, "whether proxy strips Content-Length header"); diff --git a/debian/perl-framework/t/apache/pr35292.t b/debian/perl-framework/t/apache/pr35292.t new file mode 100644 index 0000000..9a6243e --- /dev/null +++ b/debian/perl-framework/t/apache/pr35292.t @@ -0,0 +1,33 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +$SIG{PIPE} = 'IGNORE'; + +plan tests => 3, need_min_apache_version('2.1.8'); + +my $sock = Apache::TestRequest::vhost_socket('default'); +ok $sock; + +Apache::TestRequest::socket_trace($sock); + +$sock->print("POST /apache/limits/ HTTP/1.1\r\n"); +$sock->print("Host: localhost\r\n"); +$sock->print("Content-Length: 1048576\r\n"); +$sock->print("\r\n"); + +foreach (1..128) { + $sock->print('x'x8192) if $sock->connected; +} + +# Before the PR 35292 fix, the socket would already have been reset by +# this point and most clients will have stopped sending and gone away. + +ok $sock->connected; + +my $line = Apache::TestRequest::getline($sock) || ''; + +ok t_cmp($line, qr{^HTTP/1\.. 413}, "read response-line"); diff --git a/debian/perl-framework/t/apache/pr35330.t b/debian/perl-framework/t/apache/pr35330.t new file mode 100644 index 0000000..e5fe01f --- /dev/null +++ b/debian/perl-framework/t/apache/pr35330.t @@ -0,0 +1,16 @@ +# +# Regression test for PR 35330 +# +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, need 'include'; + +my $r = GET '/apache/htaccess/override/hello.shtml'; + +ok t_cmp($r->code, 200, "SSI was allowed for location"); +ok t_cmp($r->content, "hello", "file was served with correct content"); diff --git a/debian/perl-framework/t/apache/pr37166.t b/debian/perl-framework/t/apache/pr37166.t new file mode 100644 index 0000000..919cda2 --- /dev/null +++ b/debian/perl-framework/t/apache/pr37166.t @@ -0,0 +1,29 @@ +# +# Regression test for PR 37166 +# +# r370692 determined that a CGI script which outputs an explicit +# "Status: 200" will not be subject to conditional request processing. +# Previous behaviour was the opposite, but fell foul of the r->status +# vs r->status_line issue fixed in r385581. +# +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 4, \&need_cgi; + +my $uri = '/modules/cgi/pr37166.pl'; + +my $r = GET $uri; + +ok t_cmp($r->code, 200, "SSI was allowed for location"); +ok t_cmp($r->content, "Hello world\n", "file was served with correct content"); + +$r = GET $uri, "If-Modified-Since" => "Tue, 15 Feb 2005 15:00:00 GMT"; + +ok t_cmp($r->code, 200, "explicit 200 response"); +ok t_cmp($r->content, "Hello world\n", + "file was again served with correct content"); diff --git a/debian/perl-framework/t/apache/pr43939.t b/debian/perl-framework/t/apache/pr43939.t new file mode 100644 index 0000000..5e35f9e --- /dev/null +++ b/debian/perl-framework/t/apache/pr43939.t @@ -0,0 +1,47 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 4, need [need_cgi, qw(include deflate case_filter)]; +my $inflator = "/modules/deflate/echo_post"; + +my @deflate_headers; +push @deflate_headers, "Accept-Encoding" => "gzip"; + +my @inflate_headers; +push @inflate_headers, "Content-Encoding" => "gzip"; + +# The SSI script has the DEFLATE filter applied. +# The SSI includes directory index page. +# The directory index page is processed with a fast internal redirect. + +# The test is that filter chain survives across the redirect. + +my $uri = "/modules/deflate/ssi/ssi2.shtml"; + +my $content = GET_BODY($uri); + +my $expected = "begin-default-end\n"; + +ok t_cmp($content, $expected); + +my $r = GET($uri, @deflate_headers); + +ok t_cmp($r->code, 200); + +my $renc = $r->header("Content-Encoding") || ""; + +ok t_cmp($renc, "gzip", "response was gzipped"); + +if ($renc eq "gzip") { + my $deflated = POST_BODY($inflator, @inflate_headers, + content => $r->content); + + ok t_cmp($deflated, $expected); +} +else { + skip "response not gzipped"; +} diff --git a/debian/perl-framework/t/apache/pr49328.t b/debian/perl-framework/t/apache/pr49328.t new file mode 100644 index 0000000..5b37032 --- /dev/null +++ b/debian/perl-framework/t/apache/pr49328.t @@ -0,0 +1,25 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1, need [qw(filter include deflate)]; + +my $inflator = "/modules/deflate/echo_post"; + +my @deflate_headers; +push @deflate_headers, "Accept-Encoding" => "gzip"; + +my @inflate_headers; +push @inflate_headers, "Content-Encoding" => "gzip"; + +my $uri = "/modules/filter/pr49328/pr49328.shtml"; + +my $content = GET_BODY($uri, @deflate_headers); + +my $deflated = POST_BODY($inflator, @inflate_headers, + content => $content); + +ok t_cmp($deflated, "before\nincluded\nafter\n"); diff --git a/debian/perl-framework/t/apache/rwrite.t b/debian/perl-framework/t/apache/rwrite.t new file mode 100644 index 0000000..e27808c --- /dev/null +++ b/debian/perl-framework/t/apache/rwrite.t @@ -0,0 +1,6 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::TestCommon (); + +Apache::TestCommon::run_write_test('test_rwrite'); diff --git a/debian/perl-framework/t/apache/server_name_port.t b/debian/perl-framework/t/apache/server_name_port.t new file mode 100644 index 0000000..2597d7c --- /dev/null +++ b/debian/perl-framework/t/apache/server_name_port.t @@ -0,0 +1,135 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Socket; + +# send +# arg #1: url prefix +# arg #2: Host header (none if undef) +# expected results: +# arg #3: response code +# arg #4: SERVER_NAME +# arg #5: SERVER_PORT (canonical port if 'REMOTE') +# undef == don't care + +my $url_suffix = 'modules/cgi/env.pl'; + +my @test_cases = ( + [ "/", "righthost" => 200, 'righthost', 'REMOTE' ], + [ "/", "righthost:123" => 200, 'righthost', '123' ], + [ "/", "Righthost" => 200, 'righthost', 'REMOTE' ], + [ "/", "Righthost:123" => 200, 'righthost', '123' ], + [ "/", "128.0.0.1" => 200, '128.0.0.1', 'REMOTE' ], + [ "/", "128.0.0.1:123" => 200, '128.0.0.1', '123' ], + [ "/", "[::1]" => 200, '[::1]', 'REMOTE' ], + [ "/", "[::1]:123" => 200, '[::1]', '123' ], + [ "/", "[a::1]" => 200, '[a::1]', 'REMOTE' ], + [ "/", "[a::1]:123" => 200, '[a::1]', '123' ], + [ "/", "[A::1]" => 200, '[a::1]', 'REMOTE' ], + [ "/", "[A::1]:123" => 200, '[a::1]', '123' ], + [ "http://righthost/", undef => 200, 'righthost', 'REMOTE' ], + [ "http://righthost:123/", undef => 200, 'righthost', '123' ], + [ "http://Righthost/", undef => 200, 'righthost', 'REMOTE' ], + [ "http://Righthost:123/", undef => 200, 'righthost', '123' ], + [ "http://128.0.0.1/", undef => 200, '128.0.0.1', 'REMOTE' ], + [ "http://128.0.0.1:123/", undef => 200, '128.0.0.1', '123' ], + [ "http://[::1]/", undef => 200, '[::1]', 'REMOTE' ], + [ "http://[::1]:123/", undef => 200, '[::1]', '123' ], + [ "http://righthost/", "wronghost" => 200, 'righthost', 'REMOTE' ], + [ "http://righthost:123/", "wronghost:321" => 200, 'righthost', '123' ], + [ "http://Righthost/", "wronghost" => 200, 'righthost', 'REMOTE' ], + [ "http://Righthost:123/", "wronghost:321" => 200, 'righthost', '123' ], + [ "http://128.0.0.1/", "126.0.0.1" => 200, '128.0.0.1', 'REMOTE' ], + [ "http://128.0.0.1:123/", "126.0.0.1:321" => 200, '128.0.0.1', '123' ], + [ "http://[::1]/", "[::2]" => 200, '[::1]', 'REMOTE' ], + [ "http://[::1]:123/", "[::2]:321" => 200, '[::1]', '123' ], +); + +my @todo; +if (!have_min_apache_version('2.4.24')) { + # r1426827 + push @todo, 32, 35, 56, 59, 80, 83; +} +if (!have_min_apache_version('2.4')) { + # r1147614, PR 26005 + push @todo, 20, 23, 26, 29; +} + +plan tests => 3 * scalar(@test_cases), todo => \@todo, need need_min_apache_version('2.2'), need_cgi; + +foreach my $t (@test_cases) { + my $req = "GET $t->[0]$url_suffix HTTP/1.1\r\nConnection: close\r\n"; + $req .= "Host: $t->[1]\r\n" if defined $t->[1]; + $req .= "\r\n"; + + my %ex = ( + rc => $t->[2], + SERVER_NAME => $t->[3], + SERVER_PORT => $t->[4], + ); + + my $sock = Apache::TestRequest::vhost_socket(); + if (!$sock) { + print "# failed to connect\n"; + ok(0); + next; + } + if (defined $ex{SERVER_PORT} && $ex{SERVER_PORT} eq 'REMOTE') { + my $peername = getpeername($sock); + my ($port) = sockaddr_in($peername); + $ex{SERVER_PORT} = "$port"; + } + + $sock->print($req); + $sock->shutdown(1); + sleep(0.1); + print "# SENDING:\n# ", escape($req), "\n"; + + my $response_data = ""; + my $buf; + while ($sock->read($buf, 10000) > 0) { + $response_data .= $buf; + } + my $response = HTTP::Response->parse($response_data); + if (! defined $response) { + die "HTTP::Response->parse failed"; + } + my $rc = $response->code; + if (! defined $rc) { + print "# HTTPD dropped the connection\n"; + ok(0); + } + else { + print "# expecting $ex{rc}, got ", $rc, "\n"; + ok ($rc == $ex{rc}); + } + + foreach my $var (qw/SERVER_NAME SERVER_PORT/) { + if (! defined $ex{$var}) { + print "# don't care about $var\n"; + ok(1); + } + elsif ($response_data =~ /^$var = (.*)$/m) { + my $val = $1; + print "# got $var='$val', expected '$ex{$var}'\n"; + ok($val eq $ex{$var}); + } + else { + print "# no $var in response, expected '$ex{$var}'\n"; + ok(0); + } + } +} + +sub escape +{ + my $in = shift; + $in =~ s{\\}{\\\\}g; + $in =~ s{\r}{\\r}g; + $in =~ s{\n}{\\n}g; + $in =~ s{\t}{\\t}g; + $in =~ s{([\x00-\x1f])}{sprintf("\\x%02x", ord($1))}ge; + return $in; +} diff --git a/debian/perl-framework/t/apache/teclchunk.t b/debian/perl-framework/t/apache/teclchunk.t new file mode 100644 index 0000000..b804368 --- /dev/null +++ b/debian/perl-framework/t/apache/teclchunk.t @@ -0,0 +1,57 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestCommon (); +use Apache::TestRequest (); + +my $module = 'default'; + +if (!have_min_apache_version('2.5.0')) { + print "1..0 # skip: Not supported yet"; + exit 0; +} + +plan tests => 4, ['echo_post_chunk']; + +my $sock = Apache::TestRequest::vhost_socket($module); +ok $sock; + +Apache::TestRequest::socket_trace($sock); +$sock->print("POST /echo_post_chunk HTTP/1.1\r\n"); +$sock->print("Host: localhost\r\n"); +$sock->print("Content-Length: 77\r\n"); +$sock->print("Transfer-Encoding: chunked\r\n"); +$sock->print("\r\n"); +$sock->print("0\r\n"); +$sock->print("X-Chunk-Trailer: $$\r\n"); +$sock->print("\r\n"); +$sock->print("GET /i_do_not_exist_in_your_wildest_imagination HTTP/1.1\r\n"); +$sock->print("Host: localhost\r\n"); + +# Read the status line +chomp(my $response = Apache::TestRequest::getline($sock) || ''); +$response =~ s/\s$//; +ok t_cmp($response, "HTTP/1.1 200 OK", "response codes"); + +# Read the rest +do { + chomp($response = Apache::TestRequest::getline($sock)); + $response =~ s/\s$//; +} +while ($response ne ""); + +# Do the next request... that MUST fail. +$sock->print("\r\n"); +$sock->print("\r\n"); + +# read the trailer (pid) +$response = Apache::TestRequest::getline($sock); +chomp($response) if (defined($response)); +ok t_cmp($response, "$$", "trailer (pid)"); + +# Make sure we have not received a 404. +chomp($response = Apache::TestRequest::getline($sock) || 'NO'); +$response =~ s/\s$//; +ok t_cmp($response, "NO", "no response"); diff --git a/debian/perl-framework/t/apr/uri.t b/debian/perl-framework/t/apr/uri.t new file mode 100644 index 0000000..e2c0cc4 --- /dev/null +++ b/debian/perl-framework/t/apr/uri.t @@ -0,0 +1,11 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_module 'test_apr_uri'; + +my $body = GET_BODY '/test_apr_uri'; + +ok $body =~ /TOTAL\s+FAILURES\s*=\s*0/; diff --git a/debian/perl-framework/t/conf/cache.conf.in b/debian/perl-framework/t/conf/cache.conf.in new file mode 100644 index 0000000..fa06db7 --- /dev/null +++ b/debian/perl-framework/t/conf/cache.conf.in @@ -0,0 +1,25 @@ +# +# Config for mod_cache tests +# + +<IfModule mod_cache.c> + <VirtualHost mod_cache> + <IfModule mod_disk_cache.c> + + CacheEnable disk /cache/ + CacheRoot @SERVERROOT@/conf/cacheroot/ + CacheDirLevels 1 + CacheDirLength 1 + + </IfModule> + <IfModule mod_cache_disk.c> + + CacheEnable disk /cache/ + CacheRoot @SERVERROOT@/conf/cacheroot/ + CacheDirLevels 1 + CacheDirLength 1 + + </IfModule> + DocumentRoot @SERVERROOT@/htdocs/modules/cache + </VirtualHost> +</IfModule> diff --git a/debian/perl-framework/t/conf/core.conf.in b/debian/perl-framework/t/conf/core.conf.in new file mode 100644 index 0000000..53122a8 --- /dev/null +++ b/debian/perl-framework/t/conf/core.conf.in @@ -0,0 +1,55 @@ +# NameVirtualHost sections for :core. All virtual hosts ending in :core +# will be converted to a set of NVH'es on the same dynamic port, so they +# are collected here. + +MaxMemFree 1 + +<VirtualHost strict-default:core> + ServerName default-strict + <IfVersion >= 2.5.1> + # StrictHostCheck can only be configure globally or in a "default" vhost + StrictHostCheck ON + </IfVersion> +</VirtualHost> +<VirtualHost strict-nvh:core> + ServerName nvh-strict + ServerAlias nvh-strict-alias + # Implicitly StrictHostCheck ON from default VH above +</VirtualHost> + +# MergeSlashes +<IfVersion >= 2.4.39> + <VirtualHost merge-default:core> + ServerName merge-default + <Directory @DocumentRoot@/authz_core/> + require all granted + </Directory> + <LocationMatch ^/authz_core/a/b/c/index.html> + require all denied + </LocationMatch> + </virtualHost> + <VirtualHost merge-disabled:core> + ServerName merge-disabled + MergeSlashes OFF + <Directory @DocumentRoot@/authz_core/> + require all granted + </Directory> + <LocationMatch ^/authz_core/a/b/c/index.html> + require all denied + </LocationMatch> + <LocationMatch ^/authz_core/a//b/c/index.html> + require all denied + </LocationMatch> + <Location /authz_core/a/b/d> + require all denied + </Location> + <ifModule rewrite_module> + <Location /CVE-2020-1927/> + RewriteEngine ON + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L] + </Location> + </ifModule> + </virtualHost> +</IfVersion> + diff --git a/debian/perl-framework/t/conf/extra.conf.in b/debian/perl-framework/t/conf/extra.conf.in new file mode 100644 index 0000000..a684f76 --- /dev/null +++ b/debian/perl-framework/t/conf/extra.conf.in @@ -0,0 +1,1474 @@ +## +## FileETag test config +## +<Directory @SERVERROOT@/htdocs/apache/etags> + AllowOverride All + Order Deny,Allow +# Satisfy Any +</Directory> + +## +## Options override test config +## +<Directory @SERVERROOT@/htdocs/apache/htaccess/override> + AllowOverride All + Options -Includes +</Directory> + +## +## AcceptPathInfo test config +## +<IfDefine APACHE2> + <Directory @SERVERROOT@/htdocs/apache/acceptpathinfo> + # default is AcceptPathInfo default + Order Deny,Allow + Allow from all + <IfModule @CGI_MODULE@> + AddHandler cgi-script .sh + Options +ExecCGI +Includes +Indexes + </IfModule> + <IfModule mod_include.c> + DirectoryIndex index.shtml + AddOutputFilter INCLUDES shtml + </IfModule> + </Directory> + <Directory @SERVERROOT@/htdocs/apache/acceptpathinfo/on> + AcceptPathInfo on + </Directory> + <Directory @SERVERROOT@/htdocs/apache/acceptpathinfo/off> + AcceptPathInfo off + </Directory> +</IfDefine> + +## +## mod_php4/mod_php5 test config +## + +<IfModule @PHP_MODULE@> + AddType application/x-httpd-php .php + AddType application/x-httpd-php-source .phps +</IfModule> + +<IfDefine APACHE2> + <IfModule sapi_apache2.c> + AddType application/x-httpd-php .php + AddType application/x-httpd-php-source .phps + </IfModule> +</IfDefine> + +<IfModule @PHP_MODULE@> + # t/htdocs/php/arg.php et al require argc/argv in _SERVER + <Directory @SERVERROOT@/htdocs/php> + php_admin_flag "register_argc_argv" 1 + </Directory> + + <Directory @SERVERROOT@/htdocs/php/multiviews> + Options MultiViews + </Directory> + +</IfModule> + +## +## mod_expires test config +## + +<IfModule mod_expires.c> + <Directory @SERVERROOT@/htdocs/modules/expires> + ExpiresActive On + ExpiresDefault "modification plus \ + 10 years 6 months 2 weeks \ + 3 days 12 hours 30 minutes 19 seconds" + ExpiresByType text/plain M60 + ExpiresByType image/gif A120 + ExpiresByType image/jpeg A86400 + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/expires/htaccess> + AllowOverride All + </Directory> +</IfModule> + +## +## mod_negotiation test config +## + +<IfModule mod_mime.c> + AddLanguage en .en + AddLanguage fr .fr + AddLanguage de .de + AddLanguage fu .fu + AddLanguage zh-TW .zh-TW + AddHandler type-map .var +</IfModule> + +<IfModule mod_negotiation.c> + <IfDefine APACHE1> + CacheNegotiatedDocs + </IfDefine> + + <IfDefine APACHE2> + CacheNegotiatedDocs On + </IfDefine> + + <Directory @SERVERROOT@/htdocs/modules/negotiation/en> + Options +MultiViews + LanguagePriority en fr de fu zh-TW + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/negotiation/de> + Options +MultiViews + LanguagePriority de en fr fu zh-TW + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/negotiation/fr> + Options +MultiViews + LanguagePriority fr en de fu zh-TW + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/negotiation/fu> + Options +MultiViews + LanguagePriority fu fr en de zh-TW + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/negotiation/zh-TW> + Options +MultiViews + LanguagePriority zh-TW fr fu en de + </Directory> + + <IfDefine APACHE2> + <IfModule @CGI_MODULE@> + <Directory @SERVERROOT@/htdocs/modules/negotiation/query> + Options +MultiViews +ExecCGI + MultiviewsMatch any + AddHandler cgi-script .pl + </Directory> + </IfModule> + </IfDefine> + +</IfModule> + +## +## mod_rewrite test config +## + +<IfModule mod_rewrite.c> + RewriteEngine On + <IfVersion < 2.3.6> + RewriteLog @SERVERROOT@/logs/rewrite_log + RewriteLogLevel 9 + </IfVersion> + <IfVersion >= 2.3.6> + LogLevel rewrite:trace8 + </IfVersion> + + <IfDefine !APACHE1> + <IfVersion < 2.3.4> + RewriteLock @SERVERROOT@/logs/rewrite_lock + </IfVersion> + <IfVersion >= 2.3.4> + # mutex created automatically + # config needed only if file-based mutexes are used and + # default lock file dir is inappropriate + # Mutex file:/path/to/lockdir rewrite-map + </IfVersion> + </IfDefine> + <IfDefine APACHE1> + RewriteLock @SERVERROOT@/logs/rewrite_lock + </IfDefine> + RewriteMap numbers-txt txt:@SERVERROOT@/htdocs/modules/rewrite/numbers.txt + RewriteMap numbers-rnd rnd:@SERVERROOT@/htdocs/modules/rewrite/numbers.rnd + #RewriteMap numbers-dbm dbm:@SERVERROOT@/htdocs/modules/rewrite/numbers.dbm + RewriteMap numbers-prg prg:@SERVERROOT@/htdocs/modules/rewrite/numbers.pl + RewriteMap lower int:tolower + + <Directory @SERVERROOT@/htdocs/modules/rewrite> + RewriteEngine On + <IfVersion >= 2.5.0> + RewriteOptions inherit LongURLOptimization + </IfVersion> + <IfVersion < 2.5.0> + RewriteOptions inherit + </IfVersion> + + RewriteRule ^forbidden$ - [F] + RewriteRule ^gone$ - [G] + RewriteRule ^perm$ - [R=permanent] + RewriteRule ^temp$ - [R] + RewriteRule ^test\.blah$ - [T=text/html] + + ## config for testing >=< conditions + RewriteCond %{HTTP_ACCEPT} =lucky13 + RewriteRule ^$ lucky13.html [L] + + RewriteCond %{HTTP_ACCEPT} >6 + RewriteRule ^$ big.html [L] + + RewriteCond %{HTTP_ACCEPT} <1 + RewriteRule ^$ zero.html [L] + + ## config for testing rewrite maps + RewriteCond %{HTTP_ACCEPT} ^(TXT|RND|DBM|PRG)$ + RewriteRule ^([1-6])$ - [C,E=MAPTYPE:${lower:%1}] + RewriteCond %{ENV:MAPTYPE} =txt + RewriteRule ^([1-6])$ ${numbers-txt:$1}.html [S=3] + RewriteCond %{ENV:MAPTYPE} =rnd + RewriteRule ^([1-6])$ ${numbers-rnd:$1}.html [S=2] + RewriteCond %{ENV:MAPTYPE} =dbm + RewriteRule ^([1-6])$ ${numbers-dbm:$1}.html [S=1] + RewriteCond %{ENV:MAPTYPE} =prg + RewriteRule ^([1-6])$ ${numbers-prg:$1}.html [L] + + ## Proxy pass-through + RewriteRule ^proxy.html$ http://@SERVERNAME@:@PORT@/modules/rewrite/lucky13.html [L,P] + + ## Query-string append + RewriteRule ^qsa.html$ @SERVERROOT@/htdocs/modules/cgi/env.pl?foo=bar [QSA,L] + + ## Proxy and QSA + RewriteRule ^proxy-qsa.html$ http://@SERVERNAME@:@PORT@/modules/cgi/env.pl?foo=bar [QSA,L,P] + + ## Redirect, directory context + RewriteRule ^redirect-dir.html$ http://@SERVERNAME@:@PORT@/foobar.html [L,R=301] + + # PR 58231: Vary header not added to the response if the RewriteCond/Rule + # combination is in a directory context. + # Vary:Host header must not also be returned in any case. + RewriteCond %{HTTP_HOST} directory-domain + RewriteRule vary3.html vary4.html [L] + + RewriteCond %{HTTP_USER_AGENT} directory-agent + RewriteRule vary3.html vary4.html [L] + + RewriteCond %{HTTP:Accept} directory-accept [OR] + RewriteCond %{HTTP_REFERER} directory-referer + RewriteRule vary3.html vary4.html [L] + </Directory> + + # PR 58231: Vary:Host header mistakenly added to the response + RewriteCond %{HTTP_HOST} test1 + RewriteRule /modules/rewrite/vary1.html /modules/rewrite/vary2.html [L] + + RewriteCond %{HTTP:Host} test2 + RewriteRule /modules/rewrite/vary1.html /modules/rewrite/vary2.html [L] + + + ### Proxy pass-through to env.pl + RewriteRule ^/modules/rewrite/proxy2/(.*)$ http://@SERVERNAME@:@PORT@/modules/cgi/$1 [L,P] + + ### Pass-through conditional on QUERY_STRING + RewriteCond %{QUERY_STRING} horse=trigger + RewriteRule ^/modules/rewrite/proxy3/(.*)$ http://@SERVERNAME@:@PORT@/modules/cgi/$1 [L,P] + + ### Redirect, server context + RewriteRule ^/modules/rewrite/redirect.html$ http://@SERVERNAME@:@PORT@/foobar.html [L,R=301] + + RewriteRule ^/modules/rewrite/cookie/$ - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly] + RewriteRule ^/modules/rewrite/cookie/0 - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:0] + RewriteRule ^/modules/rewrite/cookie/false - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:false] + RewriteRule ^/modules/rewrite/cookie/lax - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:lax] + RewriteRule ^/modules/rewrite/cookie/none - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:none] + RewriteRule ^/modules/rewrite/cookie/foo - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:foo] + + <VirtualHost cve_2011_3368_rewrite> + DocumentRoot @SERVERROOT@/htdocs/modules/proxy + RewriteEngine On + RewriteRule (.*) http://localhost$1 [P] + </VirtualHost> + + # PR60478: pathological rewrite expansion + <IfVersion >= 2.4> + <Location /modules/rewrite/pr60478-rewrite-loop> + # This pair of RewriteRules will loop but should eventually 500 once we + # reach LimitRequestLine * 2 bytes. (In this case, @limitrequestline@ * 2 = @limitrequestlinex2@.) + RewriteRule ^(.*)X(.*)$ $1x$2 + # Don't run the test machine out of memory on failure, just stop the loop + RewriteCond expr "util_strlen(%{REQUEST_FILENAME}) -le @limitrequestlinex2@" + RewriteRule X - [N] + </Location> + </IfVersion> + +</IfModule> + + +<IfModule mod_proxy.c> + <VirtualHost proxy_http_reverse> + DocumentRoot @SERVERROOT@/htdocs/modules/proxy + ProxyPass /reverse/notproxy/ ! + ProxyPass /reverse/ http://@SERVERNAME@:@PORT@/ + ProxyPassReverse /reverse/ http://@SERVERNAME@:@PORT@/ + ProxyPassMatch ^/reverse-match/(.*)$ http://@SERVERNAME@:@PORT@/$1 + ProxyPassMatch ^/reverse-slash(/.*)?$ http://@SERVERNAME@:@PORT@$1 + ProxyPassReverseCookieDomain local remote + ProxyPassReverseCookiePath /local /remote + <IfVersion >= 2.4.7> + ProxyPass /uds/ unix:/tmp/test-ptf.sock|http: + </IfVersion> + <Location /reverse/locproxy/> + ProxyPass http://@SERVERNAME@:@PORT@/ + </Location> + <IfModule mod_setenvif.c> + SetEnvIf Request_URI "^/reverse/locproxy/index.html$" no-proxy + </IfModule> + </VirtualHost> + + <VirtualHost proxy_http_nofwd> + <IfVersion >= 2.3.10> + ProxyAddHeaders off + </IfVersion> + ProxyPass /reverse/ http://@SERVERNAME@:@PORT@/ + + <Proxy "*"> + # Noop config to trigger merging bug. + Require all granted + </Proxy> + </VirtualHost> + + <IfVersion >= 2.2.5> + <VirtualHost cve_2011_3368> + DocumentRoot @SERVERROOT@/htdocs/modules/proxy + ProxyPassMatch (.*) http://@SERVERNAME@$1 + </VirtualHost> + </IfVersion> +</IfModule> + +## +## @ACCESS_MODULE@ test config +## + +<IfModule @ACCESS_MODULE@> + <Directory @SERVERROOT@/htdocs/modules/access/htaccess> + AllowOverride Limit + </Directory> +</IfModule> + +## +## mod_cgi test config +## + +<IfModule @CGI_MODULE@> + AddHandler cgi-script .sh + AddHandler cgi-script .pl + ScriptLog @SERVERROOT@/logs/mod_cgi.log + ScriptLogLength 40960 + ScriptLogBuffer 256 + + <Directory @SERVERROOT@/htdocs/modules/cgi> + Options +ExecCGI + + <IfDefine APACHE2> + <Files acceptpathinfoon.sh> + AcceptPathInfo on + </Files> + <Files acceptpathinfooff.sh> + AcceptPathInfo off + </Files> + <Files acceptpathinfodefault.sh> + AcceptPathInfo default + </Files> + </IfDefine> + </Directory> + +</IfModule> + +## +## mod_alias test config +## + +<IfModule mod_alias.c> + Alias /alias @SERVERROOT@/htdocs/modules/alias + Alias /bogu /bogus/path/to/nothing + + AliasMatch /ali([0-9]) @SERVERROOT@/htdocs/modules/alias/$1.html + + Redirect permanent /perm http://@SERVERNAME@:@PORT@/alias + Redirect temp /temp http://@SERVERNAME@:@PORT@/alias + Redirect seeother /seeother http://@SERVERNAME@:@PORT@/alias + Redirect gone /gone + Redirect 403 /forbid + + RedirectMatch permanent /p([0-9]) http://@SERVERNAME@:@PORT@/alias/$1.html + RedirectMatch temp /t([0-9]) http://@SERVERNAME@:@PORT@/alias/$1.html + RedirectMatch seeother /s([0-9]) http://@SERVERNAME@:@PORT@/alias/$1.html + RedirectMatch gone /g([0-9]) + RedirectMatch 403 /f([0-9]) + + RedirectTemp /temp2 http://@SERVERNAME@:@PORT@/alias/index.html + RedirectPermanent /perm2 http://@SERVERNAME@:@PORT@/alias/index.html + + Redirect permanent /modules/alias/redirect-me http://@SERVERNAME@:@PORT@/modules/alias/5.html + + ScriptAlias /cgi @SERVERROOT@/htdocs/modules/alias + ScriptAliasMatch /aliascgi-(.*) @SERVERROOT@/htdocs/modules/alias/$1 + + <IfDefine APACHE2> + <IfVersion >= 2.4.19> + <LocationMatch /expr/ali(?<number>[0-9])> + Alias @SERVERROOT@/htdocs/modules/alias/%{env:MATCH_NUMBER}.html + </LocationMatch> + <LocationMatch /expr/aliascgi-(?<suffix>.*)> + ScriptAlias @SERVERROOT@/htdocs/modules/alias/%{env:MATCH_SUFFIX} + </LocationMatch> + <LocationMatch /expr/p(?<number>[0-9])> + Redirect permanent http://@SERVERNAME@:@PORT@/alias/%{env:MATCH_NUMBER}.html + </LocationMatch> + <LocationMatch /expr/t(?<number>[0-9])> + Redirect temp http://@SERVERNAME@:@PORT@/alias/%{env:MATCH_NUMBER}.html + </LocationMatch> + <LocationMatch /expr/s(?<number>[0-9])> + Redirect seeother http://@SERVERNAME@:@PORT@/alias/%{env:MATCH_NUMBER}.html + </LocationMatch> + <LocationMatch /expr/g([0-9])> + Redirect gone + </LocationMatch> + <LocationMatch /expr/f([0-9])> + Redirect 403 + </LocationMatch> + </IfVersion> + </IfDefine> +</IfModule> + + +<IfVersion >= 2.5.1> + <Location /redirect_relative/default> + Redirect /out-default + </Location> + <Location /redirect_relative/on> + RedirectRelative ON + Redirect /out-on + </Location> + <Location /redirect_relative/off> + RedirectRelative OFF + Redirect /out-off + </Location> + <Location /redirect_relative/off/fail> + Redirect fail-to-construct-url + </Location> +</IfVersion> + +Alias /manual @inherit_documentroot@/manual +<Location /manual> + Order deny,allow + Deny from all + Allow from @servername@ +</Location> + +## +## mod_asis test config +## + +<IfModule mod_asis.c> + <Directory @SERVERROOT@/htdocs/modules/asis> + AddHandler send-as-is asis + </Directory> +</IfModule> + +## +## mod_headers test config +## + +<IfModule mod_headers.c> + <Directory @SERVERROOT@/htdocs/modules/headers/htaccess> + AllowOverride All + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/headers/ssl> + AllowOverride All + </Directory> + + <VirtualHost mod_headers> + <Location /manual> + Header add mod_headers_foo bar + </Location> + </VirtualHost> + + # Should match anything mapped to disk + <DirectoryMatch ^> + Header append DMMATCH1 1 + </DirectoryMatch> +</IfModule> + +## +## mod_dir test config +## + +<IfModule mod_dir.c> + <Directory @SERVERROOT@/htdocs/modules/dir/htaccess> + DirectorySlash OFF + </Directory> + <IfVersion >= 2.5.1> + <Directory @SERVERROOT@/htdocs/modules/dir/htaccess/sub> + DirectorySlash NotFound + </Directory> + </IfVersion> + <Directory @SERVERROOT@/htdocs/modules/dir/htaccess> + AllowOverride Indexes + </Directory> +</IfModule> + +## +## mod_env test config +## + +<IfModule mod_env.c> + PassEnv APACHE_TEST_HOSTNAME + SetEnv ENV_TEST "mod_env test environment variable" + SetEnv ENV_TEST_EMPTY + UnsetEnv UNSET + + PassEnv APACHE_TEST_HOSTTYPE + UnsetEnv APACHE_TEST_HOSTTYPE + + SetEnv NOT_HERE "this will not be here" + UnsetEnv NOT_HERE + + <Directory @SERVERROOT@/htdocs/modules/env> + Options +Includes + </Directory> +</IfModule> + +## +## mod_setenvif test config +## + +<IfModule mod_setenvif.c> + <Directory @SERVERROOT@/htdocs/modules/setenvif/htaccess> + Options +Includes + AllowOverride All + </Directory> +</IfModule> + +## +## mod_dav test config +## + +<IfModule mod_dav.c> + <IfVersion < 2.5.1> + DAVLockDB @SERVERROOT@/logs/davlock.db + </IfVersion> + + <Directory @SERVERROOT@/htdocs/modules/dav> + DAV On + </Directory> +</IfModule> + +## +## mod_autoindex test config +## + +<IfModule mod_autoindex.c> + <Directory @SERVERROOT@/htdocs/modules/autoindex/htaccess> + Options +Indexes + AllowOverride Indexes + </Directory> + <Directory @SERVERROOT@/htdocs/modules/autoindex2> + Options +Indexes + AllowOverride All + </Directory> +</IfModule> + +## +## LimitRequest* directive testing +## + +LimitRequestLine @limitrequestline@ +LimitRequestFieldSize 1024 +LimitRequestFields 32 +<Directory @SERVERROOT@/htdocs/apache/limits> + LimitRequestBody 65536 +</Directory> + +## +## mod_echo test config +## + +<IfModule mod_echo.c> + <VirtualHost mod_echo> + ProtocolEcho On + </VirtualHost> + + <IfModule @ssl_module@> + <VirtualHost mod_echo_ssl> + ProtocolEcho On + SSLEngine On + </VirtualHost> + </IfModule> +</IfModule> + +## +## mod_deflate test config +## +<IfDefine APACHE2> + <IfModule mod_deflate.c> + <Directory @SERVERROOT@/htdocs/modules/deflate> + SetOutputFilter DEFLATE + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/deflate/ssi> + Options +Includes + DirectoryIndex default.html + AddOutputFilter INCLUDES shtml + SetOutputFilter DEFLATE + </Directory> + + <IfModule mod_bucketeer.c> + <Directory @SERVERROOT@/htdocs/modules/deflate/bucketeer> + SetOutputFilter BUCKETEER;DEFLATE + </Directory> + </IfModule> + + + <Location /modules/cgi/not-modified.pl> + SetOutputFilter DEFLATE + </Location> + + <Location /modules/deflate/echo_post> + SetInputFilter DEFLATE + SetHandler echo_post + </Location> + </IfModule> +</IfDefine> + +### pr17629.t +<IfModule mod_case_filter.c> + <Location /modules/cgi/redirect.pl> + SetOutputFilter CASEFILTER + </Location> +</IfModule> + + +## +## Test config for security issues +## +<Directory @SERVERROOT@/htdocs/security> + Options +Includes + AllowOverride All + Order allow,deny + Allow from all + + # for CVE-2005-3352 test: + AddHandler imap-file map +</Directory> + +<Directory @SERVERROOT@/htdocs/security/CAN-2004-0811> + Options +Indexes +</Directory> + +<Directory @SERVERROOT@/htdocs/security/CAN-2004-0811/sub> + Satisfy Any +</Directory> + +## +## Digest test config +## +<IfDefine APACHE2> + <IfModule mod_auth_digest.c> + Alias /digest @DocumentRoot@ + <Location /digest> + Require valid-user + AuthType Digest + AuthName realm1 + # 2.0 + <IfModule mod_auth.c> + AuthDigestFile @ServerRoot@/realm1 + </IfModule> + # 2.1 + <IfModule mod_authn_file.c> + AuthUserFile realm1 + </IfModule> + </Location> + SetEnvIf X-Browser "MSIE" AuthDigestEnableQueryStringHack=On + </IfModule> +</IfDefine> + +## +## authz_core test config: authz by user or by env (modules/aaa.t) +## +<IfDefine APACHE2> + <IfModule mod_authz_core.c> + <IfModule mod_authn_core.c> + <IfModule mod_authn_file.c> + <IfModule mod_authz_host.c> + <IfModule mod_auth_digest.c> + Alias /authz/digest @DocumentRoot@ + <Location /authz/digest> + <RequireAny> + Require valid-user + Require env allowed + </RequireAny> + AuthType Digest + AuthName realm2 + AuthUserFile realm2 + </Location> + </IfModule> + <IfModule mod_auth_basic.c> + Alias /authz/basic @DocumentRoot@ + <Location /authz/basic> + <RequireAny> + Require valid-user + Require env allowed + </RequireAny> + AuthType Basic + AuthName basic1 + AuthUserFile basic1 + </Location> + </IfModule> + <IfVersion >= 2.3.11> + <IfModule mod_auth_basic.c> + Alias /authz/fail/401 @DocumentRoot@ + Alias /authz/fail/403 @DocumentRoot@ + <Location /authz/fail> + Require user foo + AuthType Basic + AuthName basic1 + AuthUserFile basic1 + </Location> + <Location /authz/fail/403> + AuthzSendForbiddenOnFailure On + </Location> + </IfModule> + </IfVersion> + <IfModule mod_auth_form.c> + <IfModule mod_session_cookie.c> + Alias /authz/form @DocumentRoot@ + <Location /authz/form> + AuthFormLoginRequiredLocation http://@SERVERNAME@:@PORT@/authz/login.html + AuthFormLoginSuccessLocation http://@SERVERNAME@:@PORT@/authz/form/ + AuthFormProvider file + AuthType Form + AuthUserFile form1 + AuthName form1 + Session On + SessionCookieName session path=/ + <RequireAny> + Require valid-user + Require env allowed + </RequireAny> + </Location> + <Location /authz/form/dologin.html> + SetHandler form-login-handler + Require all granted + </Location> + </IfModule> + </IfModule> + SetEnvIf X-Allowed "yes" allowed + </IfModule> + </IfModule> + </IfModule> + </IfModule> +</IfDefine> + +## +## authz_core test config: authz merging (modules/authz_core.t) +## +<IfDefine APACHE2> + <IfModule mod_authz_core.c> + <IfModule mod_authn_core.c> + <IfModule mod_authz_host.c> + <Directory @DocumentRoot@/authz_core/> + AllowOverride all + </Directory> + + SetEnvIf X-Allowed1 "yes" allowed1 + SetEnvIf X-Allowed2 "yes" allowed2 + SetEnvIf X-Allowed3 "yes" allowed3 + SetEnvIf X-Allowed4 "yes" allowed4 + </IfModule> + </IfModule> + </IfModule> +</IfDefine> + +## +## Configuration for t/modules/ldap.t. +## +<IfDefine LDAP> + Alias /modules/ldap/simple @DocumentRoot@ + Alias /modules/ldap/group @DocumentRoot@ + Alias /modules/ldap/refer @DocumentRoot@ + + # Simple user lookup + <Location /modules/ldap/simple> + AuthLDAPURL "ldap://localhost:8389/dc=example,dc=com?uid" + AuthLDAPBindDN "cn=httpd,dc=example,dc=com" + AuthLDAPBindPassword mod_authnz_ldap + AuthType Basic + AuthName ldap-simple@httpd.apache.org + AuthBasicProvider ldap + Require valid-user + </Location> + # Static group configuration + <Location /modules/ldap/group> + AuthLDAPURL "ldap://localhost:8389/dc=example,dc=com?uid" + AuthLDAPBindDN "cn=httpd,dc=example,dc=com" + AuthLDAPBindPassword mod_authnz_ldap + AuthType Basic + AuthName ldap-group@httpd.apache.org + AuthBasicProvider ldap + Require ldap-group cn=Group One,dc=example,dc=com + </Location> + # Referral configuration -- the second user is only found if + # httpd follows the referral. + <Location /modules/ldap/refer> + AuthLDAPURL "ldap://localhost:8389/dc=example,dc=com?uid" + AuthLDAPBindDN "cn=httpd,dc=example,dc=com" + AuthLDAPBindPassword mod_authnz_ldap + AuthType Basic + AuthName ldap-refer@httpd.apache.org + AuthBasicProvider ldap + Require ldap-group cn=Subgroup,ou=dept,dc=example,dc=com + </Location> +</IfDefine> + +## +## ErrorDocument handling +## create it's own virtual host so it doesn't interfere +## with other tests for 404 messages +## +<VirtualHost _default_:error_document> + ErrorDocument 404 "per-server 404 + + <Location /redefine> + ErrorDocument 404 "per-dir 404 + </Location> + + <Location /inherit> + # nothing here + </Location> + + <Location /bounce> + ErrorDocument 404 /modules/expires/expire.html + </Location> + + <Location /restore> + # special "default" value = restore canned error response + ErrorDocument 404 default + </Location> + + <Directory @DocumentRoot@/apache> + ErrorDocument 404 "testing merge + </Directory> + + <Directory @DocumentRoot@/apache/etag> + # 404 should be inherited from /apache + ErrorDocument 500 "hmph + </Directory> + +</VirtualHost> + +<Directory @DocumentRoot@/modules/filter/byterange/pr61860> + Header always set TestDuplicateHeader "shouldnotbeduplicated" +</Directory> + +<IfModule mod_bucketeer.c> + <Directory @DocumentRoot@/apache/chunked> + SetOutputFilter BUCKETEER + </Directory> +</IfModule> + +<IfModule mod_status.c> + ExtendedStatus On +</IfModule> + +<IfModule mod_filter.c> + <IfModule mod_case_filter.c> + <Location /modules/cgi/xother.pl> + FilterDeclare xother CONTENT_SET + <IfVersion >= 2.3.9> + FilterProvider xother CASEFILTER "resp('X-Foo') == 'bar'" + </IfVersion> + <IfVersion < 2.3.0> + FilterProvider xother CASEFILTER resp=X-Foo bar + </IfVersion> + FilterChain xother + </Location> + </IfModule> + + <Directory @SERVERROOT@/htdocs/modules/filter/pr49328> + Options +Includes + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + + <IfModule mod_deflate.c> + FilterDeclare pr49328 CONTENT_SET + <IfVersion < 2.3.0> + FilterProvider pr49328 DEFLATE resp=Content-Type $text/ + </IfVersion> + <IfVersion >= 2.3.0> + <IfVersion < 2.3.9> + FilterProvider pr49328 DEFLATE "$content-type = /text\//" + </IfVersion> + </IfVersion> + <IfVersion >= 2.3.9> + FilterProvider pr49328 DEFLATE "%{CONTENT_TYPE} =~ m!text/!" + </IfVersion> + FilterChain pr49328 + </IfModule> + </Directory> + <Directory @SERVERROOT@/htdocs/modules/filter/bytype> + <IfModule mod_deflate.c> + AddOutputFilterByType DEFLATE application/xml + AddOutputFilterByType DEFLATE text/xml + AddOutputFilterByType DEFLATE text/css + </IfModule> + <IfModule mod_case_filter.c> + AddOutputFilterByType CASEFILTER application/xml + AddOutputFilterByType CASEFILTER text/xml + AddOutputFilterByType CASEFILTER text/plain + </IfModule> + </Directory> +</IfModule> + +## +## mod_dumpio configuration +## +<IfModule mod_dumpio.c> + DumpIOInput on + DumpIOOutput on + LogLevel dumpio:trace7 +</IfModule> + +## +## LogLevel configuration +## +<IfDefine APACHE2> + <IfVersion >= 2.3.6> + <Directory @SERVERROOT@/htdocs/apache/loglevel/core_crit> + LogLevel info core:crit + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/core_info> + LogLevel crit core:info + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/crit> + LogLevel crit + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/crit/core_info> + LogLevel core:info + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/crit/core_info/crit> + LogLevel crit + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/info> + LogLevel info + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/info/core_crit> + LogLevel core:crit + </Directory> + <Directory @SERVERROOT@/htdocs/apache/loglevel/info/core_crit/info> + LogLevel info + </Directory> + </IfVersion> +</IfDefine> + +<Directory @SERVERROOT@/htdocs/apache/cfg_getline/> + AllowOverride All + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + Options +Includes +</Directory> + +<Directory @SERVERROOT@/htdocs/modules/substitute/> + AllowOverride All +</Directory> + +## +## expression parser test config +## + +<IfVersion >= 2.3.9> + <Directory @SERVERROOT@/htdocs/apache/expr/> + AllowOverride All + <IfModule mod_log_debug.c> + AllowOverrideList LogMessage + </IfModule> + </Directory> +</IfVersion> + +<IfDefine APACHE2> + <IfVersion >= 2.3.11> + <IfModule mod_headers.c> + <IfModule mod_proxy.c> + ProxyPass /if_sec/proxy/ http://@SERVERNAME@:@PORT@/ + + # Directory context + <Directory @SERVERROOT@/htdocs/if_sec/dir/> + <If "-n %{REQ:In-If1}"> + Header merge Out-Trace dir1 + <If "-n %{REQ:In-If11}"> + Header merge Out-Trace nested11 + <If "-n %{REQ:In-If111}"> + Header merge Out-Trace nested111 + </If> + <Elseif "-n %{REQ:In-If112}"> + Header merge Out-Trace nested112 + </Elseif> + <Else> + Header merge Out-Trace nested113 + </Else> + </If> + </If> + <If "-n %{REQ:In-If2}"> + Header merge Out-Trace dir2 + </If> + <Files *.txt> + <If "-n %{REQ:In-If1}"> + Header merge Out-Trace dir_files1 + </If> + </Files> + </Directory> + + # Location context + <Location /if_sec/proxy/> + <If "-n %{REQ:In-If1}"> + Header merge Out-Trace locp1 + </If> + <If "-n %{REQ:In-If2}"> + Header merge Out-Trace locp2 + </If> + </Location> + <Location /if_sec/loc/> + <If "-n %{REQ:In-If1}"> + Header merge Out-Trace loc1 + <If "-n %{REQ:In-If11}"> + Header merge Out-Trace nested11 + <If "-n %{REQ:In-If111}"> + Header merge Out-Trace nested111 + </If> + <Elseif "-n %{REQ:In-If112}"> + Header merge Out-Trace nested112 + </Elseif> + <Else> + Header merge Out-Trace nested113 + </Else> + </If> + </If> + <If "-n %{REQ:In-If2}"> + Header merge Out-Trace loc2 + </If> + </Location> + + # Files context + <Files *.if_test> + <If "-n %{REQ:In-If2}"> + Header merge Out-Trace files2 + <If "-n %{REQ:In-If11}"> + Header merge Out-Trace nested11 + <If "-n %{REQ:In-If111}"> + Header merge Out-Trace nested111 + </If> + <Elseif "-n %{REQ:In-If112}"> + Header merge Out-Trace nested112 + </Elseif> + <Else> + Header merge Out-Trace nested113 + </Else> + </If> + </If> + </Files> + + # Global context + <If "-n %{REQ:In-If1}"> + Header merge Out-Trace global1 + <If "-n %{REQ:In-If11}"> + Header merge Out-Trace nested11 + <If "-n %{REQ:In-If111}"> + Header merge Out-Trace nested111 + </If> + <Elseif "-n %{REQ:In-If112}"> + Header merge Out-Trace nested112 + </Elseif> + <Else> + Header merge Out-Trace nested113 + </Else> + </If> + </If> + </IfModule> + </IfModule> + </IfVersion> +</IfDefine> + +<IfDefine APACHE2> + <IfVersion >= 2.3.15> + <IfModule mod_alias.c> + AliasMatch /maxranges/([^/])+/ @SERVERROOT@/htdocs/apache/chunked/byteranges.txt + <Location /maxranges/none/> + MaxRanges none + </Location> + <Location /maxranges/default-explicit/> + MaxRanges default + </Location> + <Location /maxranges/1/> + MaxRanges 1 + </Location> + <Location /maxranges/2/> + MaxRanges 2 + </Location> + <Location /maxranges/1/merge/none/> + MaxRanges none + </Location> + <Location /maxranges/unlimited/> + MaxRanges unlimited + </Location> + </IfModule> + </IfVersion> + <IfVersion >= 2.2.21> + <IfModule mod_alias.c> + AliasMatch /maxranges/([^/])+/ @SERVERROOT@/htdocs/apache/chunked/byteranges.txt + <Location /maxranges/none/> + MaxRanges none + </Location> + <Location /maxranges/default-explicit/> + MaxRanges default + </Location> + <Location /maxranges/1/> + MaxRanges 1 + </Location> + <Location /maxranges/2/> + MaxRanges 2 + </Location> + <Location /maxranges/1/merge/none/> + MaxRanges none + </Location> + <Location /maxranges/unlimited/> + MaxRanges unlimited + </Location> + </IfModule> + </IfVersion> + +</IfDefine> + +<IfModule mod_lua.c> + AddHandler lua-script .lua + LuaHookTranslateName @SERVERROOT@/htdocs/modules/lua/translate.lua translate_name + <Location /modules/lua/translate-inherit-after> + LuaHookTranslateName @SERVERROOT@/htdocs/modules/lua/translate.lua translate_name2 + LuaInherit parent-last + </Location> + <Location /modules/lua/translate-inherit-before> + LuaHookTranslateName @SERVERROOT@/htdocs/modules/lua/translate.lua translate_name2 + LuaInherit parent-first + </Location> + <Location /modules/lua/translate-inherit-default-before> + LuaHookTranslateName @SERVERROOT@/htdocs/modules/lua/translate.lua translate_name2 + # default: LuaInherit parent-first + </Location> + + # Filtering tests + LuaOutputFilter LUA_OUTPUT @SERVERROOT@/htdocs/modules/lua/filters.lua output_filter + Alias /modules/lua/filtered @DocumentRoot@ + <Location /modules/lua/filtered/> + SetOutputFilter LUA_OUTPUT + </Location> + +</IfModule> + +# +# Strict HTTP mode test config +# +<IfDefine APACHE2> + <IfVersion >= 2.2.32> + <Directory @SERVERROOT@/htdocs/apache/http_strict> + Options +ExecCGI + AddHandler cgi-script .pl + </Directory> + <VirtualHost _default_:http_unsafe> + DocumentRoot @SERVERROOT@/htdocs/ + HttpProtocolOptions Unsafe Allow0.9 + <IfModule mod_headers.c> + <Location /regression-header> + # Use two examples to ensure multiple bad headers are caught + # Note the vertical tab (^K or 0x0B) embedded in the header value + Header always set X-Bad "verticaltab" + Header always set X?Bad "badly named header" + </Location> + </IfModule> + </VirtualHost> + <VirtualHost _default_:http_strict> + DocumentRoot @SERVERROOT@/htdocs/ + HttpProtocolOptions Strict Require1.0 RegisteredMethods + <IfModule mod_headers.c> + <Location /regression-header> + # Use two examples to ensure multiple bad headers are caught + # Note the vertical tab (^K or 0x0B) embedded in the header value + Header always set X-Bad "verticaltab" + Header always set X?Bad "badly named header" + </Location> + </IfModule> + </VirtualHost> + </IfVersion> +</IfDefine> + +# +# mod_brotli test config +# +<IfDefine APACHE2> + <IfModule mod_alias.c> + <IfModule mod_brotli.c> + # Reuse existing data for mod_deflate + Alias /only_brotli @SERVERROOT@/htdocs/modules/deflate + <Location /only_brotli> + SetOutputFilter BROTLI_COMPRESS + </Location> + + <IfModule mod_deflate.c> + Alias /brotli_and_deflate @SERVERROOT@/htdocs/modules/deflate + <Location /brotli_and_deflate> + SetOutputFilter BROTLI_COMPRESS;DEFLATE + </Location> + </IfModule> + </IfModule> + </IfModule> +</IfDefine> + +# +# <IfFile> test config (see t/apache/iffile.t) +# +<IfDefine APACHE2> + <IfVersion >= 2.4.34> + <IfModule mod_headers.c> + + <Location /apache/iffile> + # First, the IfFiles that should succeed. + <IfFile htdocs/apache/iffile/document> + Header merge X-Out success1 + </IfFile> + <IfFile !htdocs/apache/iffile/doesnotexist> + Header merge X-Out success2 + </IfFile> + <IfFile htdocs/apache/iffile> + Header merge X-Out success3 + </IfFile> + <IfFile @SERVERROOT@/htdocs/apache/iffile/document> + Header merge X-Out success4 + </IfFile> + <IfFile "htdocs/apache/iffile/document"> + Header merge X-Out success5 + </IfFile> + # Followed by the IfFiles that should fail. + <IfFile !htdocs/apache/iffile/document> + Header merge X-Out fail1 + </IfFile> + <IfFile htdocs/apache/iffile/doesnotexist> + Header merge X-Out fail2 + </IfFile> + <IfFile !htdocs/apache/iffile> + Header merge X-Out fail3 + </IfFile> + <IfFile !@SERVERROOT@/htdocs/apache/iffile/document> + Header merge X-Out fail4 + </IfFile> + <IfFile !"htdocs/apache/iffile/document"> + Header merge X-Out fail5 + </IfFile> + </Location> + + </IfModule> + </IfVersion> +</IfDefine> + + +# +# t/modules/ext_filter.t test config +# +<IfDefine APACHE2> + <IfModule mod_ext_filter.c> + ExtFilterDefine foo-to-bar mode=output cmd="@SERVERROOT@/htdocs/modules/ext_filter/eval-cmd.pl s,foo,bar,g" + ExtFilterDefine ifoo-to-bar mode=input cmd="@SERVERROOT@/htdocs/modules/ext_filter/eval-cmd.pl s,foo,bar,g" + ExtFilterDefine sleepy-cat-out mode=output cmd=@SERVERROOT@/htdocs/modules/ext_filter/sleepycat.pl + ExtFilterDefine sleepy-cat-in mode=input cmd=@SERVERROOT@/htdocs/modules/ext_filter/sleepycat.pl + AliasMatch /apache/extfilter/[^/]+/(.*) @DocumentRoot@/$1 + + <Location /apache/extfilter/out-foo> + SetOutputFilter foo-to-bar + </Location> + + <Location /apache/extfilter/out-slow> + SetOutputFilter sleepy-cat-out + </Location> + + <Location /apache/extfilter/in-foo> + SetInputFilter ifoo-to-bar + </Location> + + <Location /apache/extfilter/out-limit> + SetOutputFilter foo-to-bar + LimitRequestBody 6 + </Location> + +</IfModule> +</IfDefine> + +## +## mod_ssl_ct configuration +## +<IfModule mod_ssl_ct.c> + # If mod_ssl_ct is loaded, CTSCTStorage is needed to pass the configtest. + CTSCTStorage . +</IfModule> + +## +## mod_remote_ip configuration +## +<IfModule mod_remoteip.c> + <VirtualHost remote_ip> + DocumentRoot @SERVERROOT@/htdocs/modules/remoteip + <IfVersion >= 2.4.30> + RemoteIPProxyProtocol On + </IfVersion> + </VirtualHost> +</IfModule> + + +<IfModule mod_ratelimit.c> + AliasMatch ^/apache/ratelimit/autoindex/$ @SERVERROOT@/htdocs/ + AliasMatch ^/apache/ratelimit/$ @SERVERROOT@/htdocs/index.html + <Location /apache/ratelimit/> + Options +Indexes + SetOutputFilter RATE_LIMIT + <IfModule mod_env.c> + SetEnv rate-limit 1024 + SetEnv rate-initial-burst 512 + </IfModule> + </Location> + <Location /apache/ratelimit/chunk> + SetHandler random_chunk + </Location> +</IfModule> + +<IfModule mod_reflector.c> + <Location /apache/reflector_nodeflate/> + SetHandler reflector + # Do not set any filter + ReflectorHeader header2reflect + ReflectorHeader header2update header2updateUpdated + </Location> + <Location /apache/reflector_deflate/> + SetHandler reflector + SetOutputFilter DEFLATE + ReflectorHeader header2reflect + ReflectorHeader header2update header2updateUpdated + </Location> +</IfModule> + +<IfModule mod_allowmethods.c> + <Directory @SERVERROOT@/htdocs/modules/allowmethods> + Options +Indexes + </Directory> + <IfVersion >= 2.5.1> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/NoPost> + AllowMethods -POST + </Directory> + </IfVersion> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Get> + AllowMethods GET + </Directory> + <IfVersion >= 2.5.1> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Get/post> + AllowMethods +POST + </Directory> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Get/none> + AllowMethods -GET + </Directory> + </IfVersion> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Head> + AllowMethods HEAD + </Directory> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Post> + AllowMethods POST + </Directory> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Post/reset> + AllowMethods reset + </Directory> +</IfModule> + +<IfModule mod_buffer.c> + <IfModule mod_reflector.c> + <Location /apache/buffer_in/> + SetHandler reflector + SetInputFilter BUFFER + </Location> + <Location /apache/buffer_out/> + SetHandler reflector + SetOutputFilter BUFFER + </Location> + <Location /apache/buffer_in_out/> + SetHandler reflector + SetInputFilter BUFFER + SetOutputFilter BUFFER + </Location> + </IfModule> +</IfModule> + +<IfModule mod_data.c> + <Directory @SERVERROOT@/htdocs/modules/data/> + SetOutputFilter DATA + </Directory> +</IfModule> + +<IfModule mod_usertrack.c> + <Directory @SERVERROOT@/htdocs/modules/usertrack/> + CookieTracking on + CookieName usertrack_test + CookieExpires "60 seconds" + </Directory> +</IfModule> + +<IfModule mod_session_cookie.c> + <Directory @SERVERROOT@/htdocs/modules/session_cookie> + Session On + SessionCookieName thisisatest path=/ + SessionMaxAge 1 + </Directory> +</IfModule> + +<IfModule mod_speling.c> + <Directory @SERVERROOT@/htdocs/modules/speling/nocase/> + CheckSpelling on + </Directory> + <Directory @SERVERROOT@/htdocs/modules/speling/caseonly/> + CheckSpelling on + CheckCaseOnly on + </Directory> +</IfModule> + +<IfModule mod_actions.c> + ScriptAlias /cgi_mod_actions @SERVERROOT@/htdocs/modules/cgi + <Location /mod_actions> + SetHandler my-handler + Action my-handler "/cgi_mod_actions/perl_echo.pl" virtual + </Location> + + <Directory @SERVERROOT@/htdocs/modules/actions/action> + AddHandler my-file-type1 .xyz1 + Action my-file-type1 "/cgi_mod_actions/perl_echo.pl" + AddHandler my-file-type2 .xyz2 + Action my-file-type2 "/cgi_mod_actions/perl_echo.pl" virtual + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/actions/script> + Script GET "/cgi_mod_actions/perl_echo.pl" + Script POST "/cgi_mod_actions/perl_post.pl" + </Directory> +</IfModule> + +<IfModule mod_heartbeat.c> + <IfModule mod_heartmonitor.c> + HeartbeatListen 239.0.0.1:27999 + HeartbeatAddress 239.0.0.1:27999 + </IfModule> +</IfModule> + +# +# t/modules/sed.t test config +# +<IfModule mod_sed.c> + AliasMatch /apache/sed/[^/]+/(.*) @DocumentRoot@/$1 + + <Location /apache/sed/> + AddOutputFilter sed .html + </Location> + + <Location /apache/sed/out-foo> + OutputSed "s/foo/bar/g" + </Location> +</IfModule> + + diff --git a/debian/perl-framework/t/conf/http2.conf.in b/debian/perl-framework/t/conf/http2.conf.in new file mode 100644 index 0000000..2e6ca67 --- /dev/null +++ b/debian/perl-framework/t/conf/http2.conf.in @@ -0,0 +1,105 @@ +## +## mod_http2 test config +## + +<IfDefine APACHE2> + <IfModule http2_module> + + LogLevel http2:debug + + <VirtualHost h2c> + Protocols h2c http/1.1 + + <IfModule @CGI_MODULE@> + <Directory @SERVERROOT@/htdocs/modules/h2> + Options +ExecCGI + AddHandler cgi-script .pl + + </Directory> + </IfModule> + + <Location /modules/h2/hello.pl> + </Location> + <IfModule mod_rewrite.c> + RewriteEngine on + RewriteRule ^/modules/h2/latest.tar.gz$ /modules/h2/xxx-1.0.2a.tar.gz [R=302,NC] + </IfModule> + + </VirtualHost> + + <IfModule @ssl_module@> + + <VirtualHost @SERVERNAME@:h2> + Protocols h2 http/1.1 + H2Direct on + + SSLEngine on + SSLCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLCACertificatePath @ServerRoot@/conf/ssl + SSLCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl + SSLCARevocationCheck chain + + # taken from https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations + # + SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK + SSLProtocol All -SSLv2 -SSLv3 + SSLOptions +StdEnvVars + + <IfVersion >= 2.4.18> + # need this off as long as we ran on old openssl + H2ModernTLSOnly off + </IfVersion> + + <IfModule @CGI_MODULE@> + <Directory @SERVERROOT@/htdocs/modules/h2> + Options +ExecCGI + AddHandler cgi-script .pl + </Directory> + </IfModule> + + <Location /modules/h2/hello.pl> + </Location> + <IfModule mod_rewrite.c> + RewriteEngine on + RewriteRule ^/modules/h2/latest.tar.gz$ /modules/h2/xxx-1.0.2a.tar.gz [R=302,NC] + </IfModule> + + </VirtualHost> + + <VirtualHost noh2.example.org:h2> + Protocols http/1.1 + H2Direct off + </VirtualHost> + + <VirtualHost test.example.org:h2> + Protocols h2 http/1.1 + H2Direct on + + SSLEngine on + SSLCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLCACertificatePath @ServerRoot@/conf/ssl + SSLCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl + SSLCARevocationCheck chain + + # taken from https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations + # + SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK + SSLProtocol All -SSLv2 -SSLv3 + SSLOptions +StdEnvVars + + </VirtualHost> + + <VirtualHost test2.example.org:h2> + Protocols http/1.1 h2 + H2Direct on + </VirtualHost> + + <VirtualHost test-ser.example.org:h2> + </VirtualHost> + + </ifModule> + + </IfModule> + +</IfDefine> + diff --git a/debian/perl-framework/t/conf/include-ssi-exec.conf.in b/debian/perl-framework/t/conf/include-ssi-exec.conf.in new file mode 100644 index 0000000..42b72f9 --- /dev/null +++ b/debian/perl-framework/t/conf/include-ssi-exec.conf.in @@ -0,0 +1,499 @@ +# Test cases for Includes options inheritance, see test case +# t/security/CVE-2009-1195.t + +<IfDefine !APACHE1> +<IfVersion >= 2.1.0> +<IfModule mod_include.c> + +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/1"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/2"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/3"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/4"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/5"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/6"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/7"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/8"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/9"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/10"> + Options None + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/11"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/12"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/13"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/14"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/15"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/16"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/17"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/18"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/19"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/20"> + Options None + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/21"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/22"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/23"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/24"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/25"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/26"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/27"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/28"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/29"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/30"> + Options None + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/31"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/32"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/33"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/34"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/35"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/36"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/37"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/38"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/39"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/40"> + Options None + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/41"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/42"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/43"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/44"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/45"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/46"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/47"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/48"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/49"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/50"> + Options IncludesNoExec + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/51"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/52"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/53"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/54"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/55"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/56"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/57"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/58"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/59"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/60"> + Options IncludesNoExec + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/61"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/62"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/63"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/64"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/65"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/66"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/67"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/68"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/69"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/70"> + Options IncludesNoExec + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/71"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/72"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/73"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/74"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/75"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/76"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/77"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/78"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/79"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/80"> + Options IncludesNoExec + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/81"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/82"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/83"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/84"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/85"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/86"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/87"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/88"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/89"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/90"> + Options Includes + AllowOverride Options=IncludesNoExec +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/91"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/92"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/93"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/94"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/95"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/96"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/97"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/98"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/99"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/100"> + Options Includes + AllowOverride Options=Includes +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/101"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/102"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/103"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/104"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/105"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/106"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/107"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/108"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/109"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/110"> + Options Includes + AllowOverride All +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/111"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/112"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/113"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/114"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/115"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/116"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/117"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/118"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/119"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/120"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/121"> + Options Includes + AllowOverride None +</Directory> +<Directory "@SERVERROOT@/htdocs/modules/include/ssi-exec/120/subdir"> +# Just a dummy directive that is always available to make this a valid block + FileETag All +</Directory> + +</IfModule> +</IfVersion> +</IfDefine> diff --git a/debian/perl-framework/t/conf/include.conf.in b/debian/perl-framework/t/conf/include.conf.in new file mode 100644 index 0000000..349f565 --- /dev/null +++ b/debian/perl-framework/t/conf/include.conf.in @@ -0,0 +1,82 @@ +## +## mod_include test config +## + +<IfModule mod_include.c> + + AddType text/html .shtml + + <IfDefine APACHE1> + AddHandler server-parsed .shtml + </IfDefine> + <IfDefine APACHE2> + AddOutputFilter INCLUDES .shtml + </IfDefine> + + <Directory @SERVERROOT@/htdocs/modules/include> + <IfVersion >= 2.3.13> + SSILegacyExprParser on + </IfVersion> + Options +IncludesNOEXEC + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/include/apexpr> + <IfVersion >= 2.3.13> + SSILegacyExprParser off + </IfVersion> + Options +IncludesNOEXEC + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/include/xbithack/on> + Options +IncludesNOEXEC + XBitHack on + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/include/xbithack/both> + Options Includes + XBitHack on + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/include/xbithack/full> + Options +IncludesNOEXEC + XBitHack full + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/include/exec/on> + Options Includes + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/include/mod_request> + Options Includes + KeptBodySize 32 + </Directory> + + <IfDefine APACHE2> + <IfModule mod_bucketeer.c> + <Directory @SERVERROOT@/htdocs/modules/include/bucketeer> + SetOutputFilter BUCKETEER + </Directory> + </IfModule> + </IfDefine> + + <VirtualHost ssi-default:mod_include> + # fallback host + </VirtualHost> + + <IfDefine APACHE2> + <VirtualHost retagged1:mod_include> + SSIStartTag ---> + SSIEndTag ---> + </VirtualHost> + + <VirtualHost retagged2:mod_include> + SSIStartTag ---> + SSIEndTag printenw + </VirtualHost> + + <VirtualHost echo1:mod_include> + SSIUndefinedEcho "<!-- pass undefined echo -->" + </VirtualHost> + </IfDefine> + +</IfModule> diff --git a/debian/perl-framework/t/conf/proxy.conf.in b/debian/perl-framework/t/conf/proxy.conf.in new file mode 100644 index 0000000..a199ca8 --- /dev/null +++ b/debian/perl-framework/t/conf/proxy.conf.in @@ -0,0 +1,194 @@ +#t/TEST -proxy + +<IfModule mod_proxy.c> + + <VirtualHost _default_:mod_proxy> + ProxyRequests On + </VirtualHost> + + <IfVersion >= 2.4.49> + # Test the mapping. + ProxyPass /mapping http://@SERVERNAME@:@PORT@/servlet mapping=servlet + </IfVersion> + +</IfModule> + +<IfModule mod_proxy_hcheck.c> + # Suppress the error_log spam every 100ms watchdog cycle at trace5 + LogLevel proxy_hcheck:trace4 +</IfModule> + +<IfModule mod_proxy_balancer.c> + + <VirtualHost proxy_http_bal1> + DocumentRoot @SERVERROOT@/htdocs + </VirtualHost> + + <VirtualHost proxy_http_bal2> + DocumentRoot @SERVERROOT@/htdocs + </VirtualHost> + + <VirtualHost proxy_http_balancer> + + <IfModule mod_lbmethod_byrequests.c> + <Proxy balancer://foo1> + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 + </Proxy> + ProxySet balancer://foo1 lbmethod=byrequests + <Location /baltest1> + ProxyPass balancer://foo1/ + </Location> + </IfModule> + + <IfModule mod_lbmethod_bytraffic.c> + <Proxy balancer://foo2> + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 + </Proxy> + ProxySet balancer://foo2 lbmethod=bytraffic + <Location /baltest2> + ProxyPass balancer://foo2/ + </Location> + </IfModule> + + <IfModule mod_lbmethod_bybusyness.c> + <Proxy balancer://foo3> + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 + </Proxy> + ProxySet balancer://foo3 lbmethod=bybusyness + <Location /baltest3> + ProxyPass balancer://foo3/ + </Location> + </IfModule> + + <IfModule mod_lbmethod_heartbeat.c> + <Proxy balancer://foo4> + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 + </Proxy> + ProxySet balancer://foo4 lbmethod=heartbeat + <Location /baltest4> + # TODO heartbeat needs additional configuration to have it work + ProxyPass balancer://foo4/ + </Location> + </IfModule> + + ## PR 45434 tests + <Proxy balancer://pr45434> + BalancerMember http://@SERVERNAME@:@PORT@/modules + </Proxy> + + ProxyPass /pr45434 balancer://pr45434/alias + ProxyPassReverse /pr45434 balancer://pr45434/alias + + <Proxy balancer://failover> + BalancerMember http://@SERVERNAME@:@NextAvailablePort@ loadfactor=1 retry=1ms + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 status=H + </Proxy> + ProxyPassMatch ^/baltest_echo_post balancer://failover/echo_post + + ## Test "dynamic balancer + <Proxy balancer://dynproxy> + ProxySet growth=10 + </Proxy> + <Location /balancer-manager> + SetHandler balancer-manager + Allow from all + </Location> + ProxyPass /dynproxy balancer://dynproxy/ + + </VirtualHost> + +</IfModule> + +# +# Test config for FCGI (see t/modules/proxy_fcgi.t) +# +<IfModule mod_proxy_fcgi.c> + # XXX we have no way to retrieve the NextAvailablePort from Apache::Test... + Define FCGI_PORT @NextAvailablePort@ + + <VirtualHost proxy_fcgi> + <IfVersion >= 2.4.26> + # ProxyFCGISetEnvIf tests + <Location /fcgisetenv> + SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT} + + ProxyFCGISetEnvIf true QUERY_STRING test_value + ProxyFCGISetEnvIf true TEST_EMPTY + ProxyFCGISetEnvIf false TEST_NOT_SET + ProxyFCGISetEnvIf true TEST_DOCROOT "%{DOCUMENT_ROOT}" + ProxyFCGISetEnvIf "reqenv('GATEWAY_INTERFACE') =~ m#CGI/(.\..)#" TEST_CGI_VERSION "v$1" + ProxyFCGISetEnvIf true !REMOTE_ADDR + </Location> + </IfVersion> + + <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi> + <FilesMatch \.php$> + SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT} + </FilesMatch> + </Directory> + + <IfVersion >= 2.4.26> + <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi-generic> + ProxyFCGIBackendType GENERIC + <FilesMatch \.php$> + SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT} + </FilesMatch> + </Directory> + <Directory @SERVERROOT@/htdocs/php/fpm> + ProxyFCGIBackendType FPM + </Directory> + </IfVersion> + + <IfModule mod_rewrite.c> + <IfVersion >= 2.4.26> + <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi-generic-rewrite> + ProxyFCGIBackendType GENERIC + RewriteEngine On + RewriteRule ^.*\.php(/.*)?$ fcgi://127.0.0.1:${FCGI_PORT}@SERVERROOT@/htdocs/modules/proxy/fcgi-generic-rewrite/$0 [L,P] + </Directory> + </IfVersion> + + <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi-rewrite-path-info> + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^.*$ index.php/$0 [L] + <Files index.php> + SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT} + </Files> + </Directory> + </IfModule> + + <IfModule mod_actions.c> + #AddType application/x-php-fpm .php + Action application/x-php-fpm /php/fpm/action virtual + <Location /php/fpm/action> + SetHandler proxy:fcgi://localhost:9001 + </Location> + <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi-action> + AddType application/x-fcgi-action .php + Action application/x-fcgi-action /fcgi-action-virtual virtual + </Directory> + <Location /fcgi-action-virtual> + SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT} + </Location> + Action application/x-php-fpm /php-fpm-pp/ + ProxyPass /php-fpm-pp/ fcgi://localhost:9001/@SERVERROOT@/htdocs/ + ProxyPassReverse /php-fpm-pp/ fcgi://localhost:9001/@SERVERROOT@/htdocs/ + </IfModule> + + + </VirtualHost> + + ProxyPass /proxy/wsoc ws://@SERVERNAME@:@PORT@/modules/lua/websockets.lua + +</IfModule> + +<IfModule mod_rewrite.c> + <Directory @SERVERROOT@/htdocs/modules/proxy/rewrite> + AllowOverride All + </Directory> +</IfModule> diff --git a/debian/perl-framework/t/conf/ssl/README b/debian/perl-framework/t/conf/ssl/README new file mode 100644 index 0000000..dc86a58 --- /dev/null +++ b/debian/perl-framework/t/conf/ssl/README @@ -0,0 +1,17 @@ +certs/ + client_revoked.crt - client certificate that has been revoked + client_ok.crt - valid client certificate + client_snakeoil.crt - valid client certificate (different DN from above) + server.crt - the server certificate + ca-bundle.crt - the test server CA certificate, used to + sign above certs + +keys/ - private keys for above certificates + client_revoked.pem + client_ok.pem + client_snakeoil.pem + server.pem + +crl/ + ca-bundle.crl - certificate revocation list (client_revoked.crt) + diff --git a/debian/perl-framework/t/conf/ssl/ca-bundle-duplicates.crt b/debian/perl-framework/t/conf/ssl/ca-bundle-duplicates.crt new file mode 100644 index 0000000..ca35140 --- /dev/null +++ b/debian/perl-framework/t/conf/ssl/ca-bundle-duplicates.crt @@ -0,0 +1,114 @@ +#some duplicates of certs found in mod_ssl-2.x.x-1.3.xx/pkg.sslcfg/ca-bundle.crt +#to make sure mod_ssl can handle duplicates + +ABAecom (sub., Am. Bankers Assn.) Root CA +========================================= +MD5 Fingerprint: 82:12:F7:89:E1:0B:91:60:A4:B6:22:9F:94:68:11:92 +PEM Data: +-----BEGIN CERTIFICATE----- +MIID+DCCAuCgAwIBAgIRANAeQJAAACdLAAAAAQAAAAQwDQYJKoZIhvcNAQEFBQAw +gYwxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIEwRVdGFoMRcwFQYDVQQHEw5TYWx0IExh +a2UgQ2l0eTEYMBYGA1UEChMPWGNlcnQgRVogYnkgRFNUMRgwFgYDVQQDEw9YY2Vy +dCBFWiBieSBEU1QxITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAe +Fw05OTA3MTQxNjE0MThaFw0wOTA3MTExNjE0MThaMIGMMQswCQYDVQQGEwJVUzEN +MAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxGDAWBgNVBAoT +D1hjZXJ0IEVaIGJ5IERTVDEYMBYGA1UEAxMPWGNlcnQgRVogYnkgRFNUMSEwHwYJ +KoZIhvcNAQkBFhJjYUBkaWdzaWd0cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCtVBjetL/3reh0qu2LfI/C1HUa1YS5tmL8ie/kl2GS+x24 +4VpHNJ6eBiL70+o4y7iLB/caoBd3B1owHNQpOCDXJ0DYUJNDv9IYoil2BXKqa7Zp +mKt5Hhxl9WqL/MUWqqJy2mDtTm4ZJXoKHTDjUJtCPETrobAgHtsCfv49H7/QAIrb +QHamGKUVp1e2UsIBF5h3j4qBxhq0airmr6nWAKzP2BVJfNsbof6B+of505DBAsD5 +0ELpkWglX8a/hznplQBgKL+DLMDnXrbXNhbnYId26OcnsiUNi3rlqh3lWc3OCw5v +xsic4xDZhTnTt5v6xrp8dNJddVardKSiUb9SfO5xAgMBAAGjUzBRMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAUCCBsZuuBCmxc1bWmPEHdHJaRJ3cwHQYDVR0O +BBYEFAggbGbrgQpsXNW1pjxB3RyWkSd3MA0GCSqGSIb3DQEBBQUAA4IBAQBah1iP +Lat2IWtUDNnxQfZOzSue4x+boy1/2St9WMhnpCn16ezVvZY/o3P4xFs2fNBjLDQ5 +m0i4PW/2FMWeY+anNG7T6DOzxzwYbiOuQ5KZP5jFaTDxNjutuTCC1rZZFpYCCykS +YbQRifcML5SQhZgonFNsfmPdc/QZ/0qB0bJSI/08SjTOWhvgUIrtT4GV2GDn5MQN +u1g+WPdOaG8+Z8nLepcWJ+xCYRR2uwDF6wg9FX9LtiJdhzuQ9PPA/jez6dliDMDD +Wa9gvR8N26E0HzDEPYutsB0Ek+1f1eS/IDAE9EjpMwHRLpAnUrOb3jocq6mXf5vr +wo3CbezcE9NGxXl8 +-----END CERTIFICATE----- +Certificate Ingredients: + Data: + Version: 3 (0x2) + Serial Number: + d0:1e:40:90:00:00:27:4b:00:00:00:01:00:00:00:04 + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Utah, L=Salt Lake City, O=Xcert EZ by DST, CN=Xcert EZ by DST/Email=ca@digsigtrust.com + Validity + Not Before: Jul 14 16:14:18 1999 GMT + Not After : Jul 11 16:14:18 2009 GMT + Subject: C=US, ST=Utah, L=Salt Lake City, O=Xcert EZ by DST, CN=Xcert EZ by DST/Email=ca@digsigtrust.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ad:54:18:de:b4:bf:f7:ad:e8:74:aa:ed:8b:7c: + 8f:c2:d4:75:1a:d5:84:b9:b6:62:fc:89:ef:e4:97: + 61:92:fb:1d:b8:e1:5a:47:34:9e:9e:06:22:fb:d3: + ea:38:cb:b8:8b:07:f7:1a:a0:17:77:07:5a:30:1c: + d4:29:38:20:d7:27:40:d8:50:93:43:bf:d2:18:a2: + 29:76:05:72:aa:6b:b6:69:98:ab:79:1e:1c:65:f5: + 6a:8b:fc:c5:16:aa:a2:72:da:60:ed:4e:6e:19:25: + 7a:0a:1d:30:e3:50:9b:42:3c:44:eb:a1:b0:20:1e: + db:02:7e:fe:3d:1f:bf:d0:00:8a:db:40:76:a6:18: + a5:15:a7:57:b6:52:c2:01:17:98:77:8f:8a:81:c6: + 1a:b4:6a:2a:e6:af:a9:d6:00:ac:cf:d8:15:49:7c: + db:1b:a1:fe:81:fa:87:f9:d3:90:c1:02:c0:f9:d0: + 42:e9:91:68:25:5f:c6:bf:87:39:e9:95:00:60:28: + bf:83:2c:c0:e7:5e:b6:d7:36:16:e7:60:87:76:e8: + e7:27:b2:25:0d:8b:7a:e5:aa:1d:e5:59:cd:ce:0b: + 0e:6f:c6:c8:9c:e3:10:d9:85:39:d3:b7:9b:fa:c6: + ba:7c:74:d2:5d:75:56:ab:74:a4:a2:51:bf:52:7c: + ee:71 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:08:20:6C:66:EB:81:0A:6C:5C:D5:B5:A6:3C:41:DD:1C:96:91:27:77 + + X509v3 Subject Key Identifier: + 08:20:6C:66:EB:81:0A:6C:5C:D5:B5:A6:3C:41:DD:1C:96:91:27:77 + Signature Algorithm: sha1WithRSAEncryption + 5a:87:58:8f:2d:ab:76:21:6b:54:0c:d9:f1:41:f6:4e:cd:2b: + 9e:e3:1f:9b:a3:2d:7f:d9:2b:7d:58:c8:67:a4:29:f5:e9:ec: + d5:bd:96:3f:a3:73:f8:c4:5b:36:7c:d0:63:2c:34:39:9b:48: + b8:3d:6f:f6:14:c5:9e:63:e6:a7:34:6e:d3:e8:33:b3:c7:3c: + 18:6e:23:ae:43:92:99:3f:98:c5:69:30:f1:36:3b:ad:b9:30: + 82:d6:b6:59:16:96:02:0b:29:12:61:b4:11:89:f7:0c:2f:94: + 90:85:98:28:9c:53:6c:7e:63:dd:73:f4:19:ff:4a:81:d1:b2: + 52:23:fd:3c:4a:34:ce:5a:1b:e0:50:8a:ed:4f:81:95:d8:60: + e7:e4:c4:0d:bb:58:3e:58:f7:4e:68:6f:3e:67:c9:cb:7a:97: + 16:27:ec:42:61:14:76:bb:00:c5:eb:08:3d:15:7f:4b:b6:22: + 5d:87:3b:90:f4:f3:c0:fe:37:b3:e9:d9:62:0c:c0:c3:59:af: + 60:bd:1f:0d:db:a1:34:1f:30:c4:3d:8b:ad:b0:1d:04:93:ed: + 5f:d5:e4:bf:20:30:04:f4:48:e9:33:01:d1:2e:90:27:52:b3: + 9b:de:3a:1c:ab:a9:97:7f:9b:eb:c2:8d:c2:6d:ec:dc:13:d3: + 46:c5:79:7c + +ANX Network CA by DST +===================== +MD5 Fingerprint: A8:ED:DE:EB:93:88:66:D8:2F:C3:BD:1D:BE:45:BE:4D +PEM Data: +-----BEGIN CERTIFICATE----- +MIIDTTCCAragAwIBAgIENm6ibzANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMR0wGwYDVQQL +ExREU1QgKEFOWCBOZXR3b3JrKSBDQTAeFw05ODEyMDkxNTQ2NDhaFw0xODEyMDkx +NjE2NDhaMFIxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVy +ZSBUcnVzdCBDby4xHTAbBgNVBAsTFERTVCAoQU5YIE5ldHdvcmspIENBMIGdMA0G +CSqGSIb3DQEBAQUAA4GLADCBhwKBgQC0SBGAWKDVpZkP9jcsRLZu0XzzKmueEbaI +IwRccSWeahJ3EW6/aDllqPay9qIYsokVoGe3eowiSGv2hDQftsr3G3LL8ltI04ce +InYTBLSsbJZ/5w4IyTJRMC3VgOghZ7rzXggkLAdZnZAa7kbJtaQelrRBkdR/0o04 +JrBvQ24JfQIBA6OCATAwggEsMBEGCWCGSAGG+EIBAQQEAwIABzB0BgNVHR8EbTBr +MGmgZ6BlpGMwYTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 +dXJlIFRydXN0IENvLjEdMBsGA1UECxMURFNUIChBTlggTmV0d29yaykgQ0ExDTAL +BgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxNTQ2NDhagQ8yMDE4MTIw +OTE1NDY0OFowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIwWVXDMFgpTZMKlhKqz +ZBdDP4I2MB0GA1UdDgQWBBSMFlVwzBYKU2TCpYSqs2QXQz+CNjAMBgNVHRMEBTAD +AQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB +AEklyWCxDF+pORDTxTRVfc95wynr3vnCQPnoVsXwL+z02exIUbhjOF6TbhiWhbnK +UJykuOpmJmiThW9vTHHQvnoLPDG5975pnhDX0UDorBZxq66rOOFwscqSFuBdhaYY +gAYAnOGmGEJRp2hoWe8mlF+tMQz+KR4XAYQ3W+gSMqNd +-----END CERTIFICATE----- diff --git a/debian/perl-framework/t/conf/ssl/ca-bundle-sample.crt b/debian/perl-framework/t/conf/ssl/ca-bundle-sample.crt new file mode 100644 index 0000000..85b5f36 --- /dev/null +++ b/debian/perl-framework/t/conf/ssl/ca-bundle-sample.crt @@ -0,0 +1,393 @@ +#pkg.sslcfg/ca-bundle.crt is ~250k, so it is not checked into cvs +#for better test results, copy that file into this directory +#and leave this one in place + +ABAecom (sub., Am. Bankers Assn.) Root CA +========================================= +MD5 Fingerprint: 82:12:F7:89:E1:0B:91:60:A4:B6:22:9F:94:68:11:92 +PEM Data: +-----BEGIN CERTIFICATE----- +MIID+DCCAuCgAwIBAgIRANAeQJAAACdLAAAAAQAAAAQwDQYJKoZIhvcNAQEFBQAw +gYwxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIEwRVdGFoMRcwFQYDVQQHEw5TYWx0IExh +a2UgQ2l0eTEYMBYGA1UEChMPWGNlcnQgRVogYnkgRFNUMRgwFgYDVQQDEw9YY2Vy +dCBFWiBieSBEU1QxITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAe +Fw05OTA3MTQxNjE0MThaFw0wOTA3MTExNjE0MThaMIGMMQswCQYDVQQGEwJVUzEN +MAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxGDAWBgNVBAoT +D1hjZXJ0IEVaIGJ5IERTVDEYMBYGA1UEAxMPWGNlcnQgRVogYnkgRFNUMSEwHwYJ +KoZIhvcNAQkBFhJjYUBkaWdzaWd0cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCtVBjetL/3reh0qu2LfI/C1HUa1YS5tmL8ie/kl2GS+x24 +4VpHNJ6eBiL70+o4y7iLB/caoBd3B1owHNQpOCDXJ0DYUJNDv9IYoil2BXKqa7Zp +mKt5Hhxl9WqL/MUWqqJy2mDtTm4ZJXoKHTDjUJtCPETrobAgHtsCfv49H7/QAIrb +QHamGKUVp1e2UsIBF5h3j4qBxhq0airmr6nWAKzP2BVJfNsbof6B+of505DBAsD5 +0ELpkWglX8a/hznplQBgKL+DLMDnXrbXNhbnYId26OcnsiUNi3rlqh3lWc3OCw5v +xsic4xDZhTnTt5v6xrp8dNJddVardKSiUb9SfO5xAgMBAAGjUzBRMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAUCCBsZuuBCmxc1bWmPEHdHJaRJ3cwHQYDVR0O +BBYEFAggbGbrgQpsXNW1pjxB3RyWkSd3MA0GCSqGSIb3DQEBBQUAA4IBAQBah1iP +Lat2IWtUDNnxQfZOzSue4x+boy1/2St9WMhnpCn16ezVvZY/o3P4xFs2fNBjLDQ5 +m0i4PW/2FMWeY+anNG7T6DOzxzwYbiOuQ5KZP5jFaTDxNjutuTCC1rZZFpYCCykS +YbQRifcML5SQhZgonFNsfmPdc/QZ/0qB0bJSI/08SjTOWhvgUIrtT4GV2GDn5MQN +u1g+WPdOaG8+Z8nLepcWJ+xCYRR2uwDF6wg9FX9LtiJdhzuQ9PPA/jez6dliDMDD +Wa9gvR8N26E0HzDEPYutsB0Ek+1f1eS/IDAE9EjpMwHRLpAnUrOb3jocq6mXf5vr +wo3CbezcE9NGxXl8 +-----END CERTIFICATE----- +Certificate Ingredients: + Data: + Version: 3 (0x2) + Serial Number: + d0:1e:40:90:00:00:27:4b:00:00:00:01:00:00:00:04 + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Utah, L=Salt Lake City, O=Xcert EZ by DST, CN=Xcert EZ by DST/Email=ca@digsigtrust.com + Validity + Not Before: Jul 14 16:14:18 1999 GMT + Not After : Jul 11 16:14:18 2009 GMT + Subject: C=US, ST=Utah, L=Salt Lake City, O=Xcert EZ by DST, CN=Xcert EZ by DST/Email=ca@digsigtrust.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ad:54:18:de:b4:bf:f7:ad:e8:74:aa:ed:8b:7c: + 8f:c2:d4:75:1a:d5:84:b9:b6:62:fc:89:ef:e4:97: + 61:92:fb:1d:b8:e1:5a:47:34:9e:9e:06:22:fb:d3: + ea:38:cb:b8:8b:07:f7:1a:a0:17:77:07:5a:30:1c: + d4:29:38:20:d7:27:40:d8:50:93:43:bf:d2:18:a2: + 29:76:05:72:aa:6b:b6:69:98:ab:79:1e:1c:65:f5: + 6a:8b:fc:c5:16:aa:a2:72:da:60:ed:4e:6e:19:25: + 7a:0a:1d:30:e3:50:9b:42:3c:44:eb:a1:b0:20:1e: + db:02:7e:fe:3d:1f:bf:d0:00:8a:db:40:76:a6:18: + a5:15:a7:57:b6:52:c2:01:17:98:77:8f:8a:81:c6: + 1a:b4:6a:2a:e6:af:a9:d6:00:ac:cf:d8:15:49:7c: + db:1b:a1:fe:81:fa:87:f9:d3:90:c1:02:c0:f9:d0: + 42:e9:91:68:25:5f:c6:bf:87:39:e9:95:00:60:28: + bf:83:2c:c0:e7:5e:b6:d7:36:16:e7:60:87:76:e8: + e7:27:b2:25:0d:8b:7a:e5:aa:1d:e5:59:cd:ce:0b: + 0e:6f:c6:c8:9c:e3:10:d9:85:39:d3:b7:9b:fa:c6: + ba:7c:74:d2:5d:75:56:ab:74:a4:a2:51:bf:52:7c: + ee:71 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:08:20:6C:66:EB:81:0A:6C:5C:D5:B5:A6:3C:41:DD:1C:96:91:27:77 + + X509v3 Subject Key Identifier: + 08:20:6C:66:EB:81:0A:6C:5C:D5:B5:A6:3C:41:DD:1C:96:91:27:77 + Signature Algorithm: sha1WithRSAEncryption + 5a:87:58:8f:2d:ab:76:21:6b:54:0c:d9:f1:41:f6:4e:cd:2b: + 9e:e3:1f:9b:a3:2d:7f:d9:2b:7d:58:c8:67:a4:29:f5:e9:ec: + d5:bd:96:3f:a3:73:f8:c4:5b:36:7c:d0:63:2c:34:39:9b:48: + b8:3d:6f:f6:14:c5:9e:63:e6:a7:34:6e:d3:e8:33:b3:c7:3c: + 18:6e:23:ae:43:92:99:3f:98:c5:69:30:f1:36:3b:ad:b9:30: + 82:d6:b6:59:16:96:02:0b:29:12:61:b4:11:89:f7:0c:2f:94: + 90:85:98:28:9c:53:6c:7e:63:dd:73:f4:19:ff:4a:81:d1:b2: + 52:23:fd:3c:4a:34:ce:5a:1b:e0:50:8a:ed:4f:81:95:d8:60: + e7:e4:c4:0d:bb:58:3e:58:f7:4e:68:6f:3e:67:c9:cb:7a:97: + 16:27:ec:42:61:14:76:bb:00:c5:eb:08:3d:15:7f:4b:b6:22: + 5d:87:3b:90:f4:f3:c0:fe:37:b3:e9:d9:62:0c:c0:c3:59:af: + 60:bd:1f:0d:db:a1:34:1f:30:c4:3d:8b:ad:b0:1d:04:93:ed: + 5f:d5:e4:bf:20:30:04:f4:48:e9:33:01:d1:2e:90:27:52:b3: + 9b:de:3a:1c:ab:a9:97:7f:9b:eb:c2:8d:c2:6d:ec:dc:13:d3: + 46:c5:79:7c + +ANX Network CA by DST +===================== +MD5 Fingerprint: A8:ED:DE:EB:93:88:66:D8:2F:C3:BD:1D:BE:45:BE:4D +PEM Data: +-----BEGIN CERTIFICATE----- +MIIDTTCCAragAwIBAgIENm6ibzANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMR0wGwYDVQQL +ExREU1QgKEFOWCBOZXR3b3JrKSBDQTAeFw05ODEyMDkxNTQ2NDhaFw0xODEyMDkx +NjE2NDhaMFIxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVy +ZSBUcnVzdCBDby4xHTAbBgNVBAsTFERTVCAoQU5YIE5ldHdvcmspIENBMIGdMA0G +CSqGSIb3DQEBAQUAA4GLADCBhwKBgQC0SBGAWKDVpZkP9jcsRLZu0XzzKmueEbaI +IwRccSWeahJ3EW6/aDllqPay9qIYsokVoGe3eowiSGv2hDQftsr3G3LL8ltI04ce +InYTBLSsbJZ/5w4IyTJRMC3VgOghZ7rzXggkLAdZnZAa7kbJtaQelrRBkdR/0o04 +JrBvQ24JfQIBA6OCATAwggEsMBEGCWCGSAGG+EIBAQQEAwIABzB0BgNVHR8EbTBr +MGmgZ6BlpGMwYTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 +dXJlIFRydXN0IENvLjEdMBsGA1UECxMURFNUIChBTlggTmV0d29yaykgQ0ExDTAL +BgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxNTQ2NDhagQ8yMDE4MTIw +OTE1NDY0OFowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIwWVXDMFgpTZMKlhKqz +ZBdDP4I2MB0GA1UdDgQWBBSMFlVwzBYKU2TCpYSqs2QXQz+CNjAMBgNVHRMEBTAD +AQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB +AEklyWCxDF+pORDTxTRVfc95wynr3vnCQPnoVsXwL+z02exIUbhjOF6TbhiWhbnK +UJykuOpmJmiThW9vTHHQvnoLPDG5975pnhDX0UDorBZxq66rOOFwscqSFuBdhaYY +gAYAnOGmGEJRp2hoWe8mlF+tMQz+KR4XAYQ3W+gSMqNd +-----END CERTIFICATE----- +Certificate Ingredients: + Data: + Version: 3 (0x2) + Serial Number: 913220207 (0x366ea26f) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=Digital Signature Trust Co., OU=DST (ANX Network) CA + Validity + Not Before: Dec 9 15:46:48 1998 GMT + Not After : Dec 9 16:16:48 2018 GMT + Subject: C=US, O=Digital Signature Trust Co., OU=DST (ANX Network) CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:b4:48:11:80:58:a0:d5:a5:99:0f:f6:37:2c:44: + b6:6e:d1:7c:f3:2a:6b:9e:11:b6:88:23:04:5c:71: + 25:9e:6a:12:77:11:6e:bf:68:39:65:a8:f6:b2:f6: + a2:18:b2:89:15:a0:67:b7:7a:8c:22:48:6b:f6:84: + 34:1f:b6:ca:f7:1b:72:cb:f2:5b:48:d3:87:1e:22: + 76:13:04:b4:ac:6c:96:7f:e7:0e:08:c9:32:51:30: + 2d:d5:80:e8:21:67:ba:f3:5e:08:24:2c:07:59:9d: + 90:1a:ee:46:c9:b5:a4:1e:96:b4:41:91:d4:7f:d2: + 8d:38:26:b0:6f:43:6e:09:7d + Exponent: 3 (0x3) + X509v3 extensions: + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + X509v3 CRL Distribution Points: + DirName:/C=US/O=Digital Signature Trust Co./OU=DST (ANX Network) CA/CN=CRL1 + + X509v3 Private Key Usage Period: + Not Before: Dec 9 15:46:48 1998 GMT, Not After: Dec 9 15:46:48 2018 GMT + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Authority Key Identifier: + keyid:8C:16:55:70:CC:16:0A:53:64:C2:A5:84:AA:B3:64:17:43:3F:82:36 + + X509v3 Subject Key Identifier: + 8C:16:55:70:CC:16:0A:53:64:C2:A5:84:AA:B3:64:17:43:3F:82:36 + X509v3 Basic Constraints: + CA:TRUE + 1.2.840.113533.7.65.0: + 0 +..V4.0.... + Signature Algorithm: sha1WithRSAEncryption + 49:25:c9:60:b1:0c:5f:a9:39:10:d3:c5:34:55:7d:cf:79:c3: + 29:eb:de:f9:c2:40:f9:e8:56:c5:f0:2f:ec:f4:d9:ec:48:51: + b8:63:38:5e:93:6e:18:96:85:b9:ca:50:9c:a4:b8:ea:66:26: + 68:93:85:6f:6f:4c:71:d0:be:7a:0b:3c:31:b9:f7:be:69:9e: + 10:d7:d1:40:e8:ac:16:71:ab:ae:ab:38:e1:70:b1:ca:92:16: + e0:5d:85:a6:18:80:06:00:9c:e1:a6:18:42:51:a7:68:68:59: + ef:26:94:5f:ad:31:0c:fe:29:1e:17:01:84:37:5b:e8:12:32: + a3:5d + +American Express CA +=================== +MD5 Fingerprint: 1C:D5:8E:82:BE:70:55:8E:39:61:DF:AD:51:DB:6B:A0 +PEM Data: +-----BEGIN CERTIFICATE----- +MIICkDCCAfkCAgCNMA0GCSqGSIb3DQEBBAUAMIGPMQswCQYDVQQGEwJVUzEnMCUG +A1UEChMeQW1lcmljYW4gRXhwcmVzcyBDb21wYW55LCBJbmMuMSYwJAYDVQQLEx1B +bWVyaWNhbiBFeHByZXNzIFRlY2hub2xvZ2llczEvMC0GA1UEAxMmQW1lcmljYW4g +RXhwcmVzcyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNOTgwODE0MjIwMTAwWhcN +MDYwODE0MjM1OTAwWjCBjzELMAkGA1UEBhMCVVMxJzAlBgNVBAoTHkFtZXJpY2Fu +IEV4cHJlc3MgQ29tcGFueSwgSW5jLjEmMCQGA1UECxMdQW1lcmljYW4gRXhwcmVz +cyBUZWNobm9sb2dpZXMxLzAtBgNVBAMTJkFtZXJpY2FuIEV4cHJlc3MgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJ8kmS +hcr9FSm1BrZE7PyIo/KGzv8UTyQckvnCI8HOQ99dNMi4FOzVKnCRSZXXVs2U8amT +0Ggi3E19oApyKkfqJfCFAF82VGHPC/k3Wmed6R/pZD9wlWGn0DAC3iYopGYDBOkw ++48zB/lvYYeictvzaHhjZlmpybdm4RWySDYs+QIDAQABMA0GCSqGSIb3DQEBBAUA +A4GBAGgXYrhzi0xs60qlPqvlnS7SzYoHV/PGWZd2Fxf4Uo4nk9hY2Chs9KIEeorC +diSxArTfKPL386infiNIYYj0EWiuJl32oUtTJWrYKhQCDuCHIG6eGVxzkAsj4jGX +Iz/VIqLTBnvaN/XXtUFEF3pFAtmFRWbWjsfwegyZYiJpW+3S +-----END CERTIFICATE----- +Certificate Ingredients: + Data: + Version: 1 (0x0) + Serial Number: 141 (0x8d) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, O=American Express Company, Inc., OU=American Express Technologies, CN=American Express Certificate Authority + Validity + Not Before: Aug 14 22:01:00 1998 GMT + Not After : Aug 14 23:59:00 2006 GMT + Subject: C=US, O=American Express Company, Inc., OU=American Express Technologies, CN=American Express Certificate Authority + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:c9:f2:49:92:85:ca:fd:15:29:b5:06:b6:44:ec: + fc:88:a3:f2:86:ce:ff:14:4f:24:1c:92:f9:c2:23: + c1:ce:43:df:5d:34:c8:b8:14:ec:d5:2a:70:91:49: + 95:d7:56:cd:94:f1:a9:93:d0:68:22:dc:4d:7d:a0: + 0a:72:2a:47:ea:25:f0:85:00:5f:36:54:61:cf:0b: + f9:37:5a:67:9d:e9:1f:e9:64:3f:70:95:61:a7:d0: + 30:02:de:26:28:a4:66:03:04:e9:30:fb:8f:33:07: + f9:6f:61:87:a2:72:db:f3:68:78:63:66:59:a9:c9: + b7:66:e1:15:b2:48:36:2c:f9 + Exponent: 65537 (0x10001) + Signature Algorithm: md5WithRSAEncryption + 68:17:62:b8:73:8b:4c:6c:eb:4a:a5:3e:ab:e5:9d:2e:d2:cd: + 8a:07:57:f3:c6:59:97:76:17:17:f8:52:8e:27:93:d8:58:d8: + 28:6c:f4:a2:04:7a:8a:c2:76:24:b1:02:b4:df:28:f2:f7:f3: + a8:a7:7e:23:48:61:88:f4:11:68:ae:26:5d:f6:a1:4b:53:25: + 6a:d8:2a:14:02:0e:e0:87:20:6e:9e:19:5c:73:90:0b:23:e2: + 31:97:23:3f:d5:22:a2:d3:06:7b:da:37:f5:d7:b5:41:44:17: + 7a:45:02:d9:85:45:66:d6:8e:c7:f0:7a:0c:99:62:22:69:5b: + ed:d2 + +American Express Global CA +========================== +MD5 Fingerprint: 63:1B:66:93:8C:F3:66:CB:3C:79:57:DC:05:49:EA:DB +PEM Data: +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgICAIUwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNVBAYTAlVT +MScwJQYDVQQKEx5BbWVyaWNhbiBFeHByZXNzIENvbXBhbnksIEluYy4xJjAkBgNV +BAsTHUFtZXJpY2FuIEV4cHJlc3MgVGVjaG5vbG9naWVzMTYwNAYDVQQDEy1BbWVy +aWNhbiBFeHByZXNzIEdsb2JhbCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNOTgw +ODE0MTkwNjAwWhcNMTMwODE0MjM1OTAwWjCBljELMAkGA1UEBhMCVVMxJzAlBgNV +BAoTHkFtZXJpY2FuIEV4cHJlc3MgQ29tcGFueSwgSW5jLjEmMCQGA1UECxMdQW1l +cmljYW4gRXhwcmVzcyBUZWNobm9sb2dpZXMxNjA0BgNVBAMTLUFtZXJpY2FuIEV4 +cHJlc3MgR2xvYmFsIENlcnRpZmljYXRlIEF1dGhvcml0eTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAPAkJmYu++tKc3FTiUfLJjxTkpRMysKFtQ34w1e9 +Lyofahi3V68MABb6oLaQpvcaoS5mJsdoo4qTaWa1RlYtHYLqkAwKIsKJUI0F89Sr +c0HwzxKsKLRvFJSWWUuekHWG3+JH6+HpT0N+h8onGGaetcFAZX38YW+tm3LPqV7Y +8/nabpEQ+ky16n4g3qk5L/WI5IpvNcYgnCuGRjMK/DFVpWusFkDpzTVZbzIEw3u1 +D3t3cPNIuypSgs6vKW3xEW9t5gcAAe+a8yYNpnkTZ6/4qxx1rJG1a75AsN6cDLFp +hRlxkRNFyt/R/eayypaDedvFuKpbepALeFY+xteflEgR9a0CAwEAAaNaMFgwEgYD +VR0TAQH/BAgwBgEB/wIBBTAOBgNVHQ8BAf8EBAMCAQYwFwYDVR0gBBAwDjAMBgoq +hkiG+Q8KAQUBMBkGA1UdDgQSBBBXRzV7NicRqAj8L0Yl6yRpMA0GCSqGSIb3DQEB +BQUAA4IBAQDHYUWoinG5vjTpIXshzVYTmNUwY+kYqkuSFb8LHbvskmnFLsNhi+gw +RcsQRsFzOFyLGdIr80DrfHKzLh4n43WVihybLsSVBYZy0FX0oZJSeVzb9Pjc5dcS +sUDHPIbkMWVKyjfG3nZXGWlMRmn8Kq0WN3qTrPchSy3766lQy8HRQAjaA2mHpzde +VcHF7cTjjgwml5tcV0ty4/IDBdACOyYDQJCevgtbSQx48dVMVSng9v1MA6lUAjLR +V1qFrEPtWzsWX6C/NdtLnnvo/+cNPDuom0lBRvVzTv+SZSGDE1Vx60k8f4gawhIo +JaFGS0E3l3/sjvHUoZbCILZerakcHhGg +-----END CERTIFICATE----- +Certificate Ingredients: + Data: + Version: 3 (0x2) + Serial Number: 133 (0x85) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=American Express Company, Inc., OU=American Express Technologies, CN=American Express Global Certificate Authority + Validity + Not Before: Aug 14 19:06:00 1998 GMT + Not After : Aug 14 23:59:00 2013 GMT + Subject: C=US, O=American Express Company, Inc., OU=American Express Technologies, CN=American Express Global Certificate Authority + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:f0:24:26:66:2e:fb:eb:4a:73:71:53:89:47:cb: + 26:3c:53:92:94:4c:ca:c2:85:b5:0d:f8:c3:57:bd: + 2f:2a:1f:6a:18:b7:57:af:0c:00:16:fa:a0:b6:90: + a6:f7:1a:a1:2e:66:26:c7:68:a3:8a:93:69:66:b5: + 46:56:2d:1d:82:ea:90:0c:0a:22:c2:89:50:8d:05: + f3:d4:ab:73:41:f0:cf:12:ac:28:b4:6f:14:94:96: + 59:4b:9e:90:75:86:df:e2:47:eb:e1:e9:4f:43:7e: + 87:ca:27:18:66:9e:b5:c1:40:65:7d:fc:61:6f:ad: + 9b:72:cf:a9:5e:d8:f3:f9:da:6e:91:10:fa:4c:b5: + ea:7e:20:de:a9:39:2f:f5:88:e4:8a:6f:35:c6:20: + 9c:2b:86:46:33:0a:fc:31:55:a5:6b:ac:16:40:e9: + cd:35:59:6f:32:04:c3:7b:b5:0f:7b:77:70:f3:48: + bb:2a:52:82:ce:af:29:6d:f1:11:6f:6d:e6:07:00: + 01:ef:9a:f3:26:0d:a6:79:13:67:af:f8:ab:1c:75: + ac:91:b5:6b:be:40:b0:de:9c:0c:b1:69:85:19:71: + 91:13:45:ca:df:d1:fd:e6:b2:ca:96:83:79:db:c5: + b8:aa:5b:7a:90:0b:78:56:3e:c6:d7:9f:94:48:11: + f5:ad + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:5 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Certificate Policies: + Policy: 1.2.840.113807.10.1.5.1 + + X509v3 Subject Key Identifier: + 57:47:35:7B:36:27:11:A8:08:FC:2F:46:25:EB:24:69 + Signature Algorithm: sha1WithRSAEncryption + c7:61:45:a8:8a:71:b9:be:34:e9:21:7b:21:cd:56:13:98:d5: + 30:63:e9:18:aa:4b:92:15:bf:0b:1d:bb:ec:92:69:c5:2e:c3: + 61:8b:e8:30:45:cb:10:46:c1:73:38:5c:8b:19:d2:2b:f3:40: + eb:7c:72:b3:2e:1e:27:e3:75:95:8a:1c:9b:2e:c4:95:05:86: + 72:d0:55:f4:a1:92:52:79:5c:db:f4:f8:dc:e5:d7:12:b1:40: + c7:3c:86:e4:31:65:4a:ca:37:c6:de:76:57:19:69:4c:46:69: + fc:2a:ad:16:37:7a:93:ac:f7:21:4b:2d:fb:eb:a9:50:cb:c1: + d1:40:08:da:03:69:87:a7:37:5e:55:c1:c5:ed:c4:e3:8e:0c: + 26:97:9b:5c:57:4b:72:e3:f2:03:05:d0:02:3b:26:03:40:90: + 9e:be:0b:5b:49:0c:78:f1:d5:4c:55:29:e0:f6:fd:4c:03:a9: + 54:02:32:d1:57:5a:85:ac:43:ed:5b:3b:16:5f:a0:bf:35:db: + 4b:9e:7b:e8:ff:e7:0d:3c:3b:a8:9b:49:41:46:f5:73:4e:ff: + 92:65:21:83:13:55:71:eb:49:3c:7f:88:1a:c2:12:28:25:a1: + 46:4b:41:37:97:7f:ec:8e:f1:d4:a1:96:c2:20:b6:5e:ad:a9: + 1c:1e:11:a0 + +BelSign Object Publishing CA +============================ +MD5 Fingerprint: 8A:02:F8:DF:B8:E1:84:9F:5A:C2:60:24:65:D1:73:FB +PEM Data: +-----BEGIN CERTIFICATE----- +MIIDAzCCAmygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBuzELMAkGA1UEBhMCQkUx +ETAPBgNVBAcTCEJydXNzZWxzMRMwEQYDVQQKEwpCZWxTaWduIE5WMTgwNgYDVQQL +Ey9CZWxTaWduIE9iamVjdCBQdWJsaXNoaW5nIENlcnRpZmljYXRlIEF1dGhvcml0 +eTElMCMGA1UEAxMcQmVsU2lnbiBPYmplY3QgUHVibGlzaGluZyBDQTEjMCEGCSqG +SIb3DQEJARYUd2VibWFzdGVyQGJlbHNpZ24uYmUwHhcNOTcwOTE5MjIwMzAwWhcN +MDcwOTE5MjIwMzAwWjCBuzELMAkGA1UEBhMCQkUxETAPBgNVBAcTCEJydXNzZWxz +MRMwEQYDVQQKEwpCZWxTaWduIE5WMTgwNgYDVQQLEy9CZWxTaWduIE9iamVjdCBQ +dWJsaXNoaW5nIENlcnRpZmljYXRlIEF1dGhvcml0eTElMCMGA1UEAxMcQmVsU2ln +biBPYmplY3QgUHVibGlzaGluZyBDQTEjMCEGCSqGSIb3DQEJARYUd2VibWFzdGVy +QGJlbHNpZ24uYmUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMQuH7a/7oJA +3fm3LkHVngWxWtAmfGJVA5v8y2HeS+/+6Jn+h7mIz5DaDwk8dt8Xl7bLPyVF/bS8 +WAC+sFq2FIeP7mdkrR2Ig7tnn2VhAFgIgFCfgMkx9iqQHC33SmwQ9iNDXTgJYIhX +As0WbBj8zfuSKnfQnpOjXYhk0Mj4XVRRAgMBAAGjFTATMBEGCWCGSAGG+EIBAQQE +AwIABzANBgkqhkiG9w0BAQQFAAOBgQBjdhd8lvBTpV0BHFPOKcJ+daxMDaIIc7Rq +Mf0CBhSZ3FQEpL/IloafMUMyJVf2hfYluze+oXkjyVcGJXFrRU/49AJAFoIir1Tq +Mij2De6ZuksIUQ9uhiMhTC0liIHELg7xEyw4ipUCJMM6lWPkk45IuwhHcl+u5jpa +R9Zxxp6aUg== +-----END CERTIFICATE----- +Certificate Ingredients: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=BE, L=Brussels, O=BelSign NV, OU=BelSign Object Publishing Certificate Authority, CN=BelSign Object Publishing CA/Email=webmaster@belsign.be + Validity + Not Before: Sep 19 22:03:00 1997 GMT + Not After : Sep 19 22:03:00 2007 GMT + Subject: C=BE, L=Brussels, O=BelSign NV, OU=BelSign Object Publishing Certificate Authority, CN=BelSign Object Publishing CA/Email=webmaster@belsign.be + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:c4:2e:1f:b6:bf:ee:82:40:dd:f9:b7:2e:41:d5: + 9e:05:b1:5a:d0:26:7c:62:55:03:9b:fc:cb:61:de: + 4b:ef:fe:e8:99:fe:87:b9:88:cf:90:da:0f:09:3c: + 76:df:17:97:b6:cb:3f:25:45:fd:b4:bc:58:00:be: + b0:5a:b6:14:87:8f:ee:67:64:ad:1d:88:83:bb:67: + 9f:65:61:00:58:08:80:50:9f:80:c9:31:f6:2a:90: + 1c:2d:f7:4a:6c:10:f6:23:43:5d:38:09:60:88:57: + 02:cd:16:6c:18:fc:cd:fb:92:2a:77:d0:9e:93:a3: + 5d:88:64:d0:c8:f8:5d:54:51 + Exponent: 65537 (0x10001) + X509v3 extensions: + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + Signature Algorithm: md5WithRSAEncryption + 63:76:17:7c:96:f0:53:a5:5d:01:1c:53:ce:29:c2:7e:75:ac: + 4c:0d:a2:08:73:b4:6a:31:fd:02:06:14:99:dc:54:04:a4:bf: + c8:96:86:9f:31:43:32:25:57:f6:85:f6:25:bb:37:be:a1:79: + 23:c9:57:06:25:71:6b:45:4f:f8:f4:02:40:16:82:22:af:54: + ea:32:28:f6:0d:ee:99:ba:4b:08:51:0f:6e:86:23:21:4c:2d: + 25:88:81:c4:2e:0e:f1:13:2c:38:8a:95:02:24:c3:3a:95:63: + e4:93:8e:48:bb:08:47:72:5f:ae:e6:3a:5a:47:d6:71:c6:9e: + 9a:52 + +BelSign Secure Server CA +======================== +MD5 Fingerprint: 3D:5E:82:C6:D9:AD:D9:8B:93:6B:0C:10:B9:49:0A:B1 +PEM Data: +-----BEGIN CERTIFICATE----- +MIIC8zCCAlygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBszELMAkGA1UEBhMCQkUx +ETAPBgNVBAcTCEJydXNzZWxzMRMwEQYDVQQKEwpCZWxTaWduIE5WMTQwMgYDVQQL +EytCZWxTaWduIFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSEw +HwYDVQQDExhCZWxTaWduIFNlY3VyZSBTZXJ2ZXIgQ0ExIzAhBgkqhkiG9w0BCQEW +FHdlYm1hc3RlckBiZWxzaWduLmJlMB4XDTk3MDcxNjIyMDA1NFoXDTA3MDcxNjIy +MDA1NFowgbMxCzAJBgNVBAYTAkJFMREwDwYDVQQHEwhCcnVzc2VsczETMBEGA1UE +ChMKQmVsU2lnbiBOVjE0MDIGA1UECxMrQmVsU2lnbiBTZWN1cmUgU2VydmVyIENl +cnRpZmljYXRlIEF1dGhvcml0eTEhMB8GA1UEAxMYQmVsU2lnbiBTZWN1cmUgU2Vy +dmVyIENBMSMwIQYJKoZIhvcNAQkBFhR3ZWJtYXN0ZXJAYmVsc2lnbi5iZTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1gESeJL4BEJ/yccig/x8R3AwK0kLPjZA +kCjaIXODU/LE0RZAwFP/rqbGJLMnbaWzPTl3XagG9ubpvGMRTgZlcAqdk/miQIt/ +SoQOjRax1swIZBIM4ChLyKWEkBf7EUYu1qeFGMsYrmOasFgG9ADP+MQJGjUMofnu +Sv1t3v4mpTsCAwEAAaMVMBMwEQYJYIZIAYb4QgEBBAQDAgCgMA0GCSqGSIb3DQEB +BAUAA4GBAGw9mcMF4h3K5S2qaIWLQDEgZhNo5lg6idCNdbLFYth9go/32TKBd/Y1 +W4UpzmeyubwrGXjP84f9RvGVdbIJVwMwwXrNckdxgMp9ncllPEcRIn36BwsoeKGT +6AVFSOIyMko96FMcELfHc4wHUOH5yStTQfWDjeUJOUqOA2KqQGOL +-----END CERTIFICATE----- diff --git a/debian/perl-framework/t/conf/ssl/httpd-passphrase.pl.PL b/debian/perl-framework/t/conf/ssl/httpd-passphrase.pl.PL new file mode 100644 index 0000000..36eba94 --- /dev/null +++ b/debian/perl-framework/t/conf/ssl/httpd-passphrase.pl.PL @@ -0,0 +1,2 @@ +#for testing SSLPassPhraseDialog exec:@ServerRoot@/conf/ssl/httpd-passphrase.pl +print "httpd\n"; diff --git a/debian/perl-framework/t/conf/ssl/proxyssl.conf.in b/debian/perl-framework/t/conf/ssl/proxyssl.conf.in new file mode 100644 index 0000000..3c86c13 --- /dev/null +++ b/debian/perl-framework/t/conf/ssl/proxyssl.conf.in @@ -0,0 +1,124 @@ +<IfModule @ssl_module@> + +<IfModule mod_proxy.c> + + #here we can test http <-> https + <VirtualHost proxy_http_https> + #these are not on by default in the 1.x based mod_ssl + <IfDefine APACHE2> + SSLProxyEngine On + + SSLProxyProtocol All + SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL + + SSLProxyMachineCertificateFile @SSLCA@/asf/proxy/client_ok.pem + #SSLProxyMachineCertificatePath @SSLCA@/asf/proxy + + SSLProxyCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLProxyCACertificatePath @ServerRoot@/conf/ssl + SSLProxyCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl + <IfVersion >= 2.3.15> + SSLProxyCARevocationCheck chain + </IfVersion> + SSLProxyVerify on + SSLProxyVerifyDepth 10 + </IfDefine> + + + ProxyPass / https://@proxyssl_url@/ + ProxyPassReverse / https://@proxyssl_url@/ + </VirtualHost> + + + #here we can test https <-> https + <VirtualHost proxy_https_https> + SSLEngine on + + #these are not on by default in the 1.x based mod_ssl + <IfDefine APACHE2> + SSLProxyEngine On + # ensure that client_ok.pem is picked first: + SSLProxyMachineCertificateFile @SSLCA@/asf/proxy/client_ok.pem + SSLProxyMachineCertificatePath @SSLCA@/asf/proxy + SSLProxyCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLProxyVerify on + SSLProxyCARevocationPath @SSLCA@/asf/crl + <IfVersion >= 2.3.15> + SSLProxyCARevocationCheck chain + </IfVersion> + </IfDefine> + + + ProxyPass / https://@proxyssl_url@/ + ProxyPassReverse / https://@proxyssl_url@/ + </VirtualHost> + + #here we can test http <-> https using SSLProxyMachine* inside <Proxy> + <VirtualHost proxy_http_https_proxy_section> + #these are not on by default in the 1.x based mod_ssl + <IfDefine APACHE2> + SSLProxyEngine On + + SSLProxyProtocol All + SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL + + SSLProxyCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLProxyCACertificatePath @ServerRoot@/conf/ssl + SSLProxyCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl + <IfVersion >= 2.3.15> + SSLProxyCARevocationCheck chain + </IfVersion> + SSLProxyVerify on + SSLProxyVerifyDepth 10 + </IfDefine> + + + ProxyPass / https://@proxyssl_url@/ + ProxyPassReverse / https://@proxyssl_url@/ + <IfDefine APACHE2> + <Proxy https://@proxyssl_url@> + SSLProxyMachineCertificateFile @SSLCA@/asf/proxy/client_ok.pem + #SSLProxyMachineCertificatePath @SSLCA@/asf/proxy + </Proxy> + </IfDefine> + </VirtualHost> + + + #here we can test https <-> https using SSLProxyMachine* inside <Proxy> + <VirtualHost proxy_https_https_proxy_section> + SSLEngine on + + #these are not on by default in the 1.x based mod_ssl + <IfDefine APACHE2> + SSLProxyEngine On + SSLProxyCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLProxyVerify on + SSLProxyCARevocationPath @SSLCA@/asf/crl + <IfVersion >= 2.3.15> + SSLProxyCARevocationCheck chain + </IfVersion> + </IfDefine> + + + ProxyPass / https://@proxyssl_url@/ + ProxyPassReverse / https://@proxyssl_url@/ + <IfDefine APACHE2> + <Proxy https://@proxyssl_url@> + # ensure that client_ok.pem is picked first: + SSLProxyMachineCertificateFile @SSLCA@/asf/proxy/client_ok.pem + SSLProxyMachineCertificatePath @SSLCA@/asf/proxy + </Proxy> + </IfDefine> + </VirtualHost> + + #here we can test https <-> http + <VirtualHost proxy_https_http> + SSLEngine on + + ProxyPass / http://@servername@:@port@/ + ProxyPassReverse / http://@servername@:@port@/ + </VirtualHost> + +</IfModule> + +</IfModule> diff --git a/debian/perl-framework/t/conf/ssl/ssl.conf.in b/debian/perl-framework/t/conf/ssl/ssl.conf.in new file mode 100644 index 0000000..6fadf33 --- /dev/null +++ b/debian/perl-framework/t/conf/ssl/ssl.conf.in @@ -0,0 +1,289 @@ +#test config derived from httpd-2.0/docs/conf/ssl-std.conf -*- text -*- + +<IfModule @ssl_module@> + #base config that can be used by any SSL enabled VirtualHosts + AddType application/x-x509-ca-cert .crt + AddType application/x-pkcs7-crl .crl + + <IfDefine TEST_SSL_SESSCACHE> + SSLSessionCache ${SSL_SESSCACHE} + </IfDefine> + <IfDefine !TEST_SSL_SESSCACHE> + SSLSessionCache none + </IfDefine> + + <IfVersion < 2.3.4> + #SSLMutex file:@ServerRoot@/logs/ssl_mutex + </IfVersion> + <IfVersion >= 2.3.4> + # mutex created automatically + # config needed only if file-based mutexes are used and + # default lock file dir is inappropriate + # Mutex file:/path/to/lockdir ssl-cache + </IfVersion> + + SSLRandomSeed startup builtin + SSLRandomSeed connect builtin + #SSLRandomSeed startup file:/dev/random 512 + #SSLRandomSeed startup file:/dev/urandom 512 + #SSLRandomSeed connect file:/dev/random 512 + #SSLRandomSeed connect file:/dev/urandom 512 + + SSLProtocol @sslproto@ + + <IfModule mod_log_config.c> + LogFormat "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %>s %b" ssl + CustomLog logs/ssl_request_log ssl + </IfModule> + + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL + + <IfDefine TEST_SSL_PASSPHRASE_EXEC> + SSLPassPhraseDialog exec:@ServerRoot@/conf/ssl/httpd-passphrase.pl + </IfDefine> + #else the default is builtin + <IfDefine !TEST_SSL_PASSPHRASE_EXEC> + SSLPassPhraseDialog builtin + </IfDefine> + + <IfDefine TEST_SSL_DES3_KEY> + SSLCertificateFile @SSLCA@/asf/certs/server_des3.crt + + SSLCertificateKeyFile @SSLCA@/asf/keys/server_des3.pem + +# SSLCertificateFile @SSLCA@/asf/certs/server_des3_dsa.crt + +# SSLCertificateKeyFile @SSLCA@/asf/keys/server_des3_dsa.pem + </IfDefine> + #else the default is an unencrypted key + <IfDefine !TEST_SSL_DES3_KEY> + SSLCertificateFile @SSLCA@/asf/certs/server.crt + + SSLCertificateKeyFile @SSLCA@/asf/keys/server.pem + +# SSLCertificateFile @SSLCA@/asf/certs/server_dsa.crt + +# SSLCertificateKeyFile @SSLCA@/asf/keys/server_dsa.pem + </IfDefine> + + #SSLCertificateChainFile @SSLCA@/asf/certs/cachain.crt + + SSLCACertificateFile @SSLCA@/asf/certs/ca.crt + + SSLCACertificatePath @ServerRoot@/conf/ssl + + SSLCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl + <IfVersion >= 2.3.15> + SSLCARevocationCheck chain + </IfVersion> + + <VirtualHost @ssl_module_name@> + SSLEngine on + + #t/ssl/verify.t + Alias /verify @DocumentRoot@ + + <Location /verify> + SSLVerifyClient require + SSLVerifyDepth 10 + </Location> + + # t/ssl/pha.t + <Location /require/small> + SSLVerifyClient require + SSLVerifyDepth 10 + + SSLRenegBufferSize 10 + </Location> + Alias /require/small @DocumentRoot@/modules/cgi + + #t/ssl/require.t + Alias /require/asf @DocumentRoot@ + Alias /require/snakeoil @DocumentRoot@ + Alias /require/certext @DocumentRoot@ + Alias /require/strcmp @DocumentRoot@ + Alias /require/intcmp @DocumentRoot@ + Alias /ssl-fakebasicauth @DocumentRoot@ + Alias /ssl-fakebasicauth2 @DocumentRoot@ + Alias /ssl-cgi @DocumentRoot@/modules/cgi + Alias /require-ssl-cgi @DocumentRoot@/modules/cgi + + Alias /require-aes128-cgi @DocumentRoot@/modules/cgi + Alias /require-aes256-cgi @DocumentRoot@/modules/cgi + + <Location /require/asf> + SSLVerifyClient require + SSLVerifyDepth 10 + SSLRequire (%{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \ + and %{SSL_CLIENT_S_DN_O} eq "ASF" \ + and %{SSL_CLIENT_S_DN_OU} in \ + {"httpd-test", "httpd", "modperl"} ) + </Location> + + <Location /require/snakeoil> + SSLVerifyClient require + SSLVerifyDepth 10 + SSLRequire (%{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \ + and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ + and %{SSL_CLIENT_S_DN_OU} in \ + {"Staff", "CA", "Dev"} ) + </Location> + + <Location /require/certext> + SSLVerifyClient require + <IfVersion > 2.3.0> + SSLRequire "Lemons" in PeerExtList("1.3.6.1.4.1.18060.12.0") + </IfVersion> + <IfVersion < 2.3.0> + <IfVersion > 2.1.6> + SSLRequire "Lemons" in OID("1.3.6.1.4.1.18060.12.0") + </IfVersion> + </IfVersion> + </Location> + + <Location /require/strcmp> + SSLRequire "a" < "b" + SSLRequire "a" lt "b" + </Location> + + <Location /require/intcmp> + SSLRequire 2 < 10 + SSLRequire 2 lt 10 + </Location> + + <Location /ssl-cgi> + SSLOptions +StdEnvVars + </Location> + + <Location /require-ssl-cgi> + SSLOptions +StdEnvVars + SSLVerifyClient require + SSLVerifyDepth 10 + </Location> + + <Location /require-aes128-cgi> + SSLCipherSuite AES128-SHA + </Location> + + <Location /require-aes256-cgi> + SSLCipherSuite AES256-SHA + </Location> + + <IfModule @AUTH_MODULE@> + <Location /ssl-fakebasicauth> + SSLVerifyClient require + SSLVerifyDepth 5 + SSLOptions +FakeBasicAuth + AuthName "Snake Oil Authentication" + AuthType Basic + AuthUserFile @SSLCA@/asf/ssl.htpasswd + require valid-user + </Location> + </IfModule> + + # specific to 2.1 + <IfModule mod_authn_anon.c> + <IfModule mod_auth_basic.c> + <Location /ssl-fakebasicauth2> + SSLVerifyClient require + SSLOptions +FakeBasicAuth +StdEnvVars + AuthName "Snake Oil Authentication" + AuthType Basic + AuthBasicProvider anon + Anonymous dummy "*" + require valid-user + </Location> + </IfModule> + </IfModule> + + ## + ## mod_h2 test config + ## + <IfModule h2_module> + LogLevel h2:debug + </IfModule> + + <IfModule @CGI_MODULE@> + <Directory @SERVERROOT@/htdocs/modules/h2> + Options +ExecCGI + AddHandler cgi-script .pl + + </Directory> + </IfModule> + <Location /modules/h2/hello.pl> + SSLOptions +StdEnvVars + </Location> + <IfModule mod_rewrite.c> + RewriteEngine on + RewriteRule ^/modules/h2/latest.tar.gz$ /modules/h2/xxx-1.0.2a.tar.gz [R=302,NC] + </IfModule> + + </VirtualHost> + + # An SSL vhost which does optional ccert checks at vhost level, to + # check for CVE CAN-2005-2700. + + <VirtualHost ssl_optional_cc> + SSLEngine on + + SSLVerifyClient optional + + Alias /require/any @DocumentRoot@ + Alias /require/none @DocumentRoot@ + + <Location /require/any> + SSLVerifyClient require + SSLVerifyDepth 10 + </Location> + </VirtualHost> + + # An SSL vhost which can be used to trigger PR 33791 + + <VirtualHost ssl_pr33791> + SSLEngine On + + ErrorDocument 400 /index.html + + <Location /> + SSLVerifyClient require + </Location> + </VirtualHost> + + # For t/ssl/ocsp.t -- + <Location /modules/ssl/ocsp> + SetEnv SSL_CA_ROOT @sslca@/asf + </Location> + Alias /modules/ssl/ocsp @DocumentRoot@/modules/cgi/ocsp.pl + + <VirtualHost ssl_ocsp> + SSLEngine on + + # SSLOCSPResponderCertificateFile is available from 2.4.26 + <IfVersion >= 2.4.26> + SSLVerifyClient on + + SSLOCSPEnable on + SSLOCSPDefaultResponder http://@SERVERNAME@:@PORT@/modules/ssl/ocsp + SSLOCSPResponderCertificateFile @SSLCA@/asf/certs/server.crt + + # Ignore CRL check results + SSLCARevocationCheck none + </IfVersion> + </VirtualHost> + + # For t/ssl/pr43738.t: + <IfModule mod_actions.c> + Action application/x-pf-action /modules/cgi/action.pl + + AddType application/x-pf-action .pfa + </IfModule> + + <Location /modules/ssl/aes128/> + SSLCipherSuite AES128-SHA + </Location> + + <Location /modules/ssl/aes256/> + SSLCipherSuite AES256-SHA + </Location> + +</IfModule> diff --git a/debian/perl-framework/t/conf/vhost_alias.conf.in b/debian/perl-framework/t/conf/vhost_alias.conf.in new file mode 100644 index 0000000..1173886 --- /dev/null +++ b/debian/perl-framework/t/conf/vhost_alias.conf.in @@ -0,0 +1,9 @@ +<IfModule mod_vhost_alias.c> + + <VirtualHost _default_:mod_vhost_alias> + UseCanonicalName Off + VirtualDocumentRoot @SERVERROOT@/htdocs/modules/vhost_alias/%2/%1.4/%-2/%2+ + VirtualScriptAlias @SERVERROOT@/htdocs/modules/vhost_alias/%0 + </VirtualHost> + +</IfModule> diff --git a/debian/perl-framework/t/filter/byterange.t b/debian/perl-framework/t/filter/byterange.t new file mode 100644 index 0000000..1c16f20 --- /dev/null +++ b/debian/perl-framework/t/filter/byterange.t @@ -0,0 +1,25 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2, + need( + need_module('mod_headers'), + need_min_apache_version('2.5.0') + ); + +my @headers; +push @headers, "Range" => "bytes=6549-"; + +my $uri = "/modules/filter/byterange/pr61860/test.html"; + +my $response = GET($uri, @headers); + +ok t_cmp($response->code, 416, "Out of Range bytes in header should return HTTP 416"); + +my @duplicate_header = $response->header("TestDuplicateHeader"); + +ok t_cmp(@duplicate_header, 1, "Headers should not be duplicated on HTTP 416 responses");
\ No newline at end of file diff --git a/debian/perl-framework/t/filter/case.t b/debian/perl-framework/t/filter/case.t new file mode 100644 index 0000000..94bbb08 --- /dev/null +++ b/debian/perl-framework/t/filter/case.t @@ -0,0 +1,42 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +#test output of some other modules +my %urls = ( + mod_php4 => '/php/hello.php', + mod_cgi => '/modules/cgi/perl.pl', + mod_test_rwrite => '/test_rwrite', + mod_alias => '/getfiles-perl-pod/perlsub.pod', +); + +my @filter = ('X-AddOutputFilter' => 'CaseFilter'); #mod_client_add_filter + +for my $module (keys %urls) { + delete $urls{$module} unless have_module($module); +} + +my $tests = 1 + scalar keys %urls; + +plan tests => $tests, need_module 'case_filter'; + +verify(GET '/', @filter); + +for my $module (sort keys %urls) { + my $r = GET $urls{$module}, @filter; + print "# testing $module with $urls{$module}\n"; + print "# expected 200\n"; + print "# received ".$r->code."\n"; + print "# body: ".$r->content."\n"; + verify($r); +} + +sub verify { + my $r = shift; + my $body = $r->content; + + ok $r->code == 200 and $body + and $body =~ /[A-Z]/ and $body !~ /[a-z]/; +} diff --git a/debian/perl-framework/t/filter/case_in.t b/debian/perl-framework/t/filter/case_in.t new file mode 100644 index 0000000..400418a --- /dev/null +++ b/debian/perl-framework/t/filter/case_in.t @@ -0,0 +1,42 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +#test output of some other modules +my %urls = ( + mod_php4 => '/php/var3u.php', + mod_cgi => '/modules/cgi/perl_echo.pl', + mod_echo_post => '/echo_post', +); + +my @filter = ('X-AddInputFilter' => 'CaseFilterIn'); #mod_client_add_filter + +for my $module (keys %urls) { + delete $urls{$module} unless have_module($module); +} + +my $tests = 1 + scalar keys %urls; + +plan tests => $tests, need_module 'case_filter_in'; + +ok 1; + +my $data = "v1=one&v3=two&v2=three"; + +for my $module (sort keys %urls) { + my $r = POST $urls{$module}, @filter, content => $data; + print "# testing $module with $urls{$module}\n"; + print "# expected 200\n"; + print "# received ".$r->code."\n"; + verify($r); +} + +sub verify { + my $r = shift; + my $body = $r->content; + + ok $r->code == 200 and $body + and $body =~ /[A-Z]/ and $body !~ /[a-z]/; +} diff --git a/debian/perl-framework/t/filter/input_body.t b/debian/perl-framework/t/filter/input_body.t new file mode 100644 index 0000000..a26ee06 --- /dev/null +++ b/debian/perl-framework/t/filter/input_body.t @@ -0,0 +1,19 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, [qw(input_body_filter)]; + +my $location = '/input_body_filter'; + +for my $x (1,2) { + my $expected = "ok $x"; + my $data = scalar reverse $expected; + my $response = POST_BODY $location, content => $data; + ok t_cmp($response, + $expected, + "Posted \"$data\""); +} diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/index.shtml b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/index.shtml new file mode 100644 index 0000000..cbf077b --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/index.shtml @@ -0,0 +1 @@ +_<!--#echo var="PATH_INFO"-->_ diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/info.php b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/info.php new file mode 100644 index 0000000..cc85423 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/info.php @@ -0,0 +1 @@ +_<?php echo $_SERVER['PATH_INFO']; ?>_
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/index.shtml b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/index.shtml new file mode 100644 index 0000000..cbf077b --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/index.shtml @@ -0,0 +1 @@ +_<!--#echo var="PATH_INFO"-->_ diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/info.php b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/info.php new file mode 100644 index 0000000..cc85423 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/info.php @@ -0,0 +1 @@ +_<?php echo $_SERVER['PATH_INFO']; ?>_
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/test.sh b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/test.sh new file mode 100755 index 0000000..fb36212 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/off/test.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo Content-type: text/plain +echo +if [ -z "$PATH_INFO" ]; then + echo "_(none)_" +else + echo _${PATH_INFO}_ +fi diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/index.shtml b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/index.shtml new file mode 100644 index 0000000..cbf077b --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/index.shtml @@ -0,0 +1 @@ +_<!--#echo var="PATH_INFO"-->_ diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/info.php b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/info.php new file mode 100644 index 0000000..cc85423 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/info.php @@ -0,0 +1 @@ +_<?php echo $_SERVER['PATH_INFO']; ?>_
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/test.sh b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/test.sh new file mode 100755 index 0000000..fb36212 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/on/test.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo Content-type: text/plain +echo +if [ -z "$PATH_INFO" ]; then + echo "_(none)_" +else + echo _${PATH_INFO}_ +fi diff --git a/debian/perl-framework/t/htdocs/apache/acceptpathinfo/test.sh b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/test.sh new file mode 100755 index 0000000..fb36212 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/acceptpathinfo/test.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo Content-type: text/plain +echo +if [ -z "$PATH_INFO" ]; then + echo "_(none)_" +else + echo _${PATH_INFO}_ +fi diff --git a/debian/perl-framework/t/htdocs/apache/cfg_getline/index.shtml b/debian/perl-framework/t/htdocs/apache/cfg_getline/index.shtml new file mode 100644 index 0000000..b78e4cd --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/cfg_getline/index.shtml @@ -0,0 +1 @@ +'<!--#echo var="testvar"-->' diff --git a/debian/perl-framework/t/htdocs/apache/chunked/flush.html b/debian/perl-framework/t/htdocs/apache/chunked/flush.html new file mode 100644 index 0000000..18f4778 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/chunked/flush.html @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbb
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/apache/chunked/flushheap0.html b/debian/perl-framework/t/htdocs/apache/chunked/flushheap0.html new file mode 100644 index 0000000..d4f178a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/chunked/flushheap0.html @@ -0,0 +1 @@ +bbbbbbbbbb
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/.htaccess new file mode 100644 index 0000000..c3e3e56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/.htaccess @@ -0,0 +1 @@ +FileETag All diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/i/.htaccess new file mode 100644 index 0000000..7e1132a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/i/.htaccess @@ -0,0 +1 @@ +FileETag INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/inherit/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/inherit/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/inherit/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/is/.htaccess new file mode 100644 index 0000000..f87c221 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/is/.htaccess @@ -0,0 +1 @@ +FileETag INode Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/m/.htaccess new file mode 100644 index 0000000..f68ec74 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/m/.htaccess @@ -0,0 +1 @@ +FileETag MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/mi/.htaccess new file mode 100644 index 0000000..90a2491 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/mi/.htaccess @@ -0,0 +1 @@ +FileETag MTime INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-i/.htaccess new file mode 100644 index 0000000..a7d90dd --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-i/.htaccess @@ -0,0 +1 @@ +FileETag -INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-is/.htaccess new file mode 100644 index 0000000..7e9db5a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-is/.htaccess @@ -0,0 +1 @@ +FileETag -INode -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-m/.htaccess new file mode 100644 index 0000000..733abb1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-m/.htaccess @@ -0,0 +1 @@ +FileETag -MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mi/.htaccess new file mode 100644 index 0000000..1e151b7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mi/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mis/.htaccess new file mode 100644 index 0000000..511a433 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mis/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -INode -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-ms/.htaccess new file mode 100644 index 0000000..820277a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-ms/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/minus-s/.htaccess new file mode 100644 index 0000000..78d5049 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-s/.htaccess @@ -0,0 +1 @@ +FileETag -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/minus-s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/minus-s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/minus-s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/mis/.htaccess new file mode 100644 index 0000000..738ee9e --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/mis/.htaccess @@ -0,0 +1 @@ +FileETag MTime INode Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/ms/.htaccess new file mode 100644 index 0000000..77d4985 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/ms/.htaccess @@ -0,0 +1 @@ +FileETag MTime Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/all/s/.htaccess new file mode 100644 index 0000000..5a40829 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/s/.htaccess @@ -0,0 +1 @@ +FileETag Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/all/test.txt b/debian/perl-framework/t/htdocs/apache/etags/all/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/all/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/default/test.txt b/debian/perl-framework/t/htdocs/apache/etags/default/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/default/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/i/.htaccess new file mode 100644 index 0000000..7e1132a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/i/.htaccess @@ -0,0 +1 @@ +FileETag INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/is/.htaccess new file mode 100644 index 0000000..f87c221 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/is/.htaccess @@ -0,0 +1 @@ +FileETag INode Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/.htaccess new file mode 100644 index 0000000..f68ec74 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/.htaccess @@ -0,0 +1 @@ +FileETag MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-i/.htaccess new file mode 100644 index 0000000..a7d90dd --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-i/.htaccess @@ -0,0 +1 @@ +FileETag -INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-is/.htaccess new file mode 100644 index 0000000..7e9db5a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-is/.htaccess @@ -0,0 +1 @@ +FileETag -INode -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-m/.htaccess new file mode 100644 index 0000000..733abb1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-m/.htaccess @@ -0,0 +1 @@ +FileETag -MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mi/.htaccess new file mode 100644 index 0000000..1e151b7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mi/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mis/.htaccess new file mode 100644 index 0000000..511a433 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mis/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -INode -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-ms/.htaccess new file mode 100644 index 0000000..820277a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-ms/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/minus-s/.htaccess new file mode 100644 index 0000000..78d5049 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-s/.htaccess @@ -0,0 +1 @@ +FileETag -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/minus-s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/minus-s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/minus-s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-i/.htaccess new file mode 100644 index 0000000..9a36c1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-i/.htaccess @@ -0,0 +1 @@ +FileETag +INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-is/.htaccess new file mode 100644 index 0000000..b8d7590 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-is/.htaccess @@ -0,0 +1 @@ +FileETag +INode +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-m/.htaccess new file mode 100644 index 0000000..4ec7a0f --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-m/.htaccess @@ -0,0 +1 @@ +FileETag +MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mi/.htaccess new file mode 100644 index 0000000..ee648bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mi/.htaccess @@ -0,0 +1 @@ +FileETag +MTime +INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mis/.htaccess new file mode 100644 index 0000000..2d9ce91 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mis/.htaccess @@ -0,0 +1 @@ +FileETag +MTime +INode +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-ms/.htaccess new file mode 100644 index 0000000..2b95bf5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-ms/.htaccess @@ -0,0 +1 @@ +FileETag +MTime +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/m/plus-s/.htaccess new file mode 100644 index 0000000..c8c876a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-s/.htaccess @@ -0,0 +1 @@ +FileETag +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/plus-s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/plus-s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/plus-s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/mi/.htaccess new file mode 100644 index 0000000..90a2491 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/mi/.htaccess @@ -0,0 +1 @@ +FileETag MTime INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/mis/.htaccess new file mode 100644 index 0000000..738ee9e --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/mis/.htaccess @@ -0,0 +1 @@ +FileETag MTime INode Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/ms/.htaccess new file mode 100644 index 0000000..77d4985 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/ms/.htaccess @@ -0,0 +1 @@ +FileETag MTime Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/.htaccess new file mode 100644 index 0000000..7ec3ed9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/.htaccess @@ -0,0 +1 @@ +FileETag None diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/i/.htaccess new file mode 100644 index 0000000..7e1132a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/i/.htaccess @@ -0,0 +1 @@ +FileETag INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/inherit/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/inherit/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/inherit/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/is/.htaccess new file mode 100644 index 0000000..f87c221 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/is/.htaccess @@ -0,0 +1 @@ +FileETag INode Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/m/.htaccess new file mode 100644 index 0000000..f68ec74 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/m/.htaccess @@ -0,0 +1 @@ +FileETag MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/mi/.htaccess new file mode 100644 index 0000000..90a2491 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/mi/.htaccess @@ -0,0 +1 @@ +FileETag MTime INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/mis/.htaccess new file mode 100644 index 0000000..738ee9e --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/mis/.htaccess @@ -0,0 +1 @@ +FileETag MTime INode Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/ms/.htaccess new file mode 100644 index 0000000..77d4985 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/ms/.htaccess @@ -0,0 +1 @@ +FileETag MTime Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-i/.htaccess new file mode 100644 index 0000000..9a36c1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-i/.htaccess @@ -0,0 +1 @@ +FileETag +INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-is/.htaccess new file mode 100644 index 0000000..b8d7590 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-is/.htaccess @@ -0,0 +1 @@ +FileETag +INode +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-m/.htaccess new file mode 100644 index 0000000..4ec7a0f --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-m/.htaccess @@ -0,0 +1 @@ +FileETag +MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mi/.htaccess new file mode 100644 index 0000000..ee648bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mi/.htaccess @@ -0,0 +1 @@ +FileETag +MTime +INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/.htaccess new file mode 100644 index 0000000..2d9ce91 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/.htaccess @@ -0,0 +1 @@ +FileETag +MTime +INode +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-i/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-i/.htaccess new file mode 100644 index 0000000..a7d90dd --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-i/.htaccess @@ -0,0 +1 @@ +FileETag -INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-i/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-i/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-i/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-is/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-is/.htaccess new file mode 100644 index 0000000..7e9db5a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-is/.htaccess @@ -0,0 +1 @@ +FileETag -INode -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-is/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-is/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-is/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-m/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-m/.htaccess new file mode 100644 index 0000000..733abb1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-m/.htaccess @@ -0,0 +1 @@ +FileETag -MTime diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-m/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-m/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-m/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mi/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mi/.htaccess new file mode 100644 index 0000000..1e151b7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mi/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -INode diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mi/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mi/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mi/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mis/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mis/.htaccess new file mode 100644 index 0000000..511a433 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mis/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -INode -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-ms/.htaccess new file mode 100644 index 0000000..820277a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-ms/.htaccess @@ -0,0 +1 @@ +FileETag -MTime -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-s/.htaccess new file mode 100644 index 0000000..78d5049 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-s/.htaccess @@ -0,0 +1 @@ +FileETag -Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/minus-s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-mis/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-ms/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-ms/.htaccess new file mode 100644 index 0000000..2b95bf5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-ms/.htaccess @@ -0,0 +1 @@ +FileETag +MTime +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-ms/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-ms/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-ms/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/plus-s/.htaccess new file mode 100644 index 0000000..c8c876a --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-s/.htaccess @@ -0,0 +1 @@ +FileETag +Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/plus-s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/plus-s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/plus-s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/none/s/.htaccess new file mode 100644 index 0000000..5a40829 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/s/.htaccess @@ -0,0 +1 @@ +FileETag Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/none/test.txt b/debian/perl-framework/t/htdocs/apache/etags/none/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/none/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/s/.htaccess b/debian/perl-framework/t/htdocs/apache/etags/s/.htaccess new file mode 100644 index 0000000..5a40829 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/s/.htaccess @@ -0,0 +1 @@ +FileETag Size diff --git a/debian/perl-framework/t/htdocs/apache/etags/s/test.txt b/debian/perl-framework/t/htdocs/apache/etags/s/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/s/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/etags/test.txt b/debian/perl-framework/t/htdocs/apache/etags/test.txt new file mode 100644 index 0000000..bce1946 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/etags/test.txt @@ -0,0 +1 @@ +Test file. diff --git a/debian/perl-framework/t/htdocs/apache/expr/index.html b/debian/perl-framework/t/htdocs/apache/expr/index.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/expr/index.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/apache/htaccess/override/.htaccess b/debian/perl-framework/t/htdocs/apache/htaccess/override/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/htaccess/override/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/apache/htaccess/override/hello.shtml b/debian/perl-framework/t/htdocs/apache/htaccess/override/hello.shtml new file mode 100644 index 0000000..b6fc4c6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/htaccess/override/hello.shtml @@ -0,0 +1 @@ +hello
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/apache/http_strict/send_hdr.pl.PL b/debian/perl-framework/t/htdocs/apache/http_strict/send_hdr.pl.PL new file mode 100644 index 0000000..95ccd85 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/http_strict/send_hdr.pl.PL @@ -0,0 +1,10 @@ +use MIME::Base64; +use strict; +use warnings; + +print "Content-type: text/plain\r\n"; +print decode_base64($ENV{QUERY_STRING}), "\r\n"; +print "\r\n"; +print "Hi!\n"; +print "SERVERNAME=$ENV{SERVER_NAME}\n"; +print "HTTP_HOST=$ENV{HTTP_HOST}\n"; diff --git a/debian/perl-framework/t/htdocs/apache/iffile/document b/debian/perl-framework/t/htdocs/apache/iffile/document new file mode 100644 index 0000000..48cdce8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/iffile/document @@ -0,0 +1 @@ +placeholder diff --git a/debian/perl-framework/t/htdocs/apache/limits/index.html b/debian/perl-framework/t/htdocs/apache/limits/index.html new file mode 100644 index 0000000..d4664a9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/limits/index.html @@ -0,0 +1 @@ +Welcome to the limits testing directory diff --git a/debian/perl-framework/t/htdocs/apache/loglevel/core_crit/info.html b/debian/perl-framework/t/htdocs/apache/loglevel/core_crit/info.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/loglevel/core_crit/info.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/apache/loglevel/core_info/info.html b/debian/perl-framework/t/htdocs/apache/loglevel/core_info/info.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/loglevel/core_info/info.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/apache/loglevel/crit/core_info/crit/info.html b/debian/perl-framework/t/htdocs/apache/loglevel/crit/core_info/crit/info.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/loglevel/crit/core_info/crit/info.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/apache/loglevel/info/core_crit/info/info.html b/debian/perl-framework/t/htdocs/apache/loglevel/info/core_crit/info/info.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/apache/loglevel/info/core_crit/info/info.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/authz/login.html b/debian/perl-framework/t/htdocs/authz/login.html new file mode 100644 index 0000000..5ae8d85 --- /dev/null +++ b/debian/perl-framework/t/htdocs/authz/login.html @@ -0,0 +1,9 @@ +<html> +<body> +<form method="POST" action="/authz/form/dologin.html"> +Username: <input type="text" name="httpd_username" value="" /> +Password: <input type="password" name="httpd_password" value="" /> +<input type="submit" name="login" value="Login" /> +</form> +</body> +</html> diff --git a/debian/perl-framework/t/htdocs/authz_core/a/b/c/index.html b/debian/perl-framework/t/htdocs/authz_core/a/b/c/index.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/authz_core/a/b/c/index.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/authz_core/a/b/index.html b/debian/perl-framework/t/htdocs/authz_core/a/b/index.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/authz_core/a/b/index.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/authz_core/a/index.html b/debian/perl-framework/t/htdocs/authz_core/a/index.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/authz_core/a/index.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/echo_post.html b/debian/perl-framework/t/htdocs/echo_post.html new file mode 100644 index 0000000..205c40f --- /dev/null +++ b/debian/perl-framework/t/htdocs/echo_post.html @@ -0,0 +1,11 @@ +<html> +<body> +<form action=/echo_post method=POST enctype=multipart/form-data> +This will be posted to /echo_post. +<hr> +<input type=file name=file> +<hr> +<input type=submit name=submit value=submit> +</form> +</body> +</html> diff --git a/debian/perl-framework/t/htdocs/expr/index.html b/debian/perl-framework/t/htdocs/expr/index.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/expr/index.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/expr/zero b/debian/perl-framework/t/htdocs/expr/zero new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/expr/zero diff --git a/debian/perl-framework/t/htdocs/foobar.html b/debian/perl-framework/t/htdocs/foobar.html new file mode 100644 index 0000000..f6ea049 --- /dev/null +++ b/debian/perl-framework/t/htdocs/foobar.html @@ -0,0 +1 @@ +foobar
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/if_sec/dir/foo.txt b/debian/perl-framework/t/htdocs/if_sec/dir/foo.txt new file mode 100644 index 0000000..5839fed --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/dir/foo.txt @@ -0,0 +1 @@ +dir/foo.txt diff --git a/debian/perl-framework/t/htdocs/if_sec/dir/index.html b/debian/perl-framework/t/htdocs/if_sec/dir/index.html new file mode 100644 index 0000000..833021b --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/dir/index.html @@ -0,0 +1 @@ +dir/index.html diff --git a/debian/perl-framework/t/htdocs/if_sec/foo.if_test b/debian/perl-framework/t/htdocs/if_sec/foo.if_test new file mode 100644 index 0000000..1a4c3c8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/foo.if_test @@ -0,0 +1 @@ +foo.if_test diff --git a/debian/perl-framework/t/htdocs/if_sec/index.html b/debian/perl-framework/t/htdocs/if_sec/index.html new file mode 100644 index 0000000..dcaf716 --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/index.html @@ -0,0 +1 @@ +index.html diff --git a/debian/perl-framework/t/htdocs/if_sec/loc/foo.if_test b/debian/perl-framework/t/htdocs/if_sec/loc/foo.if_test new file mode 100644 index 0000000..928a405 --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/loc/foo.if_test @@ -0,0 +1 @@ +loc/foo.if_test diff --git a/debian/perl-framework/t/htdocs/if_sec/loc/foo.txt b/debian/perl-framework/t/htdocs/if_sec/loc/foo.txt new file mode 100644 index 0000000..91ae231 --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/loc/foo.txt @@ -0,0 +1 @@ +loc/foo.txt diff --git a/debian/perl-framework/t/htdocs/if_sec/loc/index.html b/debian/perl-framework/t/htdocs/if_sec/loc/index.html new file mode 100644 index 0000000..fdd9648 --- /dev/null +++ b/debian/perl-framework/t/htdocs/if_sec/loc/index.html @@ -0,0 +1 @@ +loc/index.html diff --git a/debian/perl-framework/t/htdocs/index.html b/debian/perl-framework/t/htdocs/index.html new file mode 100644 index 0000000..d7e0f39 --- /dev/null +++ b/debian/perl-framework/t/htdocs/index.html @@ -0,0 +1 @@ +welcome to localhost:8529 diff --git a/debian/perl-framework/t/htdocs/modules/access/htaccess/index.html b/debian/perl-framework/t/htdocs/modules/access/htaccess/index.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/access/htaccess/index.html diff --git a/debian/perl-framework/t/htdocs/modules/actions/action/dummy.txt b/debian/perl-framework/t/htdocs/modules/actions/action/dummy.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/actions/action/dummy.txt diff --git a/debian/perl-framework/t/htdocs/modules/actions/script/dummy.txt b/debian/perl-framework/t/htdocs/modules/actions/script/dummy.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/actions/script/dummy.txt diff --git a/debian/perl-framework/t/htdocs/modules/alias/0.html b/debian/perl-framework/t/htdocs/modules/alias/0.html new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/0.html @@ -0,0 +1 @@ +0
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/1.html b/debian/perl-framework/t/htdocs/modules/alias/1.html new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/1.html @@ -0,0 +1 @@ +1
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/2.html b/debian/perl-framework/t/htdocs/modules/alias/2.html new file mode 100644 index 0000000..d8263ee --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/2.html @@ -0,0 +1 @@ +2
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/3.html b/debian/perl-framework/t/htdocs/modules/alias/3.html new file mode 100644 index 0000000..e440e5c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/3.html @@ -0,0 +1 @@ +3
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/4.html b/debian/perl-framework/t/htdocs/modules/alias/4.html new file mode 100644 index 0000000..bf0d87a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/4.html @@ -0,0 +1 @@ +4
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/5.html b/debian/perl-framework/t/htdocs/modules/alias/5.html new file mode 100644 index 0000000..7813681 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/5.html @@ -0,0 +1 @@ +5
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/6.html b/debian/perl-framework/t/htdocs/modules/alias/6.html new file mode 100644 index 0000000..62f9457 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/6.html @@ -0,0 +1 @@ +6
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/7.html b/debian/perl-framework/t/htdocs/modules/alias/7.html new file mode 100644 index 0000000..c793025 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/7.html @@ -0,0 +1 @@ +7
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/8.html b/debian/perl-framework/t/htdocs/modules/alias/8.html new file mode 100644 index 0000000..301160a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/8.html @@ -0,0 +1 @@ +8
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/9.html b/debian/perl-framework/t/htdocs/modules/alias/9.html new file mode 100644 index 0000000..f11c82a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/9.html @@ -0,0 +1 @@ +9
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/alias/index.html b/debian/perl-framework/t/htdocs/modules/alias/index.html new file mode 100644 index 0000000..4eed1c7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/alias/index.html @@ -0,0 +1 @@ +alias index diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Get/foo.txt b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/foo.txt new file mode 100644 index 0000000..5716ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/foo.txt @@ -0,0 +1 @@ +bar diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Get/none/.empty b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/none/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/none/.empty diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Get/post/foo.txt b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/post/foo.txt new file mode 100644 index 0000000..5716ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/post/foo.txt @@ -0,0 +1 @@ +bar diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Head/foo.txt b/debian/perl-framework/t/htdocs/modules/allowmethods/Head/foo.txt new file mode 100644 index 0000000..5716ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Head/foo.txt @@ -0,0 +1 @@ +bar diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/NoPost/.empty b/debian/perl-framework/t/htdocs/modules/allowmethods/NoPost/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/NoPost/.empty diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Post/foo.txt b/debian/perl-framework/t/htdocs/modules/allowmethods/Post/foo.txt new file mode 100644 index 0000000..5716ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Post/foo.txt @@ -0,0 +1 @@ +bar diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Post/reset/.empty b/debian/perl-framework/t/htdocs/modules/allowmethods/Post/reset/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Post/reset/.empty diff --git a/debian/perl-framework/t/htdocs/modules/asis/foo.asis b/debian/perl-framework/t/htdocs/modules/asis/foo.asis new file mode 100644 index 0000000..779c0e0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/asis/foo.asis @@ -0,0 +1,4 @@ +Status: 200 OK +Content-Type: text/html + +This is asis content. diff --git a/debian/perl-framework/t/htdocs/modules/asis/forbid.asis b/debian/perl-framework/t/htdocs/modules/asis/forbid.asis new file mode 100644 index 0000000..07a6595 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/asis/forbid.asis @@ -0,0 +1,4 @@ +Status: 403 No Such Luck, Mate +Content-Type: text/html + +This is a 403 response, lah di dah. diff --git a/debian/perl-framework/t/htdocs/modules/asis/notfound.asis b/debian/perl-framework/t/htdocs/modules/asis/notfound.asis new file mode 100644 index 0000000..923cb90 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/asis/notfound.asis @@ -0,0 +1,4 @@ +Status: 404 No Such File, Mate +Content-Type: text/html + +This is a 404 response, lah di dah. diff --git a/debian/perl-framework/t/htdocs/modules/cache/cache/index.html b/debian/perl-framework/t/htdocs/modules/cache/cache/index.html new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cache/cache/index.html @@ -0,0 +1 @@ +hello world diff --git a/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfodefault.sh b/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfodefault.sh new file mode 100755 index 0000000..d5885ee --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfodefault.sh @@ -0,0 +1,4 @@ +#!/bin/sh +echo Content-type: text/plain +echo +echo $PATH_INFO diff --git a/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfooff.sh b/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfooff.sh new file mode 100755 index 0000000..d5885ee --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfooff.sh @@ -0,0 +1,4 @@ +#!/bin/sh +echo Content-type: text/plain +echo +echo $PATH_INFO diff --git a/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfoon.sh b/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfoon.sh new file mode 100755 index 0000000..d5885ee --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/acceptpathinfoon.sh @@ -0,0 +1,4 @@ +#!/bin/sh +echo Content-type: text/plain +echo +echo $PATH_INFO diff --git a/debian/perl-framework/t/htdocs/modules/cgi/action.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/action.pl.PL new file mode 100644 index 0000000..19d6529 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/action.pl.PL @@ -0,0 +1,10 @@ +use strict; + +print "Content-type: text/plain\n\n"; + +print $ENV{PATH_INFO} . "\n"; + +if (my $ct = $ENV{CONTENT_LENGTH}) { + read STDIN, my $buffer, $ct; + print $buffer; +} diff --git a/debian/perl-framework/t/htdocs/modules/cgi/big.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/big.pl.PL new file mode 100644 index 0000000..636fb66 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/big.pl.PL @@ -0,0 +1,22 @@ +# This is a regression test for PR 31247. + +# By sleeping, it ensures that the CGI bucket is left in the brigade +# (the first 8K will be morphed into a HEAP bucket), and hence *must* +# be setaside correctly when the byterange filter calls +# ap_save_brigade(). + +# Without the fix for PR 31247, the STDOUT content does not get +# consumed as expected, so the server will deadlock as it tries to +# consume STDERR after script execution in mod_cgi, whilst the script +# tries to write to STDOUT. So close STDERR to avoid that. + +close STDERR; + +print "Content-type: text/plain\n\n"; + +print "x"x8192; + +sleep 1; + +print "x"x8192; + diff --git a/debian/perl-framework/t/htdocs/modules/cgi/bogus-perl.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/bogus-perl.pl.PL new file mode 100755 index 0000000..8abb7b2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/bogus-perl.pl.PL @@ -0,0 +1,2 @@ + +print "perl cgi"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/bogus-sh.sh b/debian/perl-framework/t/htdocs/modules/cgi/bogus-sh.sh new file mode 100755 index 0000000..3d49f92 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/bogus-sh.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echo sh cgi diff --git a/debian/perl-framework/t/htdocs/modules/cgi/bogus1k.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/bogus1k.pl.PL new file mode 100755 index 0000000..7c3d244 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/bogus1k.pl.PL @@ -0,0 +1,2 @@ + +print "N"x1024; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/empty.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/empty.pl.PL new file mode 100755 index 0000000..31e1ae9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/empty.pl.PL @@ -0,0 +1,6 @@ +use strict; + +print "Content-type: text/plain\r\n"; +print "Content-Length: 0\r\n"; +print "\r\n"; + diff --git a/debian/perl-framework/t/htdocs/modules/cgi/env.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/env.pl.PL new file mode 100644 index 0000000..f776cab --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/env.pl.PL @@ -0,0 +1,7 @@ +use strict; + +print "Content-type: text/plain\n\n"; + +for (sort keys %ENV) { + print "$_ = $ENV{$_}\n"; +} diff --git a/debian/perl-framework/t/htdocs/modules/cgi/not-modified.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/not-modified.pl.PL new file mode 100644 index 0000000..6684e48 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/not-modified.pl.PL @@ -0,0 +1,4 @@ +use strict; + +print "Status: 304 Not Modified\r\n\r\n"; + diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-102.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-102.pl.PL new file mode 100644 index 0000000..a49eeaa --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-102.pl.PL @@ -0,0 +1,9 @@ + +print "HTTP/1.1 102 Please Wait...\r\n"; +print "Host: nph-102\r\n\r\n"; + +print "HTTP/1.1 200 OK\r\n"; +print "Content-Type: text/plain\r\n\r\n"; + +print "this is nph-stdout"; + diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-dripfeed.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-dripfeed.pl.PL new file mode 100644 index 0000000..fa73355 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-dripfeed.pl.PL @@ -0,0 +1,17 @@ +print "HTTP/1.0 200 OK\r\n"; +print "Transfer-Encoding: chunked\r\n"; +print "\r\n"; + +$| = 1; + +sub dripfeed { + my $s = shift; + + while (length($s)) { + select(undef, undef, undef, 0.2); + print substr($s, 0, 1); + $s = substr($s, 1); + } +} + +dripfeed "0005\r\nabcde\r\n1; foo=bar\r\nf\r\n0\r\n\r\n"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-foldhdr.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-foldhdr.pl.PL new file mode 100644 index 0000000..67d7e9f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-foldhdr.pl.PL @@ -0,0 +1,12 @@ +# produces output with folded response headers + +print "HTTP/1.0 200 OK\r\n"; + +for (1..50) { + print "X-Foo-Bar-$_:\n " . 'x'x($_*10) . "\n"; + print "X-Bar-$_:\n gamm\r\n beta\n theta\r\n"; +} + +print "Content-type: \n text/plain\n\n"; + +print "hello, world"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-interim1.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-interim1.pl.PL new file mode 100644 index 0000000..87c0931 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-interim1.pl.PL @@ -0,0 +1,16 @@ +foreach $i (1..5) { +print <<EOT1 +HTTP/1.1 100 Continue +Server: Sausages/1.0 + +EOT1 +; +} + +print <<EOT2 +HTTP/1.1 200 OK +Content-Type: text/html + +Hello world +EOT2 +; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-interim2.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-interim2.pl.PL new file mode 100644 index 0000000..8a90b2f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-interim2.pl.PL @@ -0,0 +1,16 @@ +foreach $i (1..50) { +print <<EOT1 +HTTP/1.1 100 Continue +Server: Sausages/1.0 + +EOT1 +; +} + +print <<EOT2 +HTTP/1.1 200 OK +Content-Type: text/html + +Hello world +EOT2 +; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-stderr.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-stderr.pl.PL new file mode 100644 index 0000000..601adf9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-stderr.pl.PL @@ -0,0 +1,12 @@ +# produces lots of stderr output + +print "HTTP/1.0 200 OK\r\n"; + +print STDERR 'x'x8192; +print "Content-Type: text/plain\r\n\r\n"; + +print "this is nph-stdout"; + +close STDOUT; + +print STDERR "this is nph-stderr"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/nph-test.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/nph-test.pl.PL new file mode 100644 index 0000000..e679931 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/nph-test.pl.PL @@ -0,0 +1,9 @@ +print "HTTP/1.0 200 OK\r\n"; +print join("\n", + 'Content-type: text/html', + 'Pragma: no-cache', + 'Cache-control: must-revalidate, no-cache, no-store', + 'Expires: -1', + "\n"); + +print "ok\n"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/ocsp.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/ocsp.pl.PL new file mode 100644 index 0000000..efdbe8b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/ocsp.pl.PL @@ -0,0 +1,78 @@ +use File::Temp qw/:POSIX/; + +my $caroot = $ENV{SSL_CA_ROOT}; + +if (! -d $caroot) { + print <<EOT +Status: 500 Internal Server Error +Content-Type: text/plain + +Cannot find CA root at "$ENV{SSL_CA_ROOT}" +EOT + ; + print STDERR "SSL_CA_ROOT env var not set or can't find CA root.\n"; + exit(1); +} + +chdir($caroot); + +my $filein = tmpnam(); +my $fileout = tmpnam(); + +# Enable slurp mode (read all lines at once) +local $/; + +# Copy STDIN to $filein, which will be used as input for openssl +open(IN, '>', "$filein") or die "Could not open file '$filein' for write: $!"; +binmode IN; +print IN <STDIN>; +close(IN); + +my $cmd = 'openssl ocsp -CA certs/ca.crt'. + ' -index index.txt'. + ' -rsigner certs/server.crt'. + ' -rkey keys/server.pem'. + ' -reqin ' . $filein . + ' -respout ' . $fileout; +system($cmd); + +# Check system result +my $err = ''; +if ($? == -1) { + my $err = "failed to execute '$cmd': $!\n"; +} +elsif ($? & 127) { + my $err = sprintf("child '$cmd' died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'); +} +else { + my $rc = $? >> 8; + my $err = "child '$cmd' exited with value $rc\n" if $rc; +} + +unlink($filein); + +if ($err ne '') { + print <<EOT +Status: 500 Internal Server Error +Content-Type: text/plain + +$err +EOT + ; + print STDERR $err; + exit(1); +} + +print <<EOT +Content-Type: application/ocsp-response + +EOT +; + +# Copy openssl result from $fileout to STDOUT +open(OUT, '<', "$fileout") or die "Could not open file '$fileout' for read: $!"; +binmode OUT; +print <OUT>; +close(OUT); +unlink($fileout); diff --git a/debian/perl-framework/t/htdocs/modules/cgi/perl.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/perl.pl.PL new file mode 100755 index 0000000..51969cc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/perl.pl.PL @@ -0,0 +1,3 @@ + +print "Content-type: text/plain\n\n"; +print "perl cgi"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/perl_echo.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/perl_echo.pl.PL new file mode 100644 index 0000000..b7591a6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/perl_echo.pl.PL @@ -0,0 +1,14 @@ +#echo some data back to the client + +print "Content-type: text/plain\n\n"; + +if (my $ct = $ENV{CONTENT_LENGTH}) { + read STDIN, my $buffer, $ct; + print $buffer; +} +elsif (my $qs = $ENV{QUERY_STRING}) { + print $qs; +} +else { + print "nada"; +} diff --git a/debian/perl-framework/t/htdocs/modules/cgi/perl_post.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/perl_post.pl.PL new file mode 100755 index 0000000..e19d204 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/perl_post.pl.PL @@ -0,0 +1,23 @@ +local ($buffer, @pairs, $pair, $name, $value); + +print "Content-type: text/plain\n\n"; + +$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; +print "$ENV{'REQUEST_METHOD'}\n"; + +# Read in text +if ($ENV{'REQUEST_METHOD'} eq "POST") { + read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); +} else { + $buffer = $ENV{'QUERY_STRING'}; +} + +# Split information into name/value pairs +@pairs = split(/&/, $buffer); +foreach $pair (@pairs) { + ($name, $value) = split(/=/, $pair); + $value =~ tr/+/ /; + $value =~ s/%(..)/pack("C", hex($1))/eg; + + print "$name: $value\n"; +} diff --git a/debian/perl-framework/t/htdocs/modules/cgi/pr37166.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/pr37166.pl.PL new file mode 100644 index 0000000..f565c5c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/pr37166.pl.PL @@ -0,0 +1,8 @@ +print <<EOT +Status: 200 +Last-Modified: Tue, 15 Feb 2005 15:00:00 GMT +Content-Type: text/html + +Hello world +EOT +; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/ranged.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/ranged.pl.PL new file mode 100644 index 0000000..9d81f5d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/ranged.pl.PL @@ -0,0 +1,11 @@ +use strict; + +print "Content-type: text/plain\n"; + +if ($ENV{'HTTP_RANGE'} eq 'bytes=5-10/10') { + print "Content-Range: bytes 5-10/10\n\n"; + print "hello\n"; +} else { + print "\npardon?\n"; +} + diff --git a/debian/perl-framework/t/htdocs/modules/cgi/redirect.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/redirect.pl.PL new file mode 100644 index 0000000..9dc93e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/redirect.pl.PL @@ -0,0 +1,5 @@ +print <<EOT +Location: /foobar.html + +EOT +; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/sh.sh b/debian/perl-framework/t/htdocs/modules/cgi/sh.sh new file mode 100755 index 0000000..2907b61 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/sh.sh @@ -0,0 +1,4 @@ +#!/bin/sh +echo Content-type: text/plain +echo +echo sh cgi diff --git a/debian/perl-framework/t/htdocs/modules/cgi/stderr1.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/stderr1.pl.PL new file mode 100644 index 0000000..71b5a11 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/stderr1.pl.PL @@ -0,0 +1,7 @@ +# produces lots of stderr output + +print STDERR 'x'x8192; + +print "Content-Type: text/plain\n\n"; + +print "this is stdout"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/stderr2.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/stderr2.pl.PL new file mode 100644 index 0000000..a1580af --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/stderr2.pl.PL @@ -0,0 +1,9 @@ +# closes stderr during script execution + +close STDERR; + +print "Content-Type: text/plain\n\n"; + +sleep 1; + +print "this is also stdout"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/stderr3.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/stderr3.pl.PL new file mode 100644 index 0000000..f4927b5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/stderr3.pl.PL @@ -0,0 +1,8 @@ +# closes stderr during script execution + +print "Content-Type: text/plain\n\n"; +print "this is more stdout"; + +close STDOUT; + +print STDERR "this is a post-stdout-closure error message"; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/unique-id.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/unique-id.pl.PL new file mode 100644 index 0000000..e54ba40 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/unique-id.pl.PL @@ -0,0 +1,3 @@ +print "Content-type: text/plain\n\n"; + +print $ENV{UNIQUE_ID}; diff --git a/debian/perl-framework/t/htdocs/modules/cgi/xother.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/xother.pl.PL new file mode 100644 index 0000000..7cd005e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/xother.pl.PL @@ -0,0 +1,6 @@ +use strict; + +print "X-Foo: bar\n"; +print "Content-type: text/plain\n\n"; + +print "helloworld"; diff --git a/debian/perl-framework/t/htdocs/modules/data/SupportApache-small.png b/debian/perl-framework/t/htdocs/modules/data/SupportApache-small.png Binary files differnew file mode 100644 index 0000000..4a23e05 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/data/SupportApache-small.png diff --git a/debian/perl-framework/t/htdocs/modules/deflate/apache_pb.gif b/debian/perl-framework/t/htdocs/modules/deflate/apache_pb.gif Binary files differnew file mode 100644 index 0000000..3a1c139 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/apache_pb.gif diff --git a/debian/perl-framework/t/htdocs/modules/deflate/asf_logo_wide.jpg b/debian/perl-framework/t/htdocs/modules/deflate/asf_logo_wide.jpg Binary files differnew file mode 100644 index 0000000..82505e3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/asf_logo_wide.jpg diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BB.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BB.txt new file mode 100644 index 0000000..5c23cfa --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BB.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BBF.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BBF.txt new file mode 100644 index 0000000..359c0ae --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BBF.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BFB.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BFB.txt new file mode 100644 index 0000000..e4d7def --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/BFB.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/F.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/F.txt new file mode 100644 index 0000000..cbe9f63 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/F.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/FBP.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/FBP.txt new file mode 100644 index 0000000..bd9d9ba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/FBP.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/FP.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/FP.txt new file mode 100644 index 0000000..962702f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/FP.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/P.txt b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/P.txt new file mode 100644 index 0000000..71278af --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/bucketeer/P.txt @@ -0,0 +1,3 @@ + +Some dummy content. Some dummy content. Some dummy content. Some dummy content. +EOF diff --git a/debian/perl-framework/t/htdocs/modules/deflate/index.html b/debian/perl-framework/t/htdocs/modules/deflate/index.html new file mode 100644 index 0000000..28da53d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/index.html @@ -0,0 +1,2 @@ +welcome to the glorious world of mod_deflate! +welcome to the glorious world of mod_deflate! diff --git a/debian/perl-framework/t/htdocs/modules/deflate/ssi/default.html b/debian/perl-framework/t/htdocs/modules/deflate/ssi/default.html new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/ssi/default.html @@ -0,0 +1 @@ +default
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/deflate/ssi/ssi.shtml b/debian/perl-framework/t/htdocs/modules/deflate/ssi/ssi.shtml new file mode 100644 index 0000000..c739277 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/ssi/ssi.shtml @@ -0,0 +1 @@ +begin-<!--#include virtual="/modules/cgi/redirect.pl"-->-end diff --git a/debian/perl-framework/t/htdocs/modules/deflate/ssi/ssi2.shtml b/debian/perl-framework/t/htdocs/modules/deflate/ssi/ssi2.shtml new file mode 100644 index 0000000..4668cab --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/ssi/ssi2.shtml @@ -0,0 +1 @@ +begin-<!--#include virtual="/modules/deflate/ssi/"-->-end diff --git a/debian/perl-framework/t/htdocs/modules/deflate/zero.txt b/debian/perl-framework/t/htdocs/modules/deflate/zero.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/deflate/zero.txt diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/0.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/0.html new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/0.html @@ -0,0 +1 @@ +0
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/1.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/1.html new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/1.html @@ -0,0 +1 @@ +1
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/2.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/2.html new file mode 100644 index 0000000..d8263ee --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/2.html @@ -0,0 +1 @@ +2
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/3.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/3.html new file mode 100644 index 0000000..e440e5c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/3.html @@ -0,0 +1 @@ +3
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/4.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/4.html new file mode 100644 index 0000000..bf0d87a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/4.html @@ -0,0 +1 @@ +4
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/5.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/5.html new file mode 100644 index 0000000..7813681 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/5.html @@ -0,0 +1 @@ +5
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/6.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/6.html new file mode 100644 index 0000000..62f9457 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/6.html @@ -0,0 +1 @@ +6
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/7.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/7.html new file mode 100644 index 0000000..c793025 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/7.html @@ -0,0 +1 @@ +7
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/8.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/8.html new file mode 100644 index 0000000..301160a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/8.html @@ -0,0 +1 @@ +8
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/9.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/9.html new file mode 100644 index 0000000..f11c82a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/9.html @@ -0,0 +1 @@ +9
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/index.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/index.html new file mode 100644 index 0000000..be1a204 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/index.html @@ -0,0 +1 @@ +dir index diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/sub1/index.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/sub1/index.html new file mode 100644 index 0000000..be1a204 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/sub1/index.html @@ -0,0 +1 @@ +dir index diff --git a/debian/perl-framework/t/htdocs/modules/env/host.shtml b/debian/perl-framework/t/htdocs/modules/env/host.shtml new file mode 100644 index 0000000..245cbd5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/env/host.shtml @@ -0,0 +1 @@ +<!--#echo var="APACHE_TEST_HOSTNAME" --> diff --git a/debian/perl-framework/t/htdocs/modules/env/nothere.shtml b/debian/perl-framework/t/htdocs/modules/env/nothere.shtml new file mode 100644 index 0000000..ecd4939 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/env/nothere.shtml @@ -0,0 +1 @@ +<!--#echo var="NOT_HERE" --> diff --git a/debian/perl-framework/t/htdocs/modules/env/set.shtml b/debian/perl-framework/t/htdocs/modules/env/set.shtml new file mode 100644 index 0000000..d673f82 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/env/set.shtml @@ -0,0 +1 @@ +<!--#echo var="ENV_TEST" --> diff --git a/debian/perl-framework/t/htdocs/modules/env/setempty.shtml b/debian/perl-framework/t/htdocs/modules/env/setempty.shtml new file mode 100644 index 0000000..9e35f9b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/env/setempty.shtml @@ -0,0 +1 @@ +<!--#echo var="ENV_TEST_EMPTY" --> diff --git a/debian/perl-framework/t/htdocs/modules/env/type.shtml b/debian/perl-framework/t/htdocs/modules/env/type.shtml new file mode 100644 index 0000000..e1214d0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/env/type.shtml @@ -0,0 +1 @@ +<!--#echo var="APACHE_TEST_HOSTTYPE" --> diff --git a/debian/perl-framework/t/htdocs/modules/env/unset.shtml b/debian/perl-framework/t/htdocs/modules/env/unset.shtml new file mode 100644 index 0000000..acb5157 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/env/unset.shtml @@ -0,0 +1 @@ +<!--#echo var="UNSET" --> diff --git a/debian/perl-framework/t/htdocs/modules/expires/expire.html b/debian/perl-framework/t/htdocs/modules/expires/expire.html new file mode 100644 index 0000000..5a3cef1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/expire.html @@ -0,0 +1,4 @@ +<HTML> +<TITLE>expire test</TITLE> +<BODY>expire test</BODY> +</HTML> diff --git a/debian/perl-framework/t/htdocs/modules/expires/foo.jpg b/debian/perl-framework/t/htdocs/modules/expires/foo.jpg new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/foo.jpg diff --git a/debian/perl-framework/t/htdocs/modules/expires/htaccess/expire.html b/debian/perl-framework/t/htdocs/modules/expires/htaccess/expire.html new file mode 100644 index 0000000..5a3cef1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/htaccess/expire.html @@ -0,0 +1,4 @@ +<HTML> +<TITLE>expire test</TITLE> +<BODY>expire test</BODY> +</HTML> diff --git a/debian/perl-framework/t/htdocs/modules/expires/htaccess/foo.jpg b/debian/perl-framework/t/htdocs/modules/expires/htaccess/foo.jpg new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/htaccess/foo.jpg diff --git a/debian/perl-framework/t/htdocs/modules/expires/htaccess/image.gif b/debian/perl-framework/t/htdocs/modules/expires/htaccess/image.gif new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/htaccess/image.gif diff --git a/debian/perl-framework/t/htdocs/modules/expires/htaccess/index.html b/debian/perl-framework/t/htdocs/modules/expires/htaccess/index.html new file mode 100644 index 0000000..45b983b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/htaccess/index.html @@ -0,0 +1 @@ +hi diff --git a/debian/perl-framework/t/htdocs/modules/expires/htaccess/text.txt b/debian/perl-framework/t/htdocs/modules/expires/htaccess/text.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/htaccess/text.txt diff --git a/debian/perl-framework/t/htdocs/modules/expires/image.gif b/debian/perl-framework/t/htdocs/modules/expires/image.gif new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/image.gif diff --git a/debian/perl-framework/t/htdocs/modules/expires/index.html b/debian/perl-framework/t/htdocs/modules/expires/index.html new file mode 100644 index 0000000..45b983b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/index.html @@ -0,0 +1 @@ +hi diff --git a/debian/perl-framework/t/htdocs/modules/expires/text.txt b/debian/perl-framework/t/htdocs/modules/expires/text.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/expires/text.txt diff --git a/debian/perl-framework/t/htdocs/modules/ext_filter/eval-cmd.pl.PL b/debian/perl-framework/t/htdocs/modules/ext_filter/eval-cmd.pl.PL new file mode 100755 index 0000000..a416b26 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/ext_filter/eval-cmd.pl.PL @@ -0,0 +1,6 @@ +use strict; + +$| = 1; + +my $cmd = shift; +do {eval $cmd; print } while <>; diff --git a/debian/perl-framework/t/htdocs/modules/ext_filter/sleepycat.pl.PL b/debian/perl-framework/t/htdocs/modules/ext_filter/sleepycat.pl.PL new file mode 100644 index 0000000..fc9c399 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/ext_filter/sleepycat.pl.PL @@ -0,0 +1,3 @@ +$| = 1; + +print && select undef,undef,undef,.2 while <>; diff --git a/debian/perl-framework/t/htdocs/modules/filter/byterange/pr61860/test.html b/debian/perl-framework/t/htdocs/modules/filter/byterange/pr61860/test.html new file mode 100644 index 0000000..3b12464 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/byterange/pr61860/test.html @@ -0,0 +1 @@ +TEST
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/filter/bytype/test.css b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.css new file mode 100644 index 0000000..31e0fce --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.css @@ -0,0 +1 @@ +helloworld diff --git a/debian/perl-framework/t/htdocs/modules/filter/bytype/test.html b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.html new file mode 100644 index 0000000..31e0fce --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.html @@ -0,0 +1 @@ +helloworld diff --git a/debian/perl-framework/t/htdocs/modules/filter/bytype/test.txt b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.txt new file mode 100644 index 0000000..31e0fce --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.txt @@ -0,0 +1 @@ +helloworld diff --git a/debian/perl-framework/t/htdocs/modules/filter/bytype/test.xml b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.xml new file mode 100644 index 0000000..31e0fce --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/bytype/test.xml @@ -0,0 +1 @@ +helloworld diff --git a/debian/perl-framework/t/htdocs/modules/filter/pr49328/included.shtml b/debian/perl-framework/t/htdocs/modules/filter/pr49328/included.shtml new file mode 100644 index 0000000..28ea5a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/pr49328/included.shtml @@ -0,0 +1 @@ +included
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/filter/pr49328/pr49328.shtml b/debian/perl-framework/t/htdocs/modules/filter/pr49328/pr49328.shtml new file mode 100644 index 0000000..7425474 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/filter/pr49328/pr49328.shtml @@ -0,0 +1,3 @@ +before +<!--#include virtual="included.shtml" --> +after diff --git a/debian/perl-framework/t/htdocs/modules/h2/001.html b/debian/perl-framework/t/htdocs/modules/h2/001.html new file mode 100755 index 0000000..184952d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/001.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML>
+ <html>
+ <head>
+ <title>HTML/2.0 Test File: 001</title>
+ </head>
+ <body>
+ <p><h1>HTML/2.0 Test File: 001</h1></p>
+ <p>This file only contains a simple HTML structure with plain text.</p>
+ </body>
+</html>
diff --git a/debian/perl-framework/t/htdocs/modules/h2/002.jpg b/debian/perl-framework/t/htdocs/modules/h2/002.jpg Binary files differnew file mode 100755 index 0000000..3feefb0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/002.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/003.html b/debian/perl-framework/t/htdocs/modules/h2/003.html new file mode 100755 index 0000000..d5b08c5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/003.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML>
+ <html>
+ <head>
+ <title>HTML/2.0 Test File: 003</title>
+ </head>
+ <body>
+ <p><h1>HTML/2.0 Test File: 003</h1></p>
+ <p>This is a text HTML file with a big image:</p>
+ <p><img src="003/003_img.jpg" alt="GSMA Logo" style="width:269px;height:249px"></p>
+ </body>
+</html>
diff --git a/debian/perl-framework/t/htdocs/modules/h2/003/003_img.jpg b/debian/perl-framework/t/htdocs/modules/h2/003/003_img.jpg Binary files differnew file mode 100755 index 0000000..3feefb0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/003/003_img.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004.html b/debian/perl-framework/t/htdocs/modules/h2/004.html new file mode 100755 index 0000000..768cb82 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004.html @@ -0,0 +1,23 @@ +<html>
+ <head>
+ <title>HTML/2.0 Test File: 004</title>
+ </head>
+ <body>
+ <p><h1>HTML/2.0 Test File: 004</h1>
+ This file contains plain text with a bunch of images.<br>
+ <img src="004/gophertiles_142.jpg" height="32" width="32"><img src="004/gophertiles_084.jpg" height="32" width="32"><img src="004/gophertiles_052.jpg" height="32" width="32"><img src="004/gophertiles_077.jpg" height="32" width="32"><img src="004/gophertiles_030.jpg" height="32" width="32"><img src="004/gophertiles_027.jpg" height="32" width="32"><img src="004/gophertiles_039.jpg" height="32" width="32"><img src="004/gophertiles_025.jpg" height="32" width="32"><img src="004/gophertiles_017.jpg" height="32" width="32"><img src="004/gophertiles_179.jpg" height="32" width="32"><img src="004/gophertiles_032.jpg" height="32" width="32"><img src="004/gophertiles_161.jpg" height="32" width="32"><img src="004/gophertiles_088.jpg" height="32" width="32"><img src="004/gophertiles_022.jpg" height="32" width="32"><img src="004/gophertiles_146.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_102.jpg" height="32" width="32"><img src="004/gophertiles_009.jpg" height="32" width="32"><img src="004/gophertiles_132.jpg" height="32" width="32"><img src="004/gophertiles_137.jpg" height="32" width="32"><img src="004/gophertiles_055.jpg" height="32" width="32"><img src="004/gophertiles_036.jpg" height="32" width="32"><img src="004/gophertiles_127.jpg" height="32" width="32"><img src="004/gophertiles_145.jpg" height="32" width="32"><img src="004/gophertiles_147.jpg" height="32" width="32"><img src="004/gophertiles_153.jpg" height="32" width="32"><img src="004/gophertiles_105.jpg" height="32" width="32"><img src="004/gophertiles_103.jpg" height="32" width="32"><img src="004/gophertiles_033.jpg" height="32" width="32"><img src="004/gophertiles_054.jpg" height="32" width="32"><img src="004/gophertiles_015.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_016.jpg" height="32" width="32"><img src="004/gophertiles_072.jpg" height="32" width="32"><img src="004/gophertiles_115.jpg" height="32" width="32"><img src="004/gophertiles_108.jpg" height="32" width="32"><img src="004/gophertiles_148.jpg" height="32" width="32"><img src="004/gophertiles_070.jpg" height="32" width="32"><img src="004/gophertiles_083.jpg" height="32" width="32"><img src="004/gophertiles_118.jpg" height="32" width="32"><img src="004/gophertiles_053.jpg" height="32" width="32"><img src="004/gophertiles_021.jpg" height="32" width="32"><img src="004/gophertiles_059.jpg" height="32" width="32"><img src="004/gophertiles_130.jpg" height="32" width="32"><img src="004/gophertiles_163.jpg" height="32" width="32"><img src="004/gophertiles_098.jpg" height="32" width="32"><img src="004/gophertiles_064.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_018.jpg" height="32" width="32"><img src="004/gophertiles_058.jpg" height="32" width="32"><img src="004/gophertiles_167.jpg" height="32" width="32"><img src="004/gophertiles_082.jpg" height="32" width="32"><img src="004/gophertiles_056.jpg" height="32" width="32"><img src="004/gophertiles_180.jpg" height="32" width="32"><img src="004/gophertiles_046.jpg" height="32" width="32"><img src="004/gophertiles_093.jpg" height="32" width="32"><img src="004/gophertiles_106.jpg" height="32" width="32"><img src="004/gophertiles_065.jpg" height="32" width="32"><img src="004/gophertiles_175.jpg" height="32" width="32"><img src="004/gophertiles_139.jpg" height="32" width="32"><img src="004/gophertiles_101.jpg" height="32" width="32"><img src="004/gophertiles_099.jpg" height="32" width="32"><img src="004/gophertiles_051.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_140.jpg" height="32" width="32"><img src="004/gophertiles_134.jpg" height="32" width="32"><img src="004/gophertiles_149.jpg" height="32" width="32"><img src="004/gophertiles_049.jpg" height="32" width="32"><img src="004/gophertiles_095.jpg" height="32" width="32"><img src="004/gophertiles_075.jpg" height="32" width="32"><img src="004/gophertiles_066.jpg" height="32" width="32"><img src="004/gophertiles_090.jpg" height="32" width="32"><img src="004/gophertiles_035.jpg" height="32" width="32"><img src="004/gophertiles_114.jpg" height="32" width="32"><img src="004/gophertiles_160.jpg" height="32" width="32"><img src="004/gophertiles_079.jpg" height="32" width="32"><img src="004/gophertiles_062.jpg" height="32" width="32"><img src="004/gophertiles_096.jpg" height="32" width="32"><img src="004/gophertiles_100.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_104.jpg" height="32" width="32"><img src="004/gophertiles_057.jpg" height="32" width="32"><img src="004/gophertiles_037.jpg" height="32" width="32"><img src="004/gophertiles_086.jpg" height="32" width="32"><img src="004/gophertiles_168.jpg" height="32" width="32"><img src="004/gophertiles_138.jpg" height="32" width="32"><img src="004/gophertiles_045.jpg" height="32" width="32"><img src="004/gophertiles_141.jpg" height="32" width="32"><img src="004/gophertiles_029.jpg" height="32" width="32"><img src="004/gophertiles_165.jpg" height="32" width="32"><img src="004/gophertiles_110.jpg" height="32" width="32"><img src="004/gophertiles_063.jpg" height="32" width="32"><img src="004/gophertiles_158.jpg" height="32" width="32"><img src="004/gophertiles_122.jpg" height="32" width="32"><img src="004/gophertiles_068.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_170.jpg" height="32" width="32"><img src="004/gophertiles_120.jpg" height="32" width="32"><img src="004/gophertiles_117.jpg" height="32" width="32"><img src="004/gophertiles_031.jpg" height="32" width="32"><img src="004/gophertiles_113.jpg" height="32" width="32"><img src="004/gophertiles_074.jpg" height="32" width="32"><img src="004/gophertiles_129.jpg" height="32" width="32"><img src="004/gophertiles_019.jpg" height="32" width="32"><img src="004/gophertiles_060.jpg" height="32" width="32"><img src="004/gophertiles_109.jpg" height="32" width="32"><img src="004/gophertiles_080.jpg" height="32" width="32"><img src="004/gophertiles_097.jpg" height="32" width="32"><img src="004/gophertiles_116.jpg" height="32" width="32"><img src="004/gophertiles_085.jpg" height="32" width="32"><img src="004/gophertiles_050.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_151.jpg" height="32" width="32"><img src="004/gophertiles_094.jpg" height="32" width="32"><img src="004/gophertiles_067.jpg" height="32" width="32"><img src="004/gophertiles_128.jpg" height="32" width="32"><img src="004/gophertiles_034.jpg" height="32" width="32"><img src="004/gophertiles_135.jpg" height="32" width="32"><img src="004/gophertiles_012.jpg" height="32" width="32"><img src="004/gophertiles_010.jpg" height="32" width="32"><img src="004/gophertiles_152.jpg" height="32" width="32"><img src="004/gophertiles_171.jpg" height="32" width="32"><img src="004/gophertiles_087.jpg" height="32" width="32"><img src="004/gophertiles_126.jpg" height="32" width="32"><img src="004/gophertiles_048.jpg" height="32" width="32"><img src="004/gophertiles_023.jpg" height="32" width="32"><img src="004/gophertiles_078.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_071.jpg" height="32" width="32"><img src="004/gophertiles_131.jpg" height="32" width="32"><img src="004/gophertiles_073.jpg" height="32" width="32"><img src="004/gophertiles_143.jpg" height="32" width="32"><img src="004/gophertiles_173.jpg" height="32" width="32"><img src="004/gophertiles_154.jpg" height="32" width="32"><img src="004/gophertiles_061.jpg" height="32" width="32"><img src="004/gophertiles_178.jpg" height="32" width="32"><img src="004/gophertiles_013.jpg" height="32" width="32"><img src="004/gophertiles_028.jpg" height="32" width="32"><img src="004/gophertiles_157.jpg" height="32" width="32"><img src="004/gophertiles_038.jpg" height="32" width="32"><img src="004/gophertiles_069.jpg" height="32" width="32"><img src="004/gophertiles_174.jpg" height="32" width="32"><img src="004/gophertiles_076.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_155.jpg" height="32" width="32"><img src="004/gophertiles_107.jpg" height="32" width="32"><img src="004/gophertiles_136.jpg" height="32" width="32"><img src="004/gophertiles_144.jpg" height="32" width="32"><img src="004/gophertiles_091.jpg" height="32" width="32"><img src="004/gophertiles_024.jpg" height="32" width="32"><img src="004/gophertiles_014.jpg" height="32" width="32"><img src="004/gophertiles_159.jpg" height="32" width="32"><img src="004/gophertiles_011.jpg" height="32" width="32"><img src="004/gophertiles_176.jpg" height="32" width="32"><img src="004/gophertiles_162.jpg" height="32" width="32"><img src="004/gophertiles_156.jpg" height="32" width="32"><img src="004/gophertiles_081.jpg" height="32" width="32"><img src="004/gophertiles_119.jpg" height="32" width="32"><img src="004/gophertiles_026.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_133.jpg" height="32" width="32"><img src="004/gophertiles_020.jpg" height="32" width="32"><img src="004/gophertiles_044.jpg" height="32" width="32"><img src="004/gophertiles_125.jpg" height="32" width="32"><img src="004/gophertiles_150.jpg" height="32" width="32"><img src="004/gophertiles_172.jpg" height="32" width="32"><img src="004/gophertiles_002.jpg" height="32" width="32"><img src="004/gophertiles_169.jpg" height="32" width="32"><img src="004/gophertiles_007.jpg" height="32" width="32"><img src="004/gophertiles_008.jpg" height="32" width="32"><img src="004/gophertiles_042.jpg" height="32" width="32"><img src="004/gophertiles_041.jpg" height="32" width="32"><img src="004/gophertiles_166.jpg" height="32" width="32"><img src="004/gophertiles_005.jpg" height="32" width="32"><img src="004/gophertiles_089.jpg" height="32" width="32"><br>
+ <img src="004/gophertiles_177.jpg" height="32" width="32"><img src="004/gophertiles_092.jpg" height="32" width="32"><img src="004/gophertiles_043.jpg" height="32" width="32"><img src="004/gophertiles_111.jpg" height="32" width="32"><img src="004/gophertiles_047.jpg" height="32" width="32"><img src="004/gophertiles.jpg" height="32" width="32"><img src="004/gophertiles_006.jpg" height="32" width="32"><img src="004/gophertiles_121.jpg" height="32" width="32"><img src="004/gophertiles_004.jpg" height="32" width="32"><img src="004/gophertiles_124.jpg" height="32" width="32"><img src="004/gophertiles_123.jpg" height="32" width="32"><img src="004/gophertiles_112.jpg" height="32" width="32"><img src="004/gophertiles_040.jpg" height="32" width="32"><img src="004/gophertiles_164.jpg" height="32" width="32"><img src="004/gophertiles_003.jpg" height="32" width="32"><br>
+ <hr>This page is developed using this template:<a href="https://http2.golang.org/">HTTP/2 demo server</a>
+ </p>
+ </body>
+</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles.jpg Binary files differnew file mode 100755 index 0000000..e45ac3b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_002.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_002.jpg Binary files differnew file mode 100755 index 0000000..91121de --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_002.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_003.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_003.jpg Binary files differnew file mode 100755 index 0000000..a26648f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_003.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_004.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_004.jpg Binary files differnew file mode 100755 index 0000000..1d2db98 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_004.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_005.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_005.jpg Binary files differnew file mode 100755 index 0000000..05a298c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_005.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_006.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_006.jpg Binary files differnew file mode 100755 index 0000000..54a4920 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_006.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_007.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_007.jpg Binary files differnew file mode 100755 index 0000000..526f850 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_007.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_008.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_008.jpg Binary files differnew file mode 100755 index 0000000..35f5a2f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_008.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_009.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_009.jpg Binary files differnew file mode 100755 index 0000000..96ec2b8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_009.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_010.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_010.jpg Binary files differnew file mode 100755 index 0000000..95a9509 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_010.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_011.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_011.jpg Binary files differnew file mode 100755 index 0000000..65701ed --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_011.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_012.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_012.jpg Binary files differnew file mode 100755 index 0000000..6242fa6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_012.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_013.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_013.jpg Binary files differnew file mode 100755 index 0000000..8096ab2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_013.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_014.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_014.jpg Binary files differnew file mode 100755 index 0000000..e027312 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_014.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_015.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_015.jpg Binary files differnew file mode 100755 index 0000000..a27076d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_015.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_016.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_016.jpg Binary files differnew file mode 100755 index 0000000..04b20db --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_016.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_017.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_017.jpg Binary files differnew file mode 100755 index 0000000..9b6e44b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_017.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_018.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_018.jpg Binary files differnew file mode 100755 index 0000000..209b6fd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_018.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_019.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_019.jpg Binary files differnew file mode 100755 index 0000000..3bc23a3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_019.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_020.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_020.jpg Binary files differnew file mode 100755 index 0000000..ba04297 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_020.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_021.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_021.jpg Binary files differnew file mode 100755 index 0000000..f5a422f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_021.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_022.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_022.jpg Binary files differnew file mode 100755 index 0000000..cb49051 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_022.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_023.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_023.jpg Binary files differnew file mode 100755 index 0000000..7e83a7e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_023.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_024.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_024.jpg Binary files differnew file mode 100755 index 0000000..87c711b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_024.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_025.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_025.jpg Binary files differnew file mode 100755 index 0000000..c42eb3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_025.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_026.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_026.jpg Binary files differnew file mode 100755 index 0000000..29f9da6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_026.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_027.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_027.jpg Binary files differnew file mode 100755 index 0000000..6ceccde --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_027.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_028.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_028.jpg Binary files differnew file mode 100755 index 0000000..6e3cb34 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_028.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_029.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_029.jpg Binary files differnew file mode 100755 index 0000000..dac302b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_029.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_030.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_030.jpg Binary files differnew file mode 100755 index 0000000..4299071 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_030.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_031.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_031.jpg Binary files differnew file mode 100755 index 0000000..739924f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_031.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_032.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_032.jpg Binary files differnew file mode 100755 index 0000000..4685513 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_032.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_033.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_033.jpg Binary files differnew file mode 100755 index 0000000..26ea0e1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_033.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_034.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_034.jpg Binary files differnew file mode 100755 index 0000000..f02930e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_034.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_035.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_035.jpg Binary files differnew file mode 100755 index 0000000..8b6bde8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_035.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_036.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_036.jpg Binary files differnew file mode 100755 index 0000000..23ac1c0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_036.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_037.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_037.jpg Binary files differnew file mode 100755 index 0000000..6de6681 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_037.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_038.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_038.jpg Binary files differnew file mode 100755 index 0000000..aea11a3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_038.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_039.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_039.jpg Binary files differnew file mode 100755 index 0000000..bb54d13 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_039.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_040.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_040.jpg Binary files differnew file mode 100755 index 0000000..91591af --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_040.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_041.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_041.jpg Binary files differnew file mode 100755 index 0000000..96b13dd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_041.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_042.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_042.jpg Binary files differnew file mode 100755 index 0000000..0ef80f1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_042.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_043.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_043.jpg Binary files differnew file mode 100755 index 0000000..c3828a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_043.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_044.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_044.jpg Binary files differnew file mode 100755 index 0000000..036ec10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_044.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_045.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_045.jpg Binary files differnew file mode 100755 index 0000000..03f5413 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_045.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_046.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_046.jpg Binary files differnew file mode 100755 index 0000000..8353e24 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_046.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_047.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_047.jpg Binary files differnew file mode 100755 index 0000000..86e4d88 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_047.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_048.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_048.jpg Binary files differnew file mode 100755 index 0000000..8f308ed --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_048.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_049.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_049.jpg Binary files differnew file mode 100755 index 0000000..bf22844 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_049.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_050.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_050.jpg Binary files differnew file mode 100755 index 0000000..65addde --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_050.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_051.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_051.jpg Binary files differnew file mode 100755 index 0000000..aabb52b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_051.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_052.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_052.jpg Binary files differnew file mode 100755 index 0000000..3d4bad8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_052.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_053.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_053.jpg Binary files differnew file mode 100755 index 0000000..d30c4d0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_053.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_054.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_054.jpg Binary files differnew file mode 100755 index 0000000..c27a34c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_054.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_055.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_055.jpg Binary files differnew file mode 100755 index 0000000..bac6e3f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_055.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_056.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_056.jpg Binary files differnew file mode 100755 index 0000000..246624e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_056.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_057.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_057.jpg Binary files differnew file mode 100755 index 0000000..0122037 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_057.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_058.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_058.jpg Binary files differnew file mode 100755 index 0000000..71f602f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_058.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_059.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_059.jpg Binary files differnew file mode 100755 index 0000000..78b0dd1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_059.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_060.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_060.jpg Binary files differnew file mode 100755 index 0000000..b2c699c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_060.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_061.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_061.jpg Binary files differnew file mode 100755 index 0000000..082fe53 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_061.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_062.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_062.jpg Binary files differnew file mode 100755 index 0000000..9b3bd8a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_062.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_063.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_063.jpg Binary files differnew file mode 100755 index 0000000..34bbfc5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_063.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_064.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_064.jpg Binary files differnew file mode 100755 index 0000000..ac0ddc7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_064.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_065.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_065.jpg Binary files differnew file mode 100755 index 0000000..f85dce5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_065.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_066.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_066.jpg Binary files differnew file mode 100755 index 0000000..616dd5c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_066.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_067.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_067.jpg Binary files differnew file mode 100755 index 0000000..bbbaecf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_067.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_068.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_068.jpg Binary files differnew file mode 100755 index 0000000..d0b6a18 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_068.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_069.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_069.jpg Binary files differnew file mode 100755 index 0000000..27e1abc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_069.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_070.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_070.jpg Binary files differnew file mode 100755 index 0000000..de1a15e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_070.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_071.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_071.jpg Binary files differnew file mode 100755 index 0000000..40912e3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_071.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_072.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_072.jpg Binary files differnew file mode 100755 index 0000000..ef01d06 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_072.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_073.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_073.jpg Binary files differnew file mode 100755 index 0000000..3298be7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_073.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_074.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_074.jpg Binary files differnew file mode 100755 index 0000000..28fb75c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_074.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_075.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_075.jpg Binary files differnew file mode 100755 index 0000000..1f70c5e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_075.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_076.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_076.jpg Binary files differnew file mode 100755 index 0000000..d929f53 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_076.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_077.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_077.jpg Binary files differnew file mode 100755 index 0000000..49c8ca1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_077.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_078.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_078.jpg Binary files differnew file mode 100755 index 0000000..a21dd87 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_078.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_079.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_079.jpg Binary files differnew file mode 100755 index 0000000..bfbd4c2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_079.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_080.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_080.jpg Binary files differnew file mode 100755 index 0000000..6ff068c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_080.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_081.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_081.jpg Binary files differnew file mode 100755 index 0000000..dd615c7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_081.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_082.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_082.jpg Binary files differnew file mode 100755 index 0000000..0c28382 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_082.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_083.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_083.jpg Binary files differnew file mode 100755 index 0000000..5512c16 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_083.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_084.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_084.jpg Binary files differnew file mode 100755 index 0000000..d08ac7b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_084.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_085.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_085.jpg Binary files differnew file mode 100755 index 0000000..c098f72 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_085.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_086.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_086.jpg Binary files differnew file mode 100755 index 0000000..203e41d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_086.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_087.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_087.jpg Binary files differnew file mode 100755 index 0000000..b664135 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_087.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_088.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_088.jpg Binary files differnew file mode 100755 index 0000000..e211d21 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_088.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_089.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_089.jpg Binary files differnew file mode 100755 index 0000000..00c4730 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_089.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_090.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_090.jpg Binary files differnew file mode 100755 index 0000000..7203f10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_090.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_091.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_091.jpg Binary files differnew file mode 100755 index 0000000..f57baa9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_091.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_092.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_092.jpg Binary files differnew file mode 100755 index 0000000..cba16c6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_092.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_093.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_093.jpg Binary files differnew file mode 100755 index 0000000..6d4c1a5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_093.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_094.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_094.jpg Binary files differnew file mode 100755 index 0000000..a5f6a2a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_094.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_095.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_095.jpg Binary files differnew file mode 100755 index 0000000..d213fe5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_095.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_096.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_096.jpg Binary files differnew file mode 100755 index 0000000..0fd51eb --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_096.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_097.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_097.jpg Binary files differnew file mode 100755 index 0000000..2b706cc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_097.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_098.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_098.jpg Binary files differnew file mode 100755 index 0000000..7861f2a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_098.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_099.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_099.jpg Binary files differnew file mode 100755 index 0000000..be10042 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_099.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_100.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_100.jpg Binary files differnew file mode 100755 index 0000000..8687873 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_100.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_101.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_101.jpg Binary files differnew file mode 100755 index 0000000..fe4b56a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_101.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_102.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_102.jpg Binary files differnew file mode 100755 index 0000000..d888f6c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_102.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_103.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_103.jpg Binary files differnew file mode 100755 index 0000000..4ebf13d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_103.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_104.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_104.jpg Binary files differnew file mode 100755 index 0000000..b4dc051 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_104.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_105.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_105.jpg Binary files differnew file mode 100755 index 0000000..4f3c5a1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_105.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_106.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_106.jpg Binary files differnew file mode 100755 index 0000000..51d6742 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_106.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_107.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_107.jpg Binary files differnew file mode 100755 index 0000000..ef986b7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_107.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_108.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_108.jpg Binary files differnew file mode 100755 index 0000000..8901141 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_108.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_109.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_109.jpg Binary files differnew file mode 100755 index 0000000..a946a2b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_109.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_110.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_110.jpg Binary files differnew file mode 100755 index 0000000..35d542c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_110.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_111.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_111.jpg Binary files differnew file mode 100755 index 0000000..0ec9641 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_111.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_112.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_112.jpg Binary files differnew file mode 100755 index 0000000..530739a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_112.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_113.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_113.jpg Binary files differnew file mode 100755 index 0000000..0537d7f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_113.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_114.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_114.jpg Binary files differnew file mode 100755 index 0000000..9ecb936 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_114.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_115.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_115.jpg Binary files differnew file mode 100755 index 0000000..221e6f4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_115.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_116.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_116.jpg Binary files differnew file mode 100755 index 0000000..0de1084 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_116.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_117.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_117.jpg Binary files differnew file mode 100755 index 0000000..8ebd1ea --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_117.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_118.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_118.jpg Binary files differnew file mode 100755 index 0000000..246d055 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_118.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_119.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_119.jpg Binary files differnew file mode 100755 index 0000000..8d92e15 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_119.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_120.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_120.jpg Binary files differnew file mode 100755 index 0000000..8ebef73 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_120.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_121.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_121.jpg Binary files differnew file mode 100755 index 0000000..e7a3772 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_121.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_122.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_122.jpg Binary files differnew file mode 100755 index 0000000..6a57fc8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_122.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_123.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_123.jpg Binary files differnew file mode 100755 index 0000000..b941523 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_123.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_124.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_124.jpg Binary files differnew file mode 100755 index 0000000..9dddf38 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_124.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_125.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_125.jpg Binary files differnew file mode 100755 index 0000000..d2e479e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_125.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_126.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_126.jpg Binary files differnew file mode 100755 index 0000000..32fc518 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_126.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_127.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_127.jpg Binary files differnew file mode 100755 index 0000000..c5f71cc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_127.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_128.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_128.jpg Binary files differnew file mode 100755 index 0000000..d899e3d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_128.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_129.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_129.jpg Binary files differnew file mode 100755 index 0000000..3508872 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_129.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_130.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_130.jpg Binary files differnew file mode 100755 index 0000000..b26d716 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_130.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_131.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_131.jpg Binary files differnew file mode 100755 index 0000000..56a27d4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_131.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_132.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_132.jpg Binary files differnew file mode 100755 index 0000000..b34a2f0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_132.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_133.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_133.jpg Binary files differnew file mode 100755 index 0000000..b5dc4da --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_133.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_134.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_134.jpg Binary files differnew file mode 100755 index 0000000..24d6866 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_134.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_135.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_135.jpg Binary files differnew file mode 100755 index 0000000..f0c27c8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_135.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_136.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_136.jpg Binary files differnew file mode 100755 index 0000000..d3b3b28 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_136.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_137.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_137.jpg Binary files differnew file mode 100755 index 0000000..7e78d35 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_137.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_138.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_138.jpg Binary files differnew file mode 100755 index 0000000..5a0024e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_138.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_139.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_139.jpg Binary files differnew file mode 100755 index 0000000..e0e16bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_139.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_140.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_140.jpg Binary files differnew file mode 100755 index 0000000..b9c54c4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_140.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_141.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_141.jpg Binary files differnew file mode 100755 index 0000000..f62eada --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_141.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_142.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_142.jpg Binary files differnew file mode 100755 index 0000000..6085722 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_142.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_143.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_143.jpg Binary files differnew file mode 100755 index 0000000..f533fe5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_143.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_144.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_144.jpg Binary files differnew file mode 100755 index 0000000..bcc5602 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_144.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_145.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_145.jpg Binary files differnew file mode 100755 index 0000000..3b9402e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_145.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_146.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_146.jpg Binary files differnew file mode 100755 index 0000000..f2f049b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_146.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_147.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_147.jpg Binary files differnew file mode 100755 index 0000000..06fc738 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_147.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_148.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_148.jpg Binary files differnew file mode 100755 index 0000000..e094d96 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_148.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_149.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_149.jpg Binary files differnew file mode 100755 index 0000000..26ab8d7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_149.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_150.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_150.jpg Binary files differnew file mode 100755 index 0000000..02ca417 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_150.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_151.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_151.jpg Binary files differnew file mode 100755 index 0000000..78fe841 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_151.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_152.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_152.jpg Binary files differnew file mode 100755 index 0000000..9cfa47a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_152.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_153.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_153.jpg Binary files differnew file mode 100755 index 0000000..0a67731 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_153.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_154.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_154.jpg Binary files differnew file mode 100755 index 0000000..9a38955 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_154.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_155.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_155.jpg Binary files differnew file mode 100755 index 0000000..5a10b47 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_155.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_156.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_156.jpg Binary files differnew file mode 100755 index 0000000..809d5f9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_156.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_157.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_157.jpg Binary files differnew file mode 100755 index 0000000..8c852e2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_157.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_158.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_158.jpg Binary files differnew file mode 100755 index 0000000..5ef80f7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_158.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_159.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_159.jpg Binary files differnew file mode 100755 index 0000000..2fe485f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_159.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_160.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_160.jpg Binary files differnew file mode 100755 index 0000000..072cfc6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_160.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_161.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_161.jpg Binary files differnew file mode 100755 index 0000000..cd66e83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_161.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_162.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_162.jpg Binary files differnew file mode 100755 index 0000000..6af87e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_162.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_163.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_163.jpg Binary files differnew file mode 100755 index 0000000..1a903c3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_163.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_164.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_164.jpg Binary files differnew file mode 100755 index 0000000..71694cf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_164.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_165.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_165.jpg Binary files differnew file mode 100755 index 0000000..084c64a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_165.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_166.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_166.jpg Binary files differnew file mode 100755 index 0000000..6554740 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_166.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_167.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_167.jpg Binary files differnew file mode 100755 index 0000000..ef2d248 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_167.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_168.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_168.jpg Binary files differnew file mode 100755 index 0000000..fda5636 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_168.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_169.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_169.jpg Binary files differnew file mode 100755 index 0000000..7b53b20 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_169.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_170.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_170.jpg Binary files differnew file mode 100755 index 0000000..271c69d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_170.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_171.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_171.jpg Binary files differnew file mode 100755 index 0000000..a52ac34 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_171.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_172.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_172.jpg Binary files differnew file mode 100755 index 0000000..7438a7e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_172.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_173.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_173.jpg Binary files differnew file mode 100755 index 0000000..d91d538 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_173.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_174.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_174.jpg Binary files differnew file mode 100755 index 0000000..3901ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_174.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_175.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_175.jpg Binary files differnew file mode 100755 index 0000000..106900d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_175.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_176.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_176.jpg Binary files differnew file mode 100755 index 0000000..c4a54bf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_176.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_177.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_177.jpg Binary files differnew file mode 100755 index 0000000..d214f26 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_177.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_178.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_178.jpg Binary files differnew file mode 100755 index 0000000..be6cb55 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_178.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_179.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_179.jpg Binary files differnew file mode 100755 index 0000000..516faa1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_179.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_180.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_180.jpg Binary files differnew file mode 100755 index 0000000..67bf870 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_180.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/006.html b/debian/perl-framework/t/htdocs/modules/h2/006.html new file mode 100755 index 0000000..6b73025 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/006.html @@ -0,0 +1,23 @@ +<!DOCTYPE HTML>
+ <html>
+ <head>
+ <title>HTML/2.0 Test File: 006</title>
+ <link rel="stylesheet" type="text/css" href="006/006.css">
+ <script type="text/javascript" src="006/006.js"></script>
+ </head>
+ <body>
+ <h1>HTML/2.0 Test File: 006</h1>
+ <div class="listTitle">This page contains:
+ <ul class="listElements">
+ <li>HTML
+ <li>CSS
+ <li>JavaScript
+ </ul>
+ </div>
+ <div class="listTitle">
+ <script type="text/javascript">
+ mainJavascript();
+ </script>
+ </div>
+ </body>
+</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/006/006.css b/debian/perl-framework/t/htdocs/modules/h2/006/006.css new file mode 100755 index 0000000..de6aa5f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/006/006.css @@ -0,0 +1,21 @@ +@CHARSET "ISO-8859-1";
+body{
+ background:HoneyDew;
+}
+p{
+color:#0000FF;
+text-align:left;
+}
+
+h1{
+color:#FF0000;
+text-align:center;
+}
+
+.listTitle{
+ font-size:large;
+}
+
+.listElements{
+ color:#3366FF
+}
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/006/006.js b/debian/perl-framework/t/htdocs/modules/h2/006/006.js new file mode 100755 index 0000000..b450067 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/006/006.js @@ -0,0 +1,31 @@ +/**
+ * JavaScript Functions File
+ */
+function returnDate()
+{
+ var currentDate;
+ currentDate=new Date();
+ var dateString=(currentDate.getMonth()+1)+'/'+currentDate.getDate()+'/'+currentDate.getFullYear();
+ return dateString;
+}
+
+function returnHour()
+{
+ var currentDate;
+ currentDate=new Date();
+ var hourString=currentDate.getHours()+':'+currentDate.getMinutes()+':'+currentDate.getSeconds();
+ return hourString;
+}
+
+function javaScriptMessage(){
+ return 'This section is generated under JavaScript:<br>';
+}
+
+function mainJavascript(){
+ document.write(javaScriptMessage())
+ document.write('<ul class="listElements">');
+ document.write('<li>Current date (dd/mm/yyyy): ' + returnDate());
+ document.write('<br>');
+ document.write('<li>Current time (hh:mm:ss): '+returnHour());
+ document.write('</ul>');
+}
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/007.html b/debian/perl-framework/t/htdocs/modules/h2/007.html new file mode 100755 index 0000000..4db93e4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/007.html @@ -0,0 +1,21 @@ +<!DOCTYPE html>
+<html>
+<head>
+<meta charset="ISO-8859-1">
+<title>HTML/2.0 Test File: 007</title>
+</head>
+<body>
+ <h1>HTML/2.0 Test File: 007</h1>
+ <div><p>This page is used to send data from the client to the server:</p>
+ <FORM ACTION="007/007.py" METHOD="post" ENCTYPE="multipart/form-data">
+ <input type="hidden" name="pageName" value="007.html">
+ Name:<input type="text" name="pName" value="Write your name here." size="30" maxlength="30"><br>
+ Age:<input type="text" name="pAge" value="00" size="2" maxlength="2"><br>
+ Gender: Male<input type="radio" name="pGender" VALUE="Male">
+ Female<input type="radio" name="pGender" VALUE="Female"><br>
+ <input type="submit" name="userForm" value="Send">
+ <input type="reset" value="Clear">
+ </FORM>
+ </div>
+</body>
+</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/007/007.py b/debian/perl-framework/t/htdocs/modules/h2/007/007.py new file mode 100755 index 0000000..02b5466 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/007/007.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import cgi, sys +import cgitb; cgitb.enable() + +print "Content-Type: text/html;charset=UTF-8" +print + +print """\ + <!DOCTYPE html><html><head> + <title>HTML/2.0 Test File: 007 (received data)</title></head> + <body><h1>HTML/2.0 Test File: 007</h1>""" + +# alternative output: parsed form params <-> plain POST body +parseContent = True # <-> False + +if parseContent: + print '<h2>Data processed:</h2><ul>' + form = cgi.FieldStorage() + for name in form: + print '<li>', name, ': ', form[name].value, '</li>' + print '</ul>' +else: + print '<h2>POST data output:</h2><div><pre>' + data = sys.stdin.read() + print data + print '</pre></div>' + +print '</body></html>'
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/009.py b/debian/perl-framework/t/htdocs/modules/h2/009.py new file mode 100755 index 0000000..8fd9095 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/009.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import cgi, sys, time +import cgitb; cgitb.enable() + +print "Content-Type: text/html;charset=UTF-8" +print + +print """\ + <!DOCTYPE html><html><head> + <title>HTML/2.0 Test File: 009 (server time)</title></head> + <body><h1>HTML/2.0 Test File: 009</h1> + <p>60 seconds of server time, one by one.</p>""" + +for i in range(60): + s = time.strftime("%Y-%m-%d %H:%M:%S") + print "<div>", s, "</div>" + sys.stdout.flush() + time.sleep(1) + +print "<p>done.</p></body></html>"
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/files/empty.txt b/debian/perl-framework/t/htdocs/modules/h2/files/empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/files/empty.txt diff --git a/debian/perl-framework/t/htdocs/modules/h2/hello.pl b/debian/perl-framework/t/htdocs/modules/h2/hello.pl new file mode 100755 index 0000000..688b102 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/hello.pl @@ -0,0 +1,13 @@ +#!/usr/bin/env perl + +use Env; + +print "Content-Type: text/html\n"; +print "\n"; + +#my $ssl_protocol = $ENV{'SSL_TLS_SNI'}; +print <<EOF +<html><body> +<h2>Hello World!</h2> +</body></html> +EOF diff --git a/debian/perl-framework/t/htdocs/modules/h2/index.html b/debian/perl-framework/t/htdocs/modules/h2/index.html new file mode 100644 index 0000000..aa11d4f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/index.html @@ -0,0 +1,45 @@ +<html> + <head> + <title>mod_h2 test site</title> + </head> + <body> + <h1>mod_h2 test site</h1> + <p></p> + <h2>served directly</h2> + <ul> + <li><a href="001.html">01: html</a></li> + <li><a href="002.jpg">02: image</a></li> + <li><a href="003.html">03: html+image</a></li> + <li><a href="004.html">04: tiled image</a></li> + <li><a href="005.txt">05: large text</a></li> + <li><a href="006.html">06: html/js/css</a></li> + <li><a href="007.html">07: form submit</a></li> + <li><a href="upload.py">08: upload</a></li> + <li><a href="009.py">09: small chunks</a></li> + </ul> + <h2>mod_proxyied</h2> + <ul> + <li><a href="proxy/001.html">01: html</a></li> + <li><a href="proxy/002.jpg">02: image</a></li> + <li><a href="proxy/003.html">03: html+image</a></li> + <li><a href="proxy/004.html">04: tiled image</a></li> + <li><a href="proxy/005.txt">05: large text</a></li> + <li><a href="proxy/006.html">06: html/js/css</a></li> + <li><a href="proxy/007.html">07: form submit</a></li> + <li><a href="proxy/upload.py">08: upload</a></li> + <li><a href="proxy/009.py">09: small chunks</a></li> + </ul> + <h2>mod_rewritten</h2> + <ul> + <li><a href="rewrite/001.html">01: html</a></li> + <li><a href="rewrite/002.jpg">02: image</a></li> + <li><a href="rewrite/003.html">03: html+image</a></li> + <li><a href="rewrite/004.html">04: tiled image</a></li> + <li><a href="rewrite/005.txt">05: large text</a></li> + <li><a href="rewrite/006.html">06: html/js/css</a></li> + <li><a href="rewrite/007.html">07: form submit</a></li> + <li><a href="rewrite/upload.py">08: upload</a></li> + <li><a href="rewrite/009.py">09: small chunks</a></li> + </ul> + </body> +</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/index.jpg b/debian/perl-framework/t/htdocs/modules/h2/index.jpg Binary files differnew file mode 100755 index 0000000..246624e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/index.jpg diff --git a/debian/perl-framework/t/htdocs/modules/h2/info.php b/debian/perl-framework/t/htdocs/modules/h2/info.php new file mode 100644 index 0000000..640e4f2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/info.php @@ -0,0 +1,3 @@ +<?php + phpinfo(); +?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/necho.pl b/debian/perl-framework/t/htdocs/modules/h2/necho.pl new file mode 100755 index 0000000..bc9b6c0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/necho.pl @@ -0,0 +1,29 @@ +#!/usr/bin/env perl + +use Env; + +my $query = $ENV{QUERY_STRING}; + +if ($query) { + $query =~ /count=([0-9]+)/; + my $count = $1; + $query =~ /text=([^&]+)/; + my $text = $1; + + print "Status: 200\n"; + print "Content-Type: text/plain\n"; + print "\n"; + foreach my $i (1..$count) { + print $text; + } +} +else { + print "Status: 400 Parameter Missing\n"; + print "Content-Type: text/plain\n"; + print "\n"; + print <<EOF; +<html><body> +<p>No query was specified.</p> +</body></html> +EOF +} diff --git a/debian/perl-framework/t/htdocs/modules/h2/upload.pl b/debian/perl-framework/t/htdocs/modules/h2/upload.pl new file mode 100755 index 0000000..71880f1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/upload.pl @@ -0,0 +1,47 @@ +#!/usr/bin/env python +import cgi, os +import cgitb; cgitb.enable() + +status = '200 Ok' + +try: # Windows needs stdio set for binary mode. + import msvcrt + msvcrt.setmode (0, os.O_BINARY) # stdin = 0 + msvcrt.setmode (1, os.O_BINARY) # stdout = 1 +except ImportError: + pass + +form = cgi.FieldStorage() + +# Test if the file was uploaded +if 'file' in form: + # A nested FieldStorage instance holds the file + fileitem = form['file'] + + # strip leading path from file name to avoid directory traversal attacks + fn = os.path.basename(fileitem.filename) + open('./files/' + fn, 'wb').write(fileitem.file.read()) + message = 'The file "' + fn + '" was uploaded successfully' + +elif 'remove' in form: + remove = form['remove'].value + try: + fn = os.path.basename(remove) + os.remove('./files/' + fn) + message = 'The file "' + fn + '" was removed successfully' + except OSError, e: + message = 'Error removing ' + fn + ': ' + e.strerror + status = '404 File Not Found' +else: + message = '''\ + Upload File<form method="POST" enctype="multipart/form-data"> + <input type="file" name="file"> + <button type="submit">Upload</button></form> + ''' + +print "Status: %s" % (status,) +print """\ + Content-Type: text/html\n + <html><body> + <p>%s</p> + </body></html>""" % (message,) diff --git a/debian/perl-framework/t/htdocs/modules/h2/upload.py b/debian/perl-framework/t/htdocs/modules/h2/upload.py new file mode 100755 index 0000000..71880f1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/upload.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +import cgi, os +import cgitb; cgitb.enable() + +status = '200 Ok' + +try: # Windows needs stdio set for binary mode. + import msvcrt + msvcrt.setmode (0, os.O_BINARY) # stdin = 0 + msvcrt.setmode (1, os.O_BINARY) # stdout = 1 +except ImportError: + pass + +form = cgi.FieldStorage() + +# Test if the file was uploaded +if 'file' in form: + # A nested FieldStorage instance holds the file + fileitem = form['file'] + + # strip leading path from file name to avoid directory traversal attacks + fn = os.path.basename(fileitem.filename) + open('./files/' + fn, 'wb').write(fileitem.file.read()) + message = 'The file "' + fn + '" was uploaded successfully' + +elif 'remove' in form: + remove = form['remove'].value + try: + fn = os.path.basename(remove) + os.remove('./files/' + fn) + message = 'The file "' + fn + '" was removed successfully' + except OSError, e: + message = 'Error removing ' + fn + ': ' + e.strerror + status = '404 File Not Found' +else: + message = '''\ + Upload File<form method="POST" enctype="multipart/form-data"> + <input type="file" name="file"> + <button type="submit">Upload</button></form> + ''' + +print "Status: %s" % (status,) +print """\ + Content-Type: text/html\n + <html><body> + <p>%s</p> + </body></html>""" % (message,) diff --git a/debian/perl-framework/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz b/debian/perl-framework/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz Binary files differnew file mode 100644 index 0000000..f025d43 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz diff --git a/debian/perl-framework/t/htdocs/modules/headers/htaccess/index.html b/debian/perl-framework/t/htdocs/modules/headers/htaccess/index.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/headers/htaccess/index.html diff --git a/debian/perl-framework/t/htdocs/modules/headers/ssl/.htaccess b/debian/perl-framework/t/htdocs/modules/headers/ssl/.htaccess new file mode 100644 index 0000000..babe7a1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/headers/ssl/.htaccess @@ -0,0 +1,3 @@ +Header set X-SSL-Flag %{HTTPS}s +Header set X-SSL-Cert %{SSL_SERVER_CERT}s +Header set X-SSL-None %{SSL_FOO_BAR}s diff --git a/debian/perl-framework/t/htdocs/modules/headers/ssl/index.html b/debian/perl-framework/t/htdocs/modules/headers/ssl/index.html new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/headers/ssl/index.html @@ -0,0 +1 @@ +hello world diff --git a/debian/perl-framework/t/htdocs/modules/include/abs-path.shtml b/debian/perl-framework/t/htdocs/modules/include/abs-path.shtml new file mode 100644 index 0000000..1a17e4e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/abs-path.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="/modules/include/extra/inc-extra1.shtml"--> +abs-path.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/apexpr/err.shtml b/debian/perl-framework/t/htdocs/modules/include/apexpr/err.shtml new file mode 100644 index 0000000..2afda99 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/apexpr/err.shtml @@ -0,0 +1,3 @@ +<!--#if expr="1 = 2 = 3" --> +<!--#include virtual="../echo.shtml" --> +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/apexpr/if1.shtml b/debian/perl-framework/t/htdocs/modules/include/apexpr/if1.shtml new file mode 100644 index 0000000..ec9c855 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/apexpr/if1.shtml @@ -0,0 +1,6 @@ +<!--#if expr="'ab' -strmatch 'a*'"--> +pass +<!--#endif --> +<!--#if expr="'ab' -strmatch 'b*'"--> +fail +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/apexpr/lazyvar.shtml b/debian/perl-framework/t/htdocs/modules/include/apexpr/lazyvar.shtml new file mode 100644 index 0000000..743ebf7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/apexpr/lazyvar.shtml @@ -0,0 +1,5 @@ +<!--#if expr="v('DATE_LOCAL') =~ /[0-9]/" --> +pass +<!--#else--> +fail +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/apexpr/restrict.shtml b/debian/perl-framework/t/htdocs/modules/include/apexpr/restrict.shtml new file mode 100644 index 0000000..5c095f8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/apexpr/restrict.shtml @@ -0,0 +1,3 @@ +<!--#if expr="-e '/etc/passwd'" --> +<!--#include virtual="../echo.shtml" --> +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/apexpr/var.shtml b/debian/perl-framework/t/htdocs/modules/include/apexpr/var.shtml new file mode 100644 index 0000000..9521c90 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/apexpr/var.shtml @@ -0,0 +1,16 @@ +<!--#set var="x" value="foo bar"--> +<!--#if expr="reqenv('x') =~ /^foo/ && reqenv('x') =~ /bar$/" --> +pass +<!--#else--> +fail +<!--#endif--> +<!--#if expr="env('x') =~ /^foo/ && v('x') =~ /bar$/" --> +pass +<!--#else--> +fail +<!--#endif--> +<!--#if expr="note('x') =~ /^foo/" --> +fail +<!--#else--> +pass +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/big.shtml b/debian/perl-framework/t/htdocs/modules/include/big.shtml new file mode 100644 index 0000000..b7134dc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/big.shtml @@ -0,0 +1,18 @@ +<!--#set var="one" value="hello"--> +<!--#if expr="\"$one\" = \"hello\""--> +<!--#set var="two" value="pass"--> +<!--#echo var="one"--> +<!--#else --> +<!--#include file="inc-three.shtml"--> +<!--#set var="two" value="fail"--> +fail1 +<!--#endif --> +<!--#if expr="\"$two\" = \"$one\""--> +fail2 +<!--#elif expr="\"$two\" = \"fail\""--> +fail3 +<!--#else --> +<!--#echo var="two"--> +<!--#include file="if4.shtml"--> +<!--#endif --> +<!--#echo var="one"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/retagged3.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/retagged3.shtml new file mode 100644 index 0000000..de819f9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/retagged3.shtml @@ -0,0 +1 @@ +------->echo var="DOCUMENT_NAME" ---> diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/retagged4.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/retagged4.shtml new file mode 100644 index 0000000..1e7273a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/retagged4.shtml @@ -0,0 +1 @@ +------>if expr=""printenw--->printenvprintenw---->endifprintenwpass diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y.shtml new file mode 100644 index 0000000..3e291d4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y.shtml @@ -0,0 +1,16 @@ +____ +_____ +_____ +___________________ +</table> + +##################################1/8</tr> +##################################2/8</tr> +##################################3/8</tr> +##################################4/8</tr> +##################################5/8</tr> +##################################6/8<!--#echo var="DOCUMENT_ROOT" --></tr> +##################################7/8</tr> +##################################8/8</tr> +@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y0.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y0.shtml new file mode 100644 index 0000000..22770ff --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y0.shtml @@ -0,0 +1,16 @@ +____ +______________________________________________________________________________ +______________________________________________________________________________________ +___________________ +</table> + +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y1.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y1.shtml new file mode 100644 index 0000000..d938ca6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y1.shtml @@ -0,0 +1,16 @@ +____ +______________________________________________________________________________ +______________________________________________________________________________________ +___________________ +</table> + +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y10.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y10.shtml new file mode 100644 index 0000000..3936815 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y10.shtml @@ -0,0 +1 @@ +<!--#set var="pass" value="\"pass\"" --><!--#echo encoding="none" var="pass"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y2.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y2.shtml new file mode 100644 index 0000000..fef6138 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y2.shtml @@ -0,0 +1,17 @@ +____ +______________________________________________________________________________ +______________________________________________________________________________________ +___________________ +</table> + +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +#####################################</tr> +@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@ + diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y3.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y3.shtml new file mode 100644 index 0000000..cb678a2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y3.shtml @@ -0,0 +1 @@ +<!--#include virtual="y0.shtml" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y4.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y4.shtml new file mode 100644 index 0000000..dfb8397 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y4.shtml @@ -0,0 +1 @@ +<!--#include virtual="missing.html" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y5.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y5.shtml new file mode 100644 index 0000000..496a9b9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y5.shtml @@ -0,0 +1,9 @@ +<!--#if expr="" --> +fail +<!--#include virtual="y4.shtml" --> +fail +<!--#else --> +pass +<!--#include virtual="y4.shtml" --> +pass +<!--#endif -->pass1 diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y6.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y6.shtml new file mode 100644 index 0000000..590a85f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y6.shtml @@ -0,0 +1 @@ +BeforeIf<!--#if expr="$X" -->preIfBlockpostIfBlock<!--#else -->ElseBlock<!--#endif -->AfterIf diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y7.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y7.shtml new file mode 100644 index 0000000..1b13c01 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y7.shtml @@ -0,0 +1 @@ +Before If <!-- comment --><!--#if expr="$FALSE" -->AnythingNothing<!--#else -->SomethingElse<!--#endif --><!-- right after if -->After if diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y8.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y8.shtml new file mode 100644 index 0000000..f3104af --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y8.shtml @@ -0,0 +1 @@ +<!--#if expr="$FALSE" -->T<!--#set var="v" value="t" -->Set<!--#else -->False<!--#set var="v" value="t" -->Set<!--#endif -->Done diff --git a/debian/perl-framework/t/htdocs/modules/include/bucketeer/y9.shtml b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y9.shtml new file mode 100644 index 0000000..8d9ef51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/bucketeer/y9.shtml @@ -0,0 +1 @@ +<!--#if expr="$FALSE" -->T<!-- comment -->Set<!--#else -->False<!--#set var="v" value="t" -->Set<!--#endif -->Done diff --git a/debian/perl-framework/t/htdocs/modules/include/comment.shtml b/debian/perl-framework/t/htdocs/modules/include/comment.shtml new file mode 100755 index 0000000..b278735 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/comment.shtml @@ -0,0 +1,5 @@ +No +<!--#comment blah blah blah ... --> +comment +<!--#comment blah blah blah ... --> +here diff --git a/debian/perl-framework/t/htdocs/modules/include/echo.shtml b/debian/perl-framework/t/htdocs/modules/include/echo.shtml new file mode 100644 index 0000000..b211acf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/echo.shtml @@ -0,0 +1 @@ +<!--#echo var="DOCUMENT_NAME" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/echo1.shtml b/debian/perl-framework/t/htdocs/modules/include/echo1.shtml new file mode 100644 index 0000000..cbf8939 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/echo1.shtml @@ -0,0 +1 @@ +<!--#echo var="undefined variable" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/echo2.shtml b/debian/perl-framework/t/htdocs/modules/include/echo2.shtml new file mode 100644 index 0000000..1290cae --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/echo2.shtml @@ -0,0 +1,9 @@ +<!--#echo var="undefined variable" --> +<!--#config echomsg="pass" --> +<!--#echo var="undefined variable" --> +<!--#config echomsg="config" --> +<!--#echo var="undefined variable" --> +<!--#config echomsg="echomsg" --> +<!--#echo var="undefined variable" --> +<!--#config echomsg="pass" --> +<!--#echo var="undefined variable" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/echo3.shtml b/debian/perl-framework/t/htdocs/modules/include/echo3.shtml new file mode 100644 index 0000000..b211acf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/echo3.shtml @@ -0,0 +1 @@ +<!--#echo var="DOCUMENT_NAME" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/encode.shtml b/debian/perl-framework/t/htdocs/modules/include/encode.shtml new file mode 100644 index 0000000..e01b858 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/encode.shtml @@ -0,0 +1,3 @@ +<!--#set var="encode" value="# %^"--> +<!--#echo encoding="none" var="encode"--> +<!--#echo encoding="url" var="encode"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/errmsg1.shtml b/debian/perl-framework/t/htdocs/modules/include/errmsg1.shtml new file mode 100644 index 0000000..2f52ac3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/errmsg1.shtml @@ -0,0 +1,2 @@ +<!--#config errmsg="errmsg"--> +<!--#include file="/doomed"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/errmsg2.shtml b/debian/perl-framework/t/htdocs/modules/include/errmsg2.shtml new file mode 100644 index 0000000..7250020 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/errmsg2.shtml @@ -0,0 +1,2 @@ +<!--#config errmsg="errmsg"--> +<!--#foo file="/doomed"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/errmsg3.shtml b/debian/perl-framework/t/htdocs/modules/include/errmsg3.shtml new file mode 100644 index 0000000..c1347dd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/errmsg3.shtml @@ -0,0 +1,2 @@ +<!--#config errmsg="errmsg"--> +<!--#echo file="inc-one.shtml"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/errmsg4.shtml b/debian/perl-framework/t/htdocs/modules/include/errmsg4.shtml new file mode 100644 index 0000000..092511f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/errmsg4.shtml @@ -0,0 +1,5 @@ +<!--#config errmsg="errmsg" --> +pass +<!--#if + +fail diff --git a/debian/perl-framework/t/htdocs/modules/include/errmsg5.shtml b/debian/perl-framework/t/htdocs/modules/include/errmsg5.shtml new file mode 100644 index 0000000..0f4af11 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/errmsg5.shtml @@ -0,0 +1,2 @@ +<!--#config errmsg="<!-- pass -->" --> +<!--#foo--> diff --git a/debian/perl-framework/t/htdocs/modules/include/exec/off/cgi.shtml b/debian/perl-framework/t/htdocs/modules/include/exec/off/cgi.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/exec/off/cgi.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/exec/off/cmd.shtml b/debian/perl-framework/t/htdocs/modules/include/exec/off/cmd.shtml new file mode 100644 index 0000000..9011ed2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/exec/off/cmd.shtml @@ -0,0 +1 @@ +<!--#exec cmd="echo pass"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/exec/on/cgi.shtml b/debian/perl-framework/t/htdocs/modules/include/exec/on/cgi.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/exec/on/cgi.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/exec/on/cmd.shtml b/debian/perl-framework/t/htdocs/modules/include/exec/on/cmd.shtml new file mode 100644 index 0000000..9011ed2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/exec/on/cmd.shtml @@ -0,0 +1 @@ +<!--#exec cmd="echo pass"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/extra/inc-bogus.shtml b/debian/perl-framework/t/htdocs/modules/include/extra/inc-bogus.shtml new file mode 100644 index 0000000..10a0525 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/extra/inc-bogus.shtml @@ -0,0 +1,2 @@ +<!--#include file="../inc-two.shtml"--> +inc-bogus.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/extra/inc-extra1.shtml b/debian/perl-framework/t/htdocs/modules/include/extra/inc-extra1.shtml new file mode 100644 index 0000000..a0b3f09 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/extra/inc-extra1.shtml @@ -0,0 +1,2 @@ +<!--#include file="inc-extra2.shtml"--> +inc-extra1.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/extra/inc-extra2.shtml b/debian/perl-framework/t/htdocs/modules/include/extra/inc-extra2.shtml new file mode 100644 index 0000000..0a8d4e1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/extra/inc-extra2.shtml @@ -0,0 +1 @@ +inc-extra2.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/file.shtml b/debian/perl-framework/t/htdocs/modules/include/file.shtml new file mode 100644 index 0000000..f32cf32 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/file.shtml @@ -0,0 +1,6 @@ +<!--#config timefmt="%A, %B %e, %G"--> +<!--#flastmod file="file.shtml"--> +<!--#flastmod virtual="/modules/include/file.shtml"--> +<!--#config timefmt="%s"--> +<!--#flastmod file="file.shtml"--> +<!--#flastmod virtual="/modules/include/file.shtml"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/foo.shtml b/debian/perl-framework/t/htdocs/modules/include/foo.shtml new file mode 100644 index 0000000..8c55e9b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/foo.shtml @@ -0,0 +1,2 @@ +<!--#foo virtual="/inc-two.shtml"--> +foo.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/foo1.shtml b/debian/perl-framework/t/htdocs/modules/include/foo1.shtml new file mode 100644 index 0000000..2d8f394 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/foo1.shtml @@ -0,0 +1,2 @@ +<!--#include file="/inc-two.shtml"--> +foo.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/foo2.shtml b/debian/perl-framework/t/htdocs/modules/include/foo2.shtml new file mode 100644 index 0000000..5fcaa7b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/foo2.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="/inc-two.shtml"--> +foo.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/footer.shtml b/debian/perl-framework/t/htdocs/modules/include/footer.shtml new file mode 100644 index 0000000..cc8ce24 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/footer.shtml @@ -0,0 +1,2 @@ +<hr> +<h5>footer</h5> diff --git a/debian/perl-framework/t/htdocs/modules/include/header.shtml b/debian/perl-framework/t/htdocs/modules/include/header.shtml new file mode 100644 index 0000000..f595ab0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/header.shtml @@ -0,0 +1,7 @@ +<html> +<head> +<title><!--#echo var="QUERY_STRING" --></title> +<meta http-equiv="Content-Type" content="text/html"> +</head> + +<h1><!--#echo var="QUERY_STRING" --></h1> diff --git a/debian/perl-framework/t/htdocs/modules/include/if1.shtml b/debian/perl-framework/t/htdocs/modules/include/if1.shtml new file mode 100644 index 0000000..182e97a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if1.shtml @@ -0,0 +1,6 @@ +<!--#if expr="\"1\" = \"1\""--> +pass +<!--#endif --> +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if10.shtml b/debian/perl-framework/t/htdocs/modules/include/if10.shtml new file mode 100644 index 0000000..4897e44 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if10.shtml @@ -0,0 +1,10 @@ +<!--#if expr="1=1" --> +pass +<!--#else--> +fail +<!--#if expr="2=2" --> +fail +<!--#else--> +fail +<!--#endif--> +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/if10a.shtml b/debian/perl-framework/t/htdocs/modules/include/if10a.shtml new file mode 100644 index 0000000..9150e2a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if10a.shtml @@ -0,0 +1,10 @@ +<!--#if expr="1=1" --> +pass +<!--#else --> +fail +<!--#if expr="2=2" --> +fail +<!--#else --> +fail +<!--#endif --> +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if11.shtml b/debian/perl-framework/t/htdocs/modules/include/if11.shtml new file mode 100644 index 0000000..75fc900 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if11.shtml @@ -0,0 +1 @@ +<!--#if expr="\(" -->pass<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if2.shtml b/debian/perl-framework/t/htdocs/modules/include/if2.shtml new file mode 100644 index 0000000..27fbff7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if2.shtml @@ -0,0 +1,10 @@ +<!--#if expr="\"1\" = \"1\""--> +pass +<!--#else --> +fail +<!--#endif --> +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#else --> +pass +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if3.shtml b/debian/perl-framework/t/htdocs/modules/include/if3.shtml new file mode 100644 index 0000000..5b71007 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if3.shtml @@ -0,0 +1,21 @@ +<!--#if expr="\"1\" = \"1\""--> +pass +<!--#elif expr="\"1\" = \"2\""--> +fail +<!--#else --> +fail +<!--#endif --> +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#elif expr="\"3\" = \"3\""--> +pass +<!--#else --> +fail +<!--#endif --> +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#elif expr="\"1\" = \"3\""--> +fail +<!--#else --> +pass +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if4.shtml b/debian/perl-framework/t/htdocs/modules/include/if4.shtml new file mode 100644 index 0000000..edac717 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if4.shtml @@ -0,0 +1,15 @@ +<!--#if expr="\"1\" = \"1\""--> +pass +<!--#elif expr="\"1\" = \"2\""--> +fail +<!--#endif --> +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#elif expr="\"3\" = \"3\""--> +pass +<!--#endif --> +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#elif expr="\"1\" = \"3\""--> +fail +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if5.shtml b/debian/perl-framework/t/htdocs/modules/include/if5.shtml new file mode 100644 index 0000000..8e85fef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if5.shtml @@ -0,0 +1,21 @@ +<!--#if expr="\"1\" = \"1\""--> +pass +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#elif expr="\"3\" = \"3\""--> +pass +<!--#if expr="\"1\" = \"2\""--> +fail +<!--#elif expr="\"1\" = \"3\""--> +fail +<!--#else --> +pass +<!--#endif --> +<!--#else --> +fail +<!--#endif --> +<!--#elif expr="\"1\" = \"2\""--> +fail +<!--#else --> +fail +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if6.shtml b/debian/perl-framework/t/htdocs/modules/include/if6.shtml new file mode 100644 index 0000000..6733b66 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if6.shtml @@ -0,0 +1,3 @@ + +<!--#if "$x = y"--> +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/if7.shtml b/debian/perl-framework/t/htdocs/modules/include/if7.shtml new file mode 100644 index 0000000..4ea4acd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if7.shtml @@ -0,0 +1,3 @@ + +<!--#if expr="$x = y" +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/if8.shtml b/debian/perl-framework/t/htdocs/modules/include/if8.shtml new file mode 100644 index 0000000..71f3dde --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if8.shtml @@ -0,0 +1,9 @@ +<!--#set var="x_p_ssl" value="1"--> +<!--#set var="x_SERVER_PORT" value="443"--> +<!--#if expr="($x_SERVER_PORT = 80) && ($x_p_ssl = 0)"--> +pass +<!--#elif expr="($x_SERVER_PORT = 443) && ($x_p_ssl = 1)"--> +pass +<!--#else--> +fail +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/if8a.shtml b/debian/perl-framework/t/htdocs/modules/include/if8a.shtml new file mode 100644 index 0000000..cb39489 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if8a.shtml @@ -0,0 +1,9 @@ +<!--#set var="x_p_ssl" value="1"--> +<!--#set var="x_SERVER_PORT" value="443"--> +<!--#if expr="($x_SERVER_PORT = 80) && ($x_p_ssl = 0)"--> +pass +<!--#elif expr="($x_SERVER_PORT = 443) && ($x_p_ssl = 1)"--> +pass +<!--#else --> +fail +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/if9.shtml b/debian/perl-framework/t/htdocs/modules/include/if9.shtml new file mode 100644 index 0000000..1982ba2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if9.shtml @@ -0,0 +1,11 @@ +<!--#set var="x" value="foo bar"--> +<!--#if expr="$x = /^foo/ && $x = /bar$/" --> +pass +<!--#else--> +fail +<!--#endif--> +<!--#if expr="($x = /^foo/) && ($x = /bar$/)" --> +pass +<!--#else--> +fail +<!--#endif--> diff --git a/debian/perl-framework/t/htdocs/modules/include/if9a.shtml b/debian/perl-framework/t/htdocs/modules/include/if9a.shtml new file mode 100644 index 0000000..30cebaa --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/if9a.shtml @@ -0,0 +1,11 @@ +<!--#set var="x" value="foo bar"--> +<!--#if expr="$x = /^foo/ && $x = /bar$/" --> +pass +<!--#else --> +fail +<!--#endif --> +<!--#if expr="($x = /^foo/) && ($x = /bar$/)" --> +pass +<!--#else --> +fail +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/inc-nego.shtml b/debian/perl-framework/t/htdocs/modules/include/inc-nego.shtml new file mode 100644 index 0000000..9142d02 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/inc-nego.shtml @@ -0,0 +1 @@ +<!--#include virtual="../negotiation/en/"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/inc-one.shtml b/debian/perl-framework/t/htdocs/modules/include/inc-one.shtml new file mode 100644 index 0000000..1ee97ad --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/inc-one.shtml @@ -0,0 +1,2 @@ +<!--#include file="inc-two.shtml"--> +inc-one.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/inc-rfile.shtml b/debian/perl-framework/t/htdocs/modules/include/inc-rfile.shtml new file mode 100644 index 0000000..7f002db --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/inc-rfile.shtml @@ -0,0 +1,2 @@ +<!--#include file="extra/inc-extra1.shtml"--> +inc-rfile.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/inc-rvirtual.shtml b/debian/perl-framework/t/htdocs/modules/include/inc-rvirtual.shtml new file mode 100644 index 0000000..ff75cea --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/inc-rvirtual.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="extra/inc-extra1.shtml"--> +inc-rvirtual.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/inc-three.shtml b/debian/perl-framework/t/htdocs/modules/include/inc-three.shtml new file mode 100644 index 0000000..35d1f73 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/inc-three.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="/modules/include/inc-one.shtml"--> +inc-three.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/inc-two.shtml b/debian/perl-framework/t/htdocs/modules/include/inc-two.shtml new file mode 100644 index 0000000..c5b197b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/inc-two.shtml @@ -0,0 +1 @@ +inc-two.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/include1.shtml b/debian/perl-framework/t/htdocs/modules/include/include1.shtml new file mode 100644 index 0000000..2a957f0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/include1.shtml @@ -0,0 +1,2 @@ +<!--#include file="inc-two.shtml"--> +include.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/include2.shtml b/debian/perl-framework/t/htdocs/modules/include/include2.shtml new file mode 100644 index 0000000..466b931 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/include2.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="/modules/include/inc-two.shtml"--> +include.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/include3.shtml b/debian/perl-framework/t/htdocs/modules/include/include3.shtml new file mode 100644 index 0000000..d2b5ee2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/include3.shtml @@ -0,0 +1,2 @@ +<!--#include file="inc-one.shtml"--> +include.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/include4.shtml b/debian/perl-framework/t/htdocs/modules/include/include4.shtml new file mode 100644 index 0000000..0ce120a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/include4.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="/modules/include/inc-one.shtml"--> +include.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/include5.shtml b/debian/perl-framework/t/htdocs/modules/include/include5.shtml new file mode 100644 index 0000000..442cb40 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/include5.shtml @@ -0,0 +1,2 @@ +<!--#include file="inc-three.shtml"--> +include.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/include6.shtml b/debian/perl-framework/t/htdocs/modules/include/include6.shtml new file mode 100644 index 0000000..3287e2b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/include6.shtml @@ -0,0 +1,2 @@ +<!--#include virtual="/modules/include/inc-three.shtml"--> +include.shtml body diff --git a/debian/perl-framework/t/htdocs/modules/include/malformed.shtml b/debian/perl-framework/t/htdocs/modules/include/malformed.shtml new file mode 100644 index 0000000..49ee8c0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/malformed.shtml @@ -0,0 +1,6 @@ +<!--#if expr="$lang != "de" --> +<!--#include virtual="echo.shtml" --> +<!--#endif --> +<!--#if expr="$lang = de" --> +<!--#include virtual="echo.shtml" --> +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/mod_request/echo.shtml b/debian/perl-framework/t/htdocs/modules/include/mod_request/echo.shtml new file mode 100755 index 0000000..b211acf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/mod_request/echo.shtml @@ -0,0 +1 @@ +<!--#echo var="DOCUMENT_NAME" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/mod_request/post.shtml b/debian/perl-framework/t/htdocs/modules/include/mod_request/post.shtml new file mode 100755 index 0000000..a6721e3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/mod_request/post.shtml @@ -0,0 +1 @@ +<!--#include virtual="/modules/cgi/perl_post.pl?$QUERY_STRING"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/newline.shtml b/debian/perl-framework/t/htdocs/modules/include/newline.shtml new file mode 100644 index 0000000..0cb539b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/newline.shtml @@ -0,0 +1 @@ +<!--#include virtual="inc-two.shtml"-->
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/include/notreal.shtml b/debian/perl-framework/t/htdocs/modules/include/notreal.shtml new file mode 100644 index 0000000..6bc39dc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/notreal.shtml @@ -0,0 +1 @@ +pass <!--
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/include/parse1.shtml b/debian/perl-framework/t/htdocs/modules/include/parse1.shtml new file mode 100644 index 0000000..5a23afb --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/parse1.shtml @@ -0,0 +1,2 @@ +<!--#set var="x" value="-->" --> +<!--#echo encoding="none" var="x" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/parse2.shtml b/debian/perl-framework/t/htdocs/modules/include/parse2.shtml new file mode 100644 index 0000000..7989338 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/parse2.shtml @@ -0,0 +1,2 @@ +<!--#set var="x" value='"' --> +<!--#echo encoding="none" var="x" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/printenv.shtml b/debian/perl-framework/t/htdocs/modules/include/printenv.shtml new file mode 100644 index 0000000..9be2cd8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/printenv.shtml @@ -0,0 +1 @@ +<!--#printenv --> diff --git a/debian/perl-framework/t/htdocs/modules/include/ranged-virtual.shtml b/debian/perl-framework/t/htdocs/modules/include/ranged-virtual.shtml new file mode 100644 index 0000000..1a67c9b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ranged-virtual.shtml @@ -0,0 +1 @@ +<!--#include virtual="/modules/cgi/big.pl" --><!--#include virtual="/modules/cgi/big.pl" -->
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/include/regex.shtml b/debian/perl-framework/t/htdocs/modules/include/regex.shtml new file mode 100644 index 0000000..7de0c1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/regex.shtml @@ -0,0 +1,5 @@ +<!--#set var="foo" value="1234567890" --> +<!--#echo var="1"--> +<!--#if expr="$foo = /(.)/"--><!--#endif--> +<!--#echo var="1"--> +<!--#echo var="2"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/retagged1.shtml b/debian/perl-framework/t/htdocs/modules/include/retagged1.shtml new file mode 100644 index 0000000..9f54fcf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/retagged1.shtml @@ -0,0 +1 @@ +--->echo var="DOCUMENT_NAME" ---> diff --git a/debian/perl-framework/t/htdocs/modules/include/retagged2.shtml b/debian/perl-framework/t/htdocs/modules/include/retagged2.shtml new file mode 100644 index 0000000..a692b85 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/retagged2.shtml @@ -0,0 +1 @@ +------->echo var="DOCUMENT_NAME" ---> diff --git a/debian/perl-framework/t/htdocs/modules/include/set.shtml b/debian/perl-framework/t/htdocs/modules/include/set.shtml new file mode 100644 index 0000000..50d1065 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/set.shtml @@ -0,0 +1,2 @@ +<!--#set var="message" value="set works"--> +<!--#echo var="message"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/size.shtml b/debian/perl-framework/t/htdocs/modules/include/size.shtml new file mode 100644 index 0000000..457cfd6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/size.shtml @@ -0,0 +1,17 @@ +<!--#config sizefmt="bytes"--> +<!--#fsize file="size.shtml"--> +<!--#fsize virtual="/modules/include/size.shtml"--> +<!--#config sizefmt="abbrev"--> +<!--#fsize file="size.shtml"--> +<!--#fsize virtual="/modules/include/size.shtml"--> +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/1/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/1/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/1/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/1/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/1/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/1/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/10/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/10/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/10/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/10/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/10/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/10/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/100/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/100/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/100/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/100/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/100/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/100/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/101/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/101/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/101/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/101/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/101/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/101/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/102/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/102/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/102/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/102/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/102/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/102/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/103/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/103/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/103/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/103/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/103/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/103/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/104/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/104/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/104/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/104/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/104/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/104/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/105/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/105/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/105/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/105/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/105/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/105/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/106/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/106/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/106/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/106/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/106/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/106/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/107/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/107/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/107/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/107/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/107/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/107/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/108/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/108/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/108/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/108/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/108/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/108/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/109/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/109/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/109/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/109/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/109/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/109/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/11/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/11/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/11/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/11/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/11/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/11/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/110/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/110/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/110/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/110/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/110/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/110/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/111/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/111/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/111/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/111/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/111/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/111/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/112/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/112/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/112/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/112/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/112/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/112/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/113/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/113/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/113/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/113/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/113/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/113/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/114/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/114/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/114/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/114/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/114/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/114/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/115/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/115/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/115/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/115/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/115/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/115/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/116/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/116/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/116/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/116/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/116/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/116/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/117/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/117/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/117/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/117/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/117/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/117/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/118/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/118/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/118/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/118/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/118/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/118/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/119/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/119/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/119/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/119/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/119/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/119/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/12/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/12/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/12/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/12/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/12/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/12/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/120/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/120/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/120/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/120/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/120/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/120/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/121/subdir/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/121/subdir/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/121/subdir/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/13/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/13/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/13/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/13/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/13/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/13/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/14/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/14/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/14/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/14/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/14/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/14/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/15/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/15/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/15/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/15/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/15/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/15/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/16/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/16/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/16/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/16/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/16/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/16/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/17/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/17/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/17/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/17/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/17/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/17/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/18/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/18/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/18/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/18/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/18/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/18/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/19/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/19/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/19/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/19/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/19/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/19/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/2/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/2/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/2/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/2/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/2/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/2/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/20/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/20/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/20/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/20/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/20/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/20/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/21/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/21/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/21/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/21/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/21/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/21/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/22/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/22/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/22/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/22/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/22/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/22/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/23/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/23/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/23/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/23/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/23/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/23/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/24/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/24/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/24/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/24/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/24/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/24/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/25/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/25/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/25/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/25/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/25/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/25/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/26/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/26/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/26/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/26/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/26/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/26/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/27/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/27/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/27/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/27/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/27/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/27/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/28/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/28/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/28/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/28/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/28/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/28/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/29/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/29/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/29/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/29/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/29/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/29/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/3/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/3/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/3/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/3/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/3/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/3/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/30/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/30/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/30/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/30/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/30/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/30/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/31/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/31/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/31/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/31/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/31/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/31/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/32/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/32/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/32/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/32/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/32/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/32/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/33/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/33/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/33/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/33/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/33/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/33/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/34/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/34/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/34/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/34/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/34/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/34/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/35/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/35/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/35/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/35/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/35/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/35/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/36/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/36/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/36/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/36/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/36/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/36/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/37/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/37/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/37/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/37/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/37/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/37/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/38/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/38/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/38/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/38/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/38/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/38/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/39/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/39/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/39/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/39/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/39/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/39/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/4/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/4/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/4/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/4/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/4/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/4/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/40/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/40/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/40/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/40/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/40/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/40/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/41/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/41/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/41/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/41/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/41/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/41/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/42/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/42/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/42/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/42/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/42/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/42/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/43/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/43/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/43/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/43/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/43/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/43/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/44/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/44/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/44/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/44/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/44/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/44/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/45/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/45/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/45/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/45/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/45/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/45/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/46/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/46/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/46/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/46/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/46/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/46/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/47/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/47/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/47/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/47/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/47/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/47/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/48/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/48/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/48/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/48/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/48/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/48/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/49/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/49/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/49/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/49/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/49/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/49/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/5/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/5/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/5/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/5/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/5/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/5/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/50/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/50/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/50/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/50/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/50/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/50/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/51/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/51/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/51/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/51/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/51/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/51/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/52/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/52/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/52/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/52/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/52/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/52/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/53/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/53/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/53/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/53/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/53/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/53/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/54/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/54/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/54/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/54/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/54/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/54/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/55/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/55/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/55/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/55/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/55/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/55/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/56/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/56/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/56/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/56/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/56/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/56/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/57/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/57/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/57/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/57/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/57/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/57/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/58/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/58/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/58/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/58/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/58/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/58/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/59/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/59/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/59/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/59/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/59/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/59/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/6/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/6/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/6/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/6/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/6/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/6/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/60/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/60/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/60/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/60/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/60/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/60/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/61/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/61/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/61/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/61/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/61/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/61/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/62/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/62/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/62/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/62/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/62/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/62/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/63/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/63/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/63/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/63/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/63/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/63/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/64/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/64/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/64/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/64/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/64/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/64/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/65/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/65/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/65/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/65/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/65/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/65/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/66/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/66/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/66/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/66/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/66/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/66/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/67/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/67/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/67/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/67/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/67/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/67/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/68/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/68/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/68/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/68/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/68/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/68/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/69/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/69/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/69/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/69/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/69/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/69/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/7/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/7/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/7/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/7/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/7/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/7/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/70/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/70/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/70/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/70/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/70/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/70/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/71/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/71/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/71/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/71/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/71/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/71/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/72/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/72/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/72/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/72/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/72/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/72/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/73/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/73/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/73/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/73/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/73/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/73/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/74/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/74/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/74/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/74/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/74/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/74/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/75/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/75/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/75/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/75/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/75/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/75/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/76/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/76/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/76/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/76/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/76/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/76/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/77/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/77/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/77/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/77/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/77/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/77/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/78/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/78/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/78/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/78/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/78/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/78/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/79/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/79/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/79/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/79/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/79/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/79/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/8/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/8/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/8/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/8/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/8/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/8/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/80/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/80/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/80/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/80/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/80/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/80/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/81/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/81/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/81/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/81/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/81/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/81/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/82/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/82/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/82/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/82/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/82/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/82/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/83/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/83/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/83/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/83/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/83/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/83/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/84/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/84/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/84/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/84/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/84/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/84/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/85/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/85/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/85/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/85/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/85/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/85/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/86/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/86/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/86/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/86/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/86/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/86/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/87/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/87/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/87/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/87/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/87/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/87/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/88/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/88/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/88/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/88/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/88/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/88/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/89/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/89/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/89/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/89/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/89/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/89/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/9/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/9/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/9/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/9/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/9/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/9/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/90/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/90/.htaccess new file mode 100644 index 0000000..b84d035 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/90/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/90/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/90/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/90/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/91/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/91/.htaccess new file mode 100644 index 0000000..47c4d75 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/91/.htaccess @@ -0,0 +1 @@ +Options +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/91/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/91/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/91/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/92/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/92/.htaccess new file mode 100644 index 0000000..363ba0e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/92/.htaccess @@ -0,0 +1 @@ +Options +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/92/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/92/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/92/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/93/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/93/.htaccess new file mode 100644 index 0000000..f079f8f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/93/.htaccess @@ -0,0 +1 @@ +Options Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/93/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/93/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/93/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/94/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/94/.htaccess new file mode 100644 index 0000000..30fa87f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/94/.htaccess @@ -0,0 +1 @@ +Options IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/94/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/94/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/94/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/95/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/95/.htaccess new file mode 100644 index 0000000..8b5ceba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/95/.htaccess @@ -0,0 +1 @@ +Options -Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/95/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/95/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/95/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/96/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/96/.htaccess new file mode 100644 index 0000000..039925a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/96/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/96/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/96/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/96/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/97/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/97/.htaccess new file mode 100644 index 0000000..a0d70d1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/97/.htaccess @@ -0,0 +1 @@ +Options -Includes +IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/97/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/97/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/97/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/98/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/98/.htaccess new file mode 100644 index 0000000..5e70ab6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/98/.htaccess @@ -0,0 +1 @@ +Options +Includes -IncludesNoExec diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/98/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/98/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/98/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/99/.htaccess b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/99/.htaccess new file mode 100644 index 0000000..cab2b65 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/99/.htaccess @@ -0,0 +1 @@ +Options -IncludesNoExec +Includes diff --git a/debian/perl-framework/t/htdocs/modules/include/ssi-exec/99/exec.shtml b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/99/exec.shtml new file mode 100644 index 0000000..74f7c51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/ssi-exec/99/exec.shtml @@ -0,0 +1 @@ +<!--#exec cgi="/modules/cgi/perl.pl"--> diff --git a/debian/perl-framework/t/htdocs/modules/include/var128.shtml b/debian/perl-framework/t/htdocs/modules/include/var128.shtml new file mode 100644 index 0000000..d188595 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/var128.shtml @@ -0,0 +1,4 @@ +<!--#set var="HTTP_COOKIE" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyz" --> +<!--#if expr="$HTTP_COOKIE = /(.+)/" --> +<!--#echo var="1" --> +<!--#endif --> diff --git a/debian/perl-framework/t/htdocs/modules/include/virtual.shtml b/debian/perl-framework/t/htdocs/modules/include/virtual.shtml new file mode 100644 index 0000000..0fce67d --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/virtual.shtml @@ -0,0 +1,7 @@ +<!--#include virtual="/modules/include/header.shtml?mod_include test" --> + +Hello World + +<p align=right>[<a href="../index.html">back</a>]</p> + +<!--#include virtual="/modules/include/footer.shtml" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/virtualq.shtml b/debian/perl-framework/t/htdocs/modules/include/virtualq.shtml new file mode 100644 index 0000000..b587b46 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/virtualq.shtml @@ -0,0 +1,4 @@ +<!--#echo var="QUERY_STRING" --> +<!--#include virtual="if1.shtml?$QUERY_STRING" --> +<!--#include virtual="inc-two.shtml" --> +<!--#echo var="QUERY_STRING" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/xbithack/both/timefmt.shtml b/debian/perl-framework/t/htdocs/modules/include/xbithack/both/timefmt.shtml new file mode 100755 index 0000000..e4ef522 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/xbithack/both/timefmt.shtml @@ -0,0 +1,2 @@ +<!--#config timefmt="%Y" --> +xx<!--#echo var="DATE_LOCAL" -->xx diff --git a/debian/perl-framework/t/htdocs/modules/include/xbithack/full/test.html b/debian/perl-framework/t/htdocs/modules/include/xbithack/full/test.html new file mode 100755 index 0000000..f8f4ff1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/xbithack/full/test.html @@ -0,0 +1,3 @@ +<BODY> +<!--#include virtual="../../inc-two.shtml"--> +</BODY> diff --git a/debian/perl-framework/t/htdocs/modules/include/xbithack/off/test.html b/debian/perl-framework/t/htdocs/modules/include/xbithack/off/test.html new file mode 100755 index 0000000..f8f4ff1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/xbithack/off/test.html @@ -0,0 +1,3 @@ +<BODY> +<!--#include virtual="../../inc-two.shtml"--> +</BODY> diff --git a/debian/perl-framework/t/htdocs/modules/include/xbithack/on/test.html b/debian/perl-framework/t/htdocs/modules/include/xbithack/on/test.html new file mode 100755 index 0000000..f8f4ff1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/xbithack/on/test.html @@ -0,0 +1,3 @@ +<BODY> +<!--#include virtual="../../inc-two.shtml"--> +</BODY> diff --git a/debian/perl-framework/t/htdocs/modules/lua/201.lua b/debian/perl-framework/t/htdocs/modules/lua/201.lua new file mode 100644 index 0000000..f354125 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/201.lua @@ -0,0 +1,3 @@ +function handle(r) + r.status = 201 +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/filters.lua b/debian/perl-framework/t/htdocs/modules/lua/filters.lua new file mode 100644 index 0000000..4236ecc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/filters.lua @@ -0,0 +1,16 @@ +--[[ + Example output filter that escapes all HTML entities in the output +]]-- +function output_filter(r) + coroutine.yield("prefix\n") + while bucket do -- For each bucket, do... + if string.len(bucket) > 0 then + local output = "bucket:" .. bucket .. "\n" + coroutine.yield(output) -- Send converted data down the chain + else + coroutine.yield("") -- Send converted data down the chain + end + end + coroutine.yield("suffix\n") + -- No more buckets available. +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/hello.lua b/debian/perl-framework/t/htdocs/modules/lua/hello.lua new file mode 100644 index 0000000..85cd99e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/hello.lua @@ -0,0 +1,4 @@ +function handle(r) + r.content_type = "text/plain" + r:puts("Hello Lua World!\n") +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/hello2.lua b/debian/perl-framework/t/htdocs/modules/lua/hello2.lua new file mode 100644 index 0000000..2a4b16f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/hello2.lua @@ -0,0 +1,4 @@ +function handle(r) + r.content_type = "text/plain" + r:puts("other lua handler\n") +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/https.lua b/debian/perl-framework/t/htdocs/modules/lua/https.lua new file mode 100644 index 0000000..9393093 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/https.lua @@ -0,0 +1,7 @@ +function handle(r) + if r.is_https then + r:puts("yep") + else + r:puts("nope") + end +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/method.lua b/debian/perl-framework/t/htdocs/modules/lua/method.lua new file mode 100644 index 0000000..e5ea3ee --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/method.lua @@ -0,0 +1,3 @@ +function handle(r) + r:puts(r.method) +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/setheaderfromparam.lua b/debian/perl-framework/t/htdocs/modules/lua/setheaderfromparam.lua new file mode 100644 index 0000000..6c8d9c5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/setheaderfromparam.lua @@ -0,0 +1,10 @@ +-- Syntax: setheader.lua?HeaderName=foo&HeaderValue=bar +-- +-- This will return a document with 'bar' set in the header 'foo' + +function handle(r) + local GET, GETMULTI = r:parseargs() + + r.headers_out[GET['HeaderName']] = GET['HeaderValue'] + r:puts("Header set") +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/setheaders.lua b/debian/perl-framework/t/htdocs/modules/lua/setheaders.lua new file mode 100644 index 0000000..faa7f68 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/setheaders.lua @@ -0,0 +1,4 @@ +function handle(r) + r.headers_out["X-Header"] = "yes" + r.headers_out["X-Host"] = r.headers_in["Host"] +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/translate.lua b/debian/perl-framework/t/htdocs/modules/lua/translate.lua new file mode 100644 index 0000000..7d19c9a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/translate.lua @@ -0,0 +1,28 @@ +require 'apache2' + +function translate_name(r) + r:debug("translate_name: " .. r.uri) + local query = r:parseargs() + if query.translateme then + r:debug("translate_name: translateme was true " .. r.uri) + r.uri = "/modules/lua/hello.lua" + return apache2.DECLINED + end + return apache2.DECLINED +end + +function translate_name2(r) + r:debug("translate_name2: " .. r.uri) + local query = r:parseargs() + if (query.ok) then + r:debug("will return OK") + end + if query.translateme then + r.uri = "/modules/lua/hello2.lua" + if query.ok then + r.filename= r.document_root .. r.uri + return apache2.OK + end + end + return apache2.DECLINED +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/version.lua b/debian/perl-framework/t/htdocs/modules/lua/version.lua new file mode 100644 index 0000000..7853844 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/version.lua @@ -0,0 +1,3 @@ +function handle(r) + r:puts(apache2.version) +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/websockets.lua b/debian/perl-framework/t/htdocs/modules/lua/websockets.lua new file mode 100644 index 0000000..1acd91b --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/websockets.lua @@ -0,0 +1,13 @@ +function handle(r) +if r:wsupgrade() then -- if we can upgrade: + while true do + local line, isFinal = r:wsread() + r:wswrite(line) + if line == "quit" then + r:wsclose() -- goodbye! + break + end + + end +end +end diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/content-type/test.var b/debian/perl-framework/t/htdocs/modules/negotiation/content-type/test.var new file mode 100644 index 0000000..a2d3525 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/content-type/test.var @@ -0,0 +1,26 @@ +URI: test + +# NOTE: When adding new cases, pad out bodies with spaces so that they're of +# equal length. mod_negotiation will prefer shorter bodies if all else is equal, +# which is confusing. We just want the first acceptable alternate to win for +# these tests. + +URI: test.txt +Content-Type: text/plain +Body:--- +text/plain--- + +URI: test.html +Content-Type: text/html +Body:--- +text/html --- + +URI: test.jpg +Content-Type: image/jpeg +Body:--- +image/jpeg--- + +URI: test.gif +Content-Type: image/gif +Body:--- +image/gif --- diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.de new file mode 100644 index 0000000..555bd83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.de @@ -0,0 +1 @@ +index.html.de.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.en new file mode 100644 index 0000000..b0d750c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.en @@ -0,0 +1 @@ +index.html.en.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.fr new file mode 100644 index 0000000..3a8b0bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.fr @@ -0,0 +1 @@ +index.html.fr.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.fu new file mode 100644 index 0000000..c0b85df --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.fu @@ -0,0 +1 @@ +index.html.fu.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.de new file mode 100644 index 0000000..1d9a5e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.de @@ -0,0 +1 @@ +index.html.de diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.en new file mode 100644 index 0000000..d288e3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.en @@ -0,0 +1 @@ +index.html.en diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.fr new file mode 100644 index 0000000..e739edd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.fr @@ -0,0 +1 @@ +index.html.fr diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.fu new file mode 100644 index 0000000..c0b6f1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.fu @@ -0,0 +1 @@ +index.html.fu diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.de.html b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.de.html new file mode 100644 index 0000000..075f6bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.de.html @@ -0,0 +1 @@ +index.de.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.en.html b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.en.html new file mode 100644 index 0000000..35c0623 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.en.html @@ -0,0 +1 @@ +index.en.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.fr.html b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.fr.html new file mode 100644 index 0000000..8c756a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.fr.html @@ -0,0 +1 @@ +index.fr.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.fu.html b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.fu.html new file mode 100644 index 0000000..72eb5ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.fu.html @@ -0,0 +1 @@ +index.fu.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var new file mode 100644 index 0000000..1069a10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var @@ -0,0 +1,21 @@ +URI: index.html + +URI: index.en.html +Content-Type: text/html +Content-Language: en + +URI: index.de.html +Content-Type: text/html +Content-Language: de + +URI: index.fr.html +Content-Type: text/html +Content-Language: fr + +URI: index.fu.html +Content-Type: text/html +Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.de new file mode 100644 index 0000000..555bd83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.de @@ -0,0 +1 @@ +index.html.de.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.en new file mode 100644 index 0000000..b0d750c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.en @@ -0,0 +1 @@ +index.html.en.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.fr new file mode 100644 index 0000000..3a8b0bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.fr @@ -0,0 +1 @@ +index.html.fr.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.fu new file mode 100644 index 0000000..c0b85df --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.fu @@ -0,0 +1 @@ +index.html.fu.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.de new file mode 100644 index 0000000..1d9a5e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.de @@ -0,0 +1 @@ +index.html.de diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.en new file mode 100644 index 0000000..d288e3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.en @@ -0,0 +1 @@ +index.html.en diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.fr new file mode 100644 index 0000000..e739edd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.fr @@ -0,0 +1 @@ +index.html.fr diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.fu new file mode 100644 index 0000000..c0b6f1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.fu @@ -0,0 +1 @@ +index.html.fu diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.de.html b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.de.html new file mode 100644 index 0000000..075f6bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.de.html @@ -0,0 +1 @@ +index.de.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.en.html b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.en.html new file mode 100644 index 0000000..35c0623 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.en.html @@ -0,0 +1 @@ +index.en.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.fr.html b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.fr.html new file mode 100644 index 0000000..8c756a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.fr.html @@ -0,0 +1 @@ +index.fr.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.fu.html b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.fu.html new file mode 100644 index 0000000..72eb5ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.fu.html @@ -0,0 +1 @@ +index.fu.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var new file mode 100644 index 0000000..1069a10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var @@ -0,0 +1,21 @@ +URI: index.html + +URI: index.en.html +Content-Type: text/html +Content-Language: en + +URI: index.de.html +Content-Type: text/html +Content-Language: de + +URI: index.fr.html +Content-Type: text/html +Content-Language: fr + +URI: index.fu.html +Content-Type: text/html +Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.de new file mode 100644 index 0000000..555bd83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.de @@ -0,0 +1 @@ +index.html.de.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.en new file mode 100644 index 0000000..b0d750c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.en @@ -0,0 +1 @@ +index.html.en.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.fr new file mode 100644 index 0000000..3a8b0bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.fr @@ -0,0 +1 @@ +index.html.fr.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.fu new file mode 100644 index 0000000..c0b85df --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.fu @@ -0,0 +1 @@ +index.html.fu.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.de new file mode 100644 index 0000000..1d9a5e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.de @@ -0,0 +1 @@ +index.html.de diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.en new file mode 100644 index 0000000..d288e3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.en @@ -0,0 +1 @@ +index.html.en diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.fr new file mode 100644 index 0000000..e739edd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.fr @@ -0,0 +1 @@ +index.html.fr diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.fu new file mode 100644 index 0000000..c0b6f1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.fu @@ -0,0 +1 @@ +index.html.fu diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.de.html b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.de.html new file mode 100644 index 0000000..075f6bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.de.html @@ -0,0 +1 @@ +index.de.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.en.html b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.en.html new file mode 100644 index 0000000..35c0623 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.en.html @@ -0,0 +1 @@ +index.en.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.fr.html b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.fr.html new file mode 100644 index 0000000..8c756a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.fr.html @@ -0,0 +1 @@ +index.fr.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.fu.html b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.fu.html new file mode 100644 index 0000000..72eb5ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.fu.html @@ -0,0 +1 @@ +index.fu.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var new file mode 100644 index 0000000..1069a10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var @@ -0,0 +1,21 @@ +URI: index.html + +URI: index.en.html +Content-Type: text/html +Content-Language: en + +URI: index.de.html +Content-Type: text/html +Content-Language: de + +URI: index.fr.html +Content-Type: text/html +Content-Language: fr + +URI: index.fu.html +Content-Type: text/html +Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.de new file mode 100644 index 0000000..555bd83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.de @@ -0,0 +1 @@ +index.html.de.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.en new file mode 100644 index 0000000..b0d750c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.en @@ -0,0 +1 @@ +index.html.en.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.fr new file mode 100644 index 0000000..3a8b0bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.fr @@ -0,0 +1 @@ +index.html.fr.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.fu new file mode 100644 index 0000000..c0b85df --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.fu @@ -0,0 +1 @@ +index.html.fu.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.de new file mode 100644 index 0000000..1d9a5e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.de @@ -0,0 +1 @@ +index.html.de diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.en new file mode 100644 index 0000000..d288e3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.en @@ -0,0 +1 @@ +index.html.en diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.fr new file mode 100644 index 0000000..e739edd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.fr @@ -0,0 +1 @@ +index.html.fr diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.fu new file mode 100644 index 0000000..c0b6f1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.fu @@ -0,0 +1 @@ +index.html.fu diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.de.html b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.de.html new file mode 100644 index 0000000..075f6bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.de.html @@ -0,0 +1 @@ +index.de.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.en.html b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.en.html new file mode 100644 index 0000000..35c0623 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.en.html @@ -0,0 +1 @@ +index.en.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.fr.html b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.fr.html new file mode 100644 index 0000000..8c756a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.fr.html @@ -0,0 +1 @@ +index.fr.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.fu.html b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.fu.html new file mode 100644 index 0000000..72eb5ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.fu.html @@ -0,0 +1 @@ +index.fu.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var new file mode 100644 index 0000000..1069a10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var @@ -0,0 +1,21 @@ +URI: index.html + +URI: index.en.html +Content-Type: text/html +Content-Language: en + +URI: index.de.html +Content-Type: text/html +Content-Language: de + +URI: index.fr.html +Content-Type: text/html +Content-Language: fr + +URI: index.fu.html +Content-Type: text/html +Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/query/test.html b/debian/perl-framework/t/htdocs/modules/negotiation/query/test.html new file mode 100644 index 0000000..80e8f7a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/query/test.html @@ -0,0 +1 @@ +test.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/query/test.pl.PL b/debian/perl-framework/t/htdocs/modules/negotiation/query/test.pl.PL new file mode 100755 index 0000000..b370163 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/query/test.pl.PL @@ -0,0 +1,8 @@ + +print "Content-type: text/html\n\n"; + +foreach my $key (keys %ENV) { + if ($key eq "QUERY_STRING") { + print "$key --> $ENV{$key}\n"; + } +} diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/query/test.var b/debian/perl-framework/t/htdocs/modules/negotiation/query/test.var new file mode 100644 index 0000000..6c8aca6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/query/test.var @@ -0,0 +1,7 @@ +URI: test + +URI: test.pl +Content-Type: text/html; qs=1.0 + +URI: test.html +Content-Type: text/html; qs=0.8 diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.de new file mode 100755 index 0000000..555bd83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.de @@ -0,0 +1 @@ +index.html.de.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.en new file mode 100755 index 0000000..b0d750c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.en @@ -0,0 +1 @@ +index.html.en.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fr new file mode 100755 index 0000000..3a8b0bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fr @@ -0,0 +1 @@ +index.html.fr.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fu new file mode 100755 index 0000000..c0b85df --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fu @@ -0,0 +1 @@ +index.html.fu.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.de new file mode 100755 index 0000000..1d9a5e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.de @@ -0,0 +1 @@ +index.html.de diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.en new file mode 100755 index 0000000..d288e3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.en @@ -0,0 +1 @@ +index.html.en diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fr new file mode 100755 index 0000000..e739edd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fr @@ -0,0 +1 @@ +index.html.fr diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fu new file mode 100755 index 0000000..c0b6f1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fu @@ -0,0 +1 @@ +index.html.fu diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.de.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.de.html new file mode 100755 index 0000000..075f6bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.de.html @@ -0,0 +1 @@ +index.de.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.en.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.en.html new file mode 100755 index 0000000..35c0623 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.en.html @@ -0,0 +1 @@ +index.en.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fr.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fr.html new file mode 100755 index 0000000..8c756a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fr.html @@ -0,0 +1 @@ +index.fr.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fu.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fu.html new file mode 100755 index 0000000..72eb5ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fu.html @@ -0,0 +1 @@ +index.fu.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/map.var new file mode 100755 index 0000000..1069a10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/map.var @@ -0,0 +1,21 @@ +URI: index.html + +URI: index.en.html +Content-Type: text/html +Content-Language: en + +URI: index.de.html +Content-Type: text/html +Content-Language: de + +URI: index.fr.html +Content-Type: text/html +Content-Language: fr + +URI: index.fu.html +Content-Type: text/html +Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/proxy/fcgi-action/index.php b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-action/index.php new file mode 100644 index 0000000..6316092 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-action/index.php @@ -0,0 +1,3 @@ +<?php + /* This does nothing; it's just a placeholder. */ +?> diff --git a/debian/perl-framework/t/htdocs/modules/proxy/fcgi-generic-rewrite/index.php b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-generic-rewrite/index.php new file mode 100644 index 0000000..6316092 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-generic-rewrite/index.php @@ -0,0 +1,3 @@ +<?php + /* This does nothing; it's just a placeholder. */ +?> diff --git a/debian/perl-framework/t/htdocs/modules/proxy/fcgi-generic/index.php b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-generic/index.php new file mode 100644 index 0000000..6316092 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-generic/index.php @@ -0,0 +1,3 @@ +<?php + /* This does nothing; it's just a placeholder. */ +?> diff --git a/debian/perl-framework/t/htdocs/modules/proxy/fcgi-rewrite-path-info/index.php b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-rewrite-path-info/index.php new file mode 100644 index 0000000..6316092 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/fcgi-rewrite-path-info/index.php @@ -0,0 +1,3 @@ +<?php + /* This does nothing; it's just a placeholder. */ +?> diff --git a/debian/perl-framework/t/htdocs/modules/proxy/fcgi/index.php b/debian/perl-framework/t/htdocs/modules/proxy/fcgi/index.php new file mode 100644 index 0000000..6316092 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/fcgi/index.php @@ -0,0 +1,3 @@ +<?php + /* This does nothing; it's just a placeholder. */ +?> diff --git a/debian/perl-framework/t/htdocs/modules/proxy/reverse/notproxy/local.html b/debian/perl-framework/t/htdocs/modules/proxy/reverse/notproxy/local.html new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/reverse/notproxy/local.html @@ -0,0 +1 @@ +hello world diff --git a/debian/perl-framework/t/htdocs/modules/proxy/rewrite/.htaccess b/debian/perl-framework/t/htdocs/modules/proxy/rewrite/.htaccess new file mode 100644 index 0000000..792eb94 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/proxy/rewrite/.htaccess @@ -0,0 +1,2 @@ +RewriteEngine on +RewriteRule ^(.*)$ /modules/rewrite/$1 [P,L] diff --git a/debian/perl-framework/t/htdocs/modules/remoteip/index.html b/debian/perl-framework/t/htdocs/modules/remoteip/index.html new file mode 100644 index 0000000..d788afe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/remoteip/index.html @@ -0,0 +1 @@ +PROXY-OK diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/barfoo.html b/debian/perl-framework/t/htdocs/modules/rewrite/barfoo.html new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/barfoo.html @@ -0,0 +1 @@ +pass diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/big.html b/debian/perl-framework/t/htdocs/modules/rewrite/big.html new file mode 100644 index 0000000..c7413fc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/big.html @@ -0,0 +1 @@ +BIG diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/db.pl.PL b/debian/perl-framework/t/htdocs/modules/rewrite/db.pl.PL new file mode 100644 index 0000000..a897a8a --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/db.pl.PL @@ -0,0 +1,10 @@ + +($txtmap, $dbmmap) = @ARGV; +open(TXT, "<$txtmap"); +dbmopen(%DB, $dbmmap, 0644); +while (<TXT>) { + next if (m|^s*#.*| or m|^s*$|); + $DB{$1} = $2 if (m|^\s*(\S+)\s+(\S+)$|); +} +dbmclose(%DB); +close(TXT) diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/five.html b/debian/perl-framework/t/htdocs/modules/rewrite/five.html new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/five.html @@ -0,0 +1 @@ +5 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/foo bar.html b/debian/perl-framework/t/htdocs/modules/rewrite/foo bar.html new file mode 100644 index 0000000..d675fa4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/foo bar.html @@ -0,0 +1 @@ +foo bar diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/four.html b/debian/perl-framework/t/htdocs/modules/rewrite/four.html new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/four.html @@ -0,0 +1 @@ +4 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/lucky13.html b/debian/perl-framework/t/htdocs/modules/rewrite/lucky13.html new file mode 100644 index 0000000..7743f93 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/lucky13.html @@ -0,0 +1 @@ +JACKPOT diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/numbers.dbm.db b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.dbm.db Binary files differnew file mode 100644 index 0000000..ed20201 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.dbm.db diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/numbers.pl.PL b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.pl.PL new file mode 100755 index 0000000..d3d3067 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.pl.PL @@ -0,0 +1,26 @@ + +# numbers.pl +# program rewrite map for mod_rewrite testing +# +$|=1; +my %map = ( 1 => 'one', + 2 => 'two', + 3 => 'three', + 4 => 'four', + 5 => 'five', + 6 => 'six' ); + +while (<STDIN>) { + chomp; + + print STDERR "GOT: ->$_<-\n"; + my $m = $map{$_}; + print STDERR "MAPPED: ->$_<-\n"; + + if ($m) { + print STDOUT "$m\n"; + } else { + print STDOUT "NULL"; + } +} +close (LOG); diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/numbers.rnd b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.rnd new file mode 100644 index 0000000..4027500 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.rnd @@ -0,0 +1,10 @@ +# +# numbers.rnd +# random number rewrite map for mod_rewrite testing +# +1 one|two|three|four|five|six +2 two|three|four|five|six +3 three|four|five|six +4 four|five|six +5 five|six +6 six diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/numbers.txt b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.txt new file mode 100644 index 0000000..6f36d28 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/numbers.txt @@ -0,0 +1,10 @@ +# +# numbers.txt +# text rewrite map for mod_rewrite testing +# +1 one +2 two +3 three +4 four +5 five +6 six diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/numbers2.pl.PL b/debian/perl-framework/t/htdocs/modules/rewrite/numbers2.pl.PL new file mode 100755 index 0000000..d450b68 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/numbers2.pl.PL @@ -0,0 +1,9 @@ + +# numbers.pl +# program rewrite map for mod_rewrite testing +# +funk cold medina. +$|=1; +while (<STDIN>) { + print $_; +} diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/one.html b/debian/perl-framework/t/htdocs/modules/rewrite/one.html new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/one.html @@ -0,0 +1 @@ +1 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/six.html b/debian/perl-framework/t/htdocs/modules/rewrite/six.html new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/six.html @@ -0,0 +1 @@ +6 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/test.blah b/debian/perl-framework/t/htdocs/modules/rewrite/test.blah new file mode 100644 index 0000000..d02f395 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/test.blah @@ -0,0 +1 @@ +<HTML>this is html</HTML> diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/three.html b/debian/perl-framework/t/htdocs/modules/rewrite/three.html new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/three.html @@ -0,0 +1 @@ +3 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/two.html b/debian/perl-framework/t/htdocs/modules/rewrite/two.html new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/two.html @@ -0,0 +1 @@ +2 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/vary1.html b/debian/perl-framework/t/htdocs/modules/rewrite/vary1.html new file mode 100644 index 0000000..3b08050 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/vary1.html @@ -0,0 +1 @@ +VARY1 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/vary2.html b/debian/perl-framework/t/htdocs/modules/rewrite/vary2.html new file mode 100644 index 0000000..bab3cc4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/vary2.html @@ -0,0 +1 @@ +VARY2 diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/vary3.html b/debian/perl-framework/t/htdocs/modules/rewrite/vary3.html new file mode 100644 index 0000000..cb7f4f1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/vary3.html @@ -0,0 +1 @@ +VARY3
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/vary4.html b/debian/perl-framework/t/htdocs/modules/rewrite/vary4.html new file mode 100644 index 0000000..04037af --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/vary4.html @@ -0,0 +1 @@ +VARY4
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/rewrite/zero.html b/debian/perl-framework/t/htdocs/modules/rewrite/zero.html new file mode 100644 index 0000000..ba55089 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/rewrite/zero.html @@ -0,0 +1 @@ +ZERO diff --git a/debian/perl-framework/t/htdocs/modules/session/env.shtml b/debian/perl-framework/t/htdocs/modules/session/env.shtml new file mode 100644 index 0000000..4f3ac45 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/session/env.shtml @@ -0,0 +1 @@ +<!--#echo decoding="urlencoded" var="HTTP_SESSION" --> diff --git a/debian/perl-framework/t/htdocs/modules/session_cookie/test b/debian/perl-framework/t/htdocs/modules/session_cookie/test new file mode 100644 index 0000000..3b12464 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/session_cookie/test @@ -0,0 +1 @@ +TEST
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/setenvif/htaccess/setenvif.shtml b/debian/perl-framework/t/htdocs/modules/setenvif/htaccess/setenvif.shtml new file mode 100644 index 0000000..d5342af --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/setenvif/htaccess/setenvif.shtml @@ -0,0 +1,3 @@ +1:<!--#echo var="VAR_ONE"--> +2:<!--#echo var="VAR_TWO"--> +3:<!--#echo var="VAR_THREE"--> diff --git a/debian/perl-framework/t/htdocs/modules/speling/caseonly/good.html b/debian/perl-framework/t/htdocs/modules/speling/caseonly/good.html new file mode 100644 index 0000000..58e1e67 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/speling/caseonly/good.html @@ -0,0 +1 @@ +<html></html diff --git a/debian/perl-framework/t/htdocs/modules/speling/caseonly/several1.html b/debian/perl-framework/t/htdocs/modules/speling/caseonly/several1.html new file mode 100644 index 0000000..58e1e67 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/speling/caseonly/several1.html @@ -0,0 +1 @@ +<html></html diff --git a/debian/perl-framework/t/htdocs/modules/speling/caseonly/several2.html b/debian/perl-framework/t/htdocs/modules/speling/caseonly/several2.html new file mode 100644 index 0000000..58e1e67 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/speling/caseonly/several2.html @@ -0,0 +1 @@ +<html></html diff --git a/debian/perl-framework/t/htdocs/modules/speling/nocase/good.html b/debian/perl-framework/t/htdocs/modules/speling/nocase/good.html new file mode 100644 index 0000000..58e1e67 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/speling/nocase/good.html @@ -0,0 +1 @@ +<html></html diff --git a/debian/perl-framework/t/htdocs/modules/speling/nocase/several1.html b/debian/perl-framework/t/htdocs/modules/speling/nocase/several1.html new file mode 100644 index 0000000..58e1e67 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/speling/nocase/several1.html @@ -0,0 +1 @@ +<html></html diff --git a/debian/perl-framework/t/htdocs/modules/speling/nocase/several2.html b/debian/perl-framework/t/htdocs/modules/speling/nocase/several2.html new file mode 100644 index 0000000..58e1e67 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/speling/nocase/several2.html @@ -0,0 +1 @@ +<html></html diff --git a/debian/perl-framework/t/htdocs/modules/ssl/aes128/empty.pfa b/debian/perl-framework/t/htdocs/modules/ssl/aes128/empty.pfa new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/ssl/aes128/empty.pfa diff --git a/debian/perl-framework/t/htdocs/modules/ssl/aes256/empty.pfa b/debian/perl-framework/t/htdocs/modules/ssl/aes256/empty.pfa new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/ssl/aes256/empty.pfa diff --git a/debian/perl-framework/t/htdocs/modules/substitute/.empty b/debian/perl-framework/t/htdocs/modules/substitute/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/substitute/.empty diff --git a/debian/perl-framework/t/htdocs/modules/usertrack/bar.html b/debian/perl-framework/t/htdocs/modules/usertrack/bar.html new file mode 100644 index 0000000..5716ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/usertrack/bar.html @@ -0,0 +1 @@ +bar diff --git a/debian/perl-framework/t/htdocs/modules/usertrack/foo.html b/debian/perl-framework/t/htdocs/modules/usertrack/foo.html new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/usertrack/foo.html @@ -0,0 +1 @@ +foo diff --git a/debian/perl-framework/t/htdocs/php/add.php b/debian/perl-framework/t/htdocs/php/add.php new file mode 100644 index 0000000..2a4a69d --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/add.php @@ -0,0 +1 @@ +<?php $a=1; $b=2; $c=3; $d=$a+$b+$c; echo $d?> diff --git a/debian/perl-framework/t/htdocs/php/arg.php b/debian/perl-framework/t/htdocs/php/arg.php new file mode 100644 index 0000000..9e88267 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/arg.php @@ -0,0 +1,5 @@ +<?php + for($i=0;$i<$_SERVER["argc"];$i++) { + echo "$i: ".$_SERVER["argv"][$i]."\n"; + } +?> diff --git a/debian/perl-framework/t/htdocs/php/cfunctions.php b/debian/perl-framework/t/htdocs/php/cfunctions.php new file mode 100644 index 0000000..3655cd6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/cfunctions.php @@ -0,0 +1,50 @@ +<?php + +function print_stuff($stuff) +{ + print $stuff; +} + + +function still_working() +{ + return "I'm still alive"; +} + +function dafna() +{ + static $foo = 0; + + print "Dafna!\n"; + print call_user_func("still_working")."\n"; + $foo++; + return (string) $foo; +} + + +class dafna_class { + function dafna_class() { + $this->myname = "Dafna"; + } + function GetMyName() { + return $this->myname; + } + function SetMyName($name) { + $this->myname = $name; + } +}; + +for ($i=0; $i<200; $i++): + print "$i\n"; + call_user_func("dafna"); + call_user_func("print_stuff","Hey there!!\n"); + print "$i\n"; +endfor; + + +$dafna = new dafna_class(); + +print $name=call_user_func(array($dafna, "GetMyName")); +print "\n"; + +?> diff --git a/debian/perl-framework/t/htdocs/php/classes.php b/debian/perl-framework/t/htdocs/php/classes.php new file mode 100644 index 0000000..3821ef2 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/classes.php @@ -0,0 +1,46 @@ +<?php + +/* pretty nifty object oriented code! */ + +class user { + var $first_name,$family_name,$address,$phone_num; + function display() + { + echo "User information\n"; + echo "----------------\n\n"; + echo "First name:\t ".$this->first_name."\n"; + echo "Family name:\t ".$this->family_name."\n"; + echo "Address:\t ".$this->address."\n"; + echo "Phone:\t\t ".$this->phone_num."\n"; + echo "\n\n"; + } + function initialize($first_name,$family_name,$address,$phone_num) + { + $this->first_name = $first_name; + $this->family_name = $family_name; + $this->address = $address; + $this->phone_num = $phone_num; + } +}; + + +function test($u) +{ /* one can pass classes as arguments */ + $u->display(); + $t = $u; + $t->address = "New address..."; + return $t; /* and also return them as return values */ +} + +$user1 = new user; +$user2 = new user; + +$user1->initialize("Zeev","Suraski","Ben Gourion 3, Kiryat Bialik, Israel","+972-4-8713139"); +$user2->initialize("Andi","Gutmans","Haifa, Israel","+972-4-8231621"); +$user1->display(); +$user2->display(); + +$tmp = test($user2); +$tmp->display(); + +?> diff --git a/debian/perl-framework/t/htdocs/php/construct.php b/debian/perl-framework/t/htdocs/php/construct.php new file mode 100644 index 0000000..4186c9b --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/construct.php @@ -0,0 +1,30 @@ +<?php +class obj { + function method() {} + } + +function test($o_copy) { + $o_copy->root->set_in_copied_o=TRUE; + var_dump($o_copy);?><BR><?php } + +$o->root=new obj(); + +ob_start(); +var_dump($o); +$x=ob_get_contents(); +ob_end_clean(); + +$o->root->method(); + +ob_start(); +var_dump($o); +$y=ob_get_contents(); +ob_end_clean(); + +// $o->root->method() makes ob_get_contents() have a '&' in front of object +// so this does not work. +// echo ($x==$y) ? 'success':'failure'; + +echo "x = $x"; +echo "y = $y"; +?> diff --git a/debian/perl-framework/t/htdocs/php/dirname.php b/debian/perl-framework/t/htdocs/php/dirname.php new file mode 100644 index 0000000..26f5845 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/dirname.php @@ -0,0 +1,17 @@ +<?php + + function check_dirname($path) + { + print "dirname($path) == " . dirname($path) . "\n"; + } + + check_dirname("/foo/"); + check_dirname("/foo"); + check_dirname("/foo/bar"); + check_dirname("d:\\foo\\bar.inc"); + check_dirname("/"); + check_dirname(".../foo"); + check_dirname("./foo"); + check_dirname("foobar///"); + check_dirname("c:\\foo"); +?> diff --git a/debian/perl-framework/t/htdocs/php/divide.php b/debian/perl-framework/t/htdocs/php/divide.php new file mode 100644 index 0000000..3cbc5be --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/divide.php @@ -0,0 +1 @@ +<?php $a=27; $b=3; $c=3; $d=$a/$b/$c; echo $d?> diff --git a/debian/perl-framework/t/htdocs/php/do-while.php b/debian/perl-framework/t/htdocs/php/do-while.php new file mode 100644 index 0000000..b824bfb --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/do-while.php @@ -0,0 +1,7 @@ +<?php +$i=3; +do { + echo $i; + $i--; +} while($i>0); +?> diff --git a/debian/perl-framework/t/htdocs/php/else.php b/debian/perl-framework/t/htdocs/php/else.php new file mode 100644 index 0000000..0bdb1a3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/else.php @@ -0,0 +1,7 @@ +<?php $a=1; + if($a==0): + echo "bad"; + else: + echo "good"; + endif?> + diff --git a/debian/perl-framework/t/htdocs/php/elseif.php b/debian/perl-framework/t/htdocs/php/elseif.php new file mode 100644 index 0000000..e5223bf --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/elseif.php @@ -0,0 +1,9 @@ +<?php $a=1; + if($a==0): + echo "bad"; + elseif($a==3): + echo "bad"; + else: + echo "good"; + endif?> + diff --git a/debian/perl-framework/t/htdocs/php/eval.php b/debian/perl-framework/t/htdocs/php/eval.php new file mode 100644 index 0000000..991185e --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/eval.php @@ -0,0 +1,5 @@ +<?php + error_reporting(0); + $a="echo \"Hello\";"; + eval($a); +?> diff --git a/debian/perl-framework/t/htdocs/php/eval2.php b/debian/perl-framework/t/htdocs/php/eval2.php new file mode 100644 index 0000000..53d16a0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/eval2.php @@ -0,0 +1,8 @@ +<?php +old_function F $a ( + eval($a); +); + +error_reporting(0); +F("echo \"Hello\";"); +?> diff --git a/debian/perl-framework/t/htdocs/php/eval3.php b/debian/perl-framework/t/htdocs/php/eval3.php new file mode 100644 index 0000000..c8041fd --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/eval3.php @@ -0,0 +1,10 @@ +<?php + +error_reporting(0); + +$message = "echo \"hey\n\";"; + +for ($i=0; $i<10; $i++) { + eval($message); + echo $i."\n"; +} diff --git a/debian/perl-framework/t/htdocs/php/eval4.php b/debian/perl-framework/t/htdocs/php/eval4.php new file mode 100644 index 0000000..f19c1c8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/eval4.php @@ -0,0 +1,13 @@ +<?php + +error_reporting(0); + +eval("function test() { echo \"hey, this is a function inside an eval()!\\n\"; } +"); + +$i=0; +while ($i<10) { + eval("echo \"hey, this is a regular echo'd eval()\\n\";"); + test(); + $i++; +} diff --git a/debian/perl-framework/t/htdocs/php/fpm/action/sub2/test.php b/debian/perl-framework/t/htdocs/php/fpm/action/sub2/test.php new file mode 100644 index 0000000..4314e0d --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/fpm/action/sub2/test.php @@ -0,0 +1,4 @@ +<?php + foreach ($_SERVER as $key => $value) { + echo "$key=$value\n"; + }
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/fpm/pp/sub1/test.php b/debian/perl-framework/t/htdocs/php/fpm/pp/sub1/test.php new file mode 100644 index 0000000..4314e0d --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/fpm/pp/sub1/test.php @@ -0,0 +1,4 @@ +<?php + foreach ($_SERVER as $key => $value) { + echo "$key=$value\n"; + }
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/fpm/test.php b/debian/perl-framework/t/htdocs/php/fpm/test.php new file mode 100644 index 0000000..ccce0c3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/fpm/test.php @@ -0,0 +1 @@ +<?php var_export($_SERVER)?> diff --git a/debian/perl-framework/t/htdocs/php/func1.php b/debian/perl-framework/t/htdocs/php/func1.php new file mode 100644 index 0000000..525b791 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/func1.php @@ -0,0 +1 @@ +<?php echo strlen("abcdef")?> diff --git a/debian/perl-framework/t/htdocs/php/func2.php b/debian/perl-framework/t/htdocs/php/func2.php new file mode 100644 index 0000000..64ea795 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/func2.php @@ -0,0 +1,13 @@ +<?php +old_function blah ( + static $hey=0,$yo=0; + + echo "hey=".$hey++.", ",$yo--."\n"; +); + +blah(); +blah(); +blah(); +if (isset($hey) || isset($yo)) { + echo "Local variables became global :(\n"; +} diff --git a/debian/perl-framework/t/htdocs/php/func3.php b/debian/perl-framework/t/htdocs/php/func3.php new file mode 100644 index 0000000..62cee15 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/func3.php @@ -0,0 +1,89 @@ +<?php + +old_function a ( + echo "hey\n"; +); + +function b($i) +{ + echo "$i\n"; +} + + +function c($i,$j) +{ + echo "Counting from $i to $j\n"; + for ($k=$i; $k<=$j; $k++) { + echo "$k\n"; + } +} + +a(); +b("blah"); +a(); +b("blah","blah"); +c(7,14); + +a(); + + +old_function factorial $n ( + if ($n==0 || $n==1) { + return 1; + } else { + return factorial($n-1)*$n; + } +); + +function factorial2($start, $n) +{ + if ($n<=$start) { + return $start; + } else { + return factorial2($start,$n-1)*$n; + } +} + + +for ($k=0; $k<10; $k++) { + for ($i=0; $i<=10; $i++) { + $n=factorial($i); + echo "factorial($i) = $n\n"; + } +} + + +echo "and now, from a function...\n"; + +old_function call_fact ( + echo "(it should break at 5...)\n"; + for ($i=0; $i<=10; $i++) { + if ($i == 5) break; + $n=factorial($i); + echo "factorial($i) = $n\n"; + } +); + +old_function return4 ( return 4; ); +old_function return7 ( return 7; ); + +for ($k=0; $k<10; $k++) { + call_fact(); +} + +echo "------\n"; +$result = factorial(factorial(3)); +echo "$result\n"; + +$result=factorial2(return4(),return7()); +echo "$result\n"; + +old_function andi $i, $j ( + for ($k=$i ; $k<=$j ; $k++) { + if ($k >5) continue; + echo "$k\n"; + } +); + +andi (3,10); + diff --git a/debian/perl-framework/t/htdocs/php/func4.php b/debian/perl-framework/t/htdocs/php/func4.php new file mode 100644 index 0000000..b1dc39c --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/func4.php @@ -0,0 +1,30 @@ +<?php + +echo "Before function declaration...\n"; + +old_function print_something_multiple_times $something,$times ( + echo "----\nIn function, printing the string \"$something\" $times times\n"; + for ($i=0; $i<$times; $i++) { + echo "$i) $something\n"; + } + echo "Done with function...\n-----\n"; +); + +old_function some_other_function ( + echo "This is some other function, to ensure more than just one function works fine...\n"; +); + +echo "After function declaration...\n"; + +echo "Calling function for the first time...\n"; +print_something_multiple_times("This works!",10); +echo "Returned from function call...\n"; + +echo "Calling the function for the second time...\n"; +print_something_multiple_times("This like, really works and stuff...",3); +echo "Returned from function call...\n"; + +some_other_function(); + +?> + diff --git a/debian/perl-framework/t/htdocs/php/func5.php b/debian/perl-framework/t/htdocs/php/func5.php new file mode 100644 index 0000000..dfc86bb --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/func5.php @@ -0,0 +1,25 @@ +<?php + +$file = $_SERVER["argv"][0]; + +function foo() +{ + global $file; + + $fp = fopen($file, "w"); + if( $fp ) + { + fclose($fp); + } + else + { + // Attempt to alert the user + error_log("can't write $file.", 0); + } +} + +register_shutdown_function("foo"); + +print "foo() will be called on shutdown...\n"; + +?> diff --git a/debian/perl-framework/t/htdocs/php/func6.php b/debian/perl-framework/t/htdocs/php/func6.php new file mode 100644 index 0000000..8ac8e1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/func6.php @@ -0,0 +1,18 @@ +<?php +function F() +{ + $a = "Hello "; + return($a); +} + +function G() +{ + static $myvar = 4; + + echo "$myvar "; + echo F(); + echo "$myvar"; +} + +G(); +?> diff --git a/debian/perl-framework/t/htdocs/php/getenv.php b/debian/perl-framework/t/htdocs/php/getenv.php new file mode 100644 index 0000000..5d0dffd --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/getenv.php @@ -0,0 +1 @@ +<?php echo getenv("REQUEST_METHOD"); ?> diff --git a/debian/perl-framework/t/htdocs/php/getlastmod.php b/debian/perl-framework/t/htdocs/php/getlastmod.php new file mode 100644 index 0000000..e10a7eb --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/getlastmod.php @@ -0,0 +1 @@ +<?php echo date("F", getlastmod()); ?> diff --git a/debian/perl-framework/t/htdocs/php/globals.php b/debian/perl-framework/t/htdocs/php/globals.php new file mode 100644 index 0000000..619ea73 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/globals.php @@ -0,0 +1,19 @@ +<?php error_reporting(0); + $a = 10; + function Test() + { + static $a=1; + global $b; + $c = 1; + $b = 5; + echo "$a $b "; + $a++; + $c++; + echo "$a $c "; + } + Test(); + echo "$a $b $c "; + Test(); + echo "$a $b $c "; + Test()?> + diff --git a/debian/perl-framework/t/htdocs/php/hello.php b/debian/perl-framework/t/htdocs/php/hello.php new file mode 100644 index 0000000..e2c0484 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/hello.php @@ -0,0 +1 @@ +<?php echo "Hello World"?> diff --git a/debian/perl-framework/t/htdocs/php/if.php b/debian/perl-framework/t/htdocs/php/if.php new file mode 100644 index 0000000..8a25e82 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/if.php @@ -0,0 +1 @@ +<?php $a=1; if($a>0) { echo "Yes"; } ?> diff --git a/debian/perl-framework/t/htdocs/php/if2.php b/debian/perl-framework/t/htdocs/php/if2.php new file mode 100644 index 0000000..612718c --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/if2.php @@ -0,0 +1,11 @@ +<?php $a = 1; +old_function Test $a ( + if($a<3): + return(3); + endif; +); + +if($a < Test($a)): + echo "$a\n"; + $a++; +endif?> diff --git a/debian/perl-framework/t/htdocs/php/include.inc b/debian/perl-framework/t/htdocs/php/include.inc new file mode 100644 index 0000000..d436a7b --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/include.inc @@ -0,0 +1,3 @@ +<?php + echo "Hello"; +?> diff --git a/debian/perl-framework/t/htdocs/php/include.php b/debian/perl-framework/t/htdocs/php/include.php new file mode 100644 index 0000000..2f2eac6 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/include.php @@ -0,0 +1,3 @@ +<?php + include "include.inc"; +?> diff --git a/debian/perl-framework/t/htdocs/php/include2.inc b/debian/perl-framework/t/htdocs/php/include2.inc new file mode 100644 index 0000000..7039e3f --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/include2.inc @@ -0,0 +1,5 @@ +<?php + old_function MyFunc $a ( + echo $a; + ); +?> diff --git a/debian/perl-framework/t/htdocs/php/include2.php b/debian/perl-framework/t/htdocs/php/include2.php new file mode 100644 index 0000000..b529569 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/include2.php @@ -0,0 +1,4 @@ +<?php + include "include2.inc"; + MyFunc("Hello"); +?> diff --git a/debian/perl-framework/t/htdocs/php/inheritance.php b/debian/perl-framework/t/htdocs/php/inheritance.php new file mode 100644 index 0000000..a0944b1 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/inheritance.php @@ -0,0 +1,43 @@ +<?php + +/* Inheritance test. Pretty nifty if I do say so myself! */ + +class foo { + var $a; + var $b; + function display() { + echo "This is class foo\n"; + echo "a = ".$this->a."\n"; + echo "b = ".$this->b."\n"; + } + function mul() { + return $this->a*$this->b; + } +}; + +class bar extends foo { + var $c; + function display() { /* alternative display function for class bar */ + echo "This is class bar\n"; + echo "a = ".$this->a."\n"; + echo "b = ".$this->b."\n"; + echo "c = ".$this->c."\n"; + } +}; + + +$foo1 = new foo; +$foo1->a = 2; +$foo1->b = 5; +$foo1->display(); +echo $foo1->mul()."\n"; + +echo "-----\n"; + +$bar1 = new bar; +$bar1->a = 4; +$bar1->b = 3; +$bar1->c = 12; +$bar1->display(); +echo $bar1->mul()."\n"; +?> diff --git a/debian/perl-framework/t/htdocs/php/lookup.php b/debian/perl-framework/t/htdocs/php/lookup.php new file mode 100644 index 0000000..bbdfa43 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/lookup.php @@ -0,0 +1,5 @@ +<?php +$r = apache_lookup_uri("target.php"); +printf("status=%d:method=%s:uri=%s", + $r->status, $r->method, $r->uri); +?> diff --git a/debian/perl-framework/t/htdocs/php/lookup2.php b/debian/perl-framework/t/htdocs/php/lookup2.php new file mode 100644 index 0000000..f4f74ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/lookup2.php @@ -0,0 +1,8 @@ +<?php +header("X-Before: foobar"); +$r = apache_lookup_uri("target.php"); +header("X-After: foobar"); + +printf("status=%d:method=%s:uri=%s", + $r->status, $r->method, $r->uri); +?> diff --git a/debian/perl-framework/t/htdocs/php/multiply.php b/debian/perl-framework/t/htdocs/php/multiply.php new file mode 100644 index 0000000..4ed88c5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/multiply.php @@ -0,0 +1 @@ +<?php $a=2; $b=4; $c=8; $d=$a*$b*$c; echo $d?> diff --git a/debian/perl-framework/t/htdocs/php/multiviews/file.html b/debian/perl-framework/t/htdocs/php/multiviews/file.html new file mode 100644 index 0000000..3c36ced --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/multiviews/file.html @@ -0,0 +1 @@ +file.html
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/nestif.php b/debian/perl-framework/t/htdocs/php/nestif.php new file mode 100644 index 0000000..6b0654a --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/nestif.php @@ -0,0 +1,15 @@ +<?php $a=1; $b=2; + if($a==0): + echo "bad"; + elseif($a==3): + echo "bad"; + else: + if($b==1): + echo "bad"; + elseif($b==2): + echo "good"; + else: + echo "bad"; + endif; + endif?> + diff --git a/debian/perl-framework/t/htdocs/php/ops.php b/debian/perl-framework/t/htdocs/php/ops.php new file mode 100644 index 0000000..912ba33 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/ops.php @@ -0,0 +1 @@ +<?php $a=8; $b=4; $c=8; echo $a|$b&$c?> diff --git a/debian/perl-framework/t/htdocs/php/param.php b/debian/perl-framework/t/htdocs/php/param.php new file mode 100644 index 0000000..0bc2bf0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/param.php @@ -0,0 +1,5 @@ +<?php old_function Test $a,$b ( + echo $a+$b; + ); + Test(1,2)?> + diff --git a/debian/perl-framework/t/htdocs/php/param2.php b/debian/perl-framework/t/htdocs/php/param2.php new file mode 100644 index 0000000..4a8fe74 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/param2.php @@ -0,0 +1,7 @@ +<?php old_function Test $b ( + $b++; + return($b); + ); + $a = Test(1); + echo $a?> + diff --git a/debian/perl-framework/t/htdocs/php/recurse.php b/debian/perl-framework/t/htdocs/php/recurse.php new file mode 100644 index 0000000..3378bfb --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/recurse.php @@ -0,0 +1,10 @@ +<?php Function Test() + { + static $a=1; + + echo "$a "; + $a++; + if($a<10): Test(); endif; + } + Test()?> + diff --git a/debian/perl-framework/t/htdocs/php/regression.php b/debian/perl-framework/t/htdocs/php/regression.php new file mode 100644 index 0000000..8713d41 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/regression.php @@ -0,0 +1,22 @@ +PHP Regression Test + +<?php + +include("regression1.inc"); + +$wedding_timestamp = mktime(20,0,0,8,31,1997); +$time_left=$wedding_timestamp-time(); + +if ($time_left>0) { + $days = $time_left/(24*3600); + $time_left -= $days*24*3600; + $hours = $time_left/3600; + $time_left -= $hours*3600; + $minutes = $time_left/60; + echo "Limor Ullmann is getting married on ".($wedding_date=date("l, F dS, Y",$wedding_timestamp)).",\nwhich is $days days, $hours hours and $minutes minutes from now.\n"; + echo "Her hashed wedding date is $wedding_date.\n"; +} else { + echo "Limor Ullmann is now Limor Baruch :I\n"; +} +?> + diff --git a/debian/perl-framework/t/htdocs/php/regression1.inc b/debian/perl-framework/t/htdocs/php/regression1.inc new file mode 100644 index 0000000..d841d06 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/regression1.inc @@ -0,0 +1,356 @@ +<html> +<head> +<?php +/* the point of this file is to intensively test various aspects of + * the parser. right now, each test focuses in one aspect only + * (e.g. variable aliasing, arithemtic operator, various control + * structures), while trying to combine code from other parts of the + * parser as well. + */ +?> + +*** Testing assignments and variable aliasing: ***<br> +<?php + /* This test tests assignments to variables using other variables as variable-names */ + $a = "b"; + $$a = "test"; + $$$a = "blah"; + ${$$$a}["associative arrays work too"] = "this is nifty"; +?> +This should read "blah": <?php echo "$test<br>\n"; ?> +This should read "this is nifty": <?php echo $blah[$test="associative arrays work too"]."<br>\n"; ?> +*************************************************<br> + +*** Testing integer operators ***<br> +<?php + /* test just about any operator possible on $i and $j (ints) */ + $i = 5; + $j = 3; +?> +Correct result - 8: <?php echo $i+$j; ?><br> +Correct result - 8: <?php echo $i+$j; ?><br> +Correct result - 2: <?php echo $i-$j; ?><br> +Correct result - -2: <?php echo $j-$i; ?><br> +Correct result - 15: <?php echo $i*$j; ?><br> +Correct result - 15: <?php echo $j*$i; ?><br> +Correct result - 2: <?php echo $i%$j; ?><br> +Correct result - 3: <?php echo $j%$i; ?><br> +*********************************<br> + +*** Testing real operators ***<br> +<?php + /* test just about any operator possible on $i and $j (floats) */ + $i = 5.0; + $j = 3.0; +?> +Correct result - 8: <?php echo $i+$j; ?><br> +Correct result - 8: <?php echo $i+$j; ?><br> +Correct result - 2: <?php echo $i-$j; ?><br> +Correct result - -2: <?php echo $j-$i; ?><br> +Correct result - 15: <?php echo $i*$j; ?><br> +Correct result - 15: <?php echo $j*$i; ?><br> +Correct result - 2: <?php echo $i%$j; ?><br> +Correct result - 3: <?php echo $j%$i; ?><br> +*********************************<br> + +*** Testing if/elseif/else control ***<br> + +<?php +/* sick if/elseif/else test by Andi :) */ +$a = 5; +if ($a == "4") { + echo "This "." does "." not "." work<br>\n"; +} elseif ($a == "5") { + echo "This "." works<br>\n"; + $a = 6; + if ("andi" == ($test = "andi")) { + echo "this_still_works<br>\n"; + } elseif (1) { + echo "should_not_print<br>\n"; + } else { + echo "should_not_print<br>\n"; + } + if (44 == 43) { + echo "should_not_print<br>\n"; + } else { + echo "should_print<br>\n"; + } +} elseif ($a == 6) { + echo "this "."broken<br>\n"; + if (0) { + echo "this_should_not_print<br>\n"; + } else { + echo "TestingDanglingElse_This_Should_not_print<br>\n"; + } +} else { + echo "This "."does "." not"." work<br>\n"; +} +?> + + +*** Seriously nested if's test ***<br> +** spelling correction by kluzz ** +<?php +/* yet another sick if/elseif/else test by Zeev */ +$i=$j=0; +echo "Only two lines of text should follow:<br>\n"; +if (0) { /* this code is not supposed to be executed */ + echo "hmm, this shouldn't be displayed #1<br>\n"; + $j++; + if (1) { + $i ++= + $j; + if (0) { + $j = ++$i; + if (1) { + $j *= $i; + echo "damn, this shouldn't be displayed<br>\n"; + } else { + $j /= $i; + ++$j; + echo "this shouldn't be displayed either<br>\n"; + } + } elseif (1) { + $i++; $j++; + echo "this isn't supposed to be displayed<br>\n"; + } + } elseif (0) { + $i++; + echo "this definitely shouldn't be displayed<br>\n"; + } else { + --$j; + echo "and this too shouldn't be displayed<br>\n"; + while ($j>0) { + $j--; + } + } +} elseif (2-2) { /* as long as 2-2==0, this isn't supposed to be executed either */ + $i = ++$j; + echo "hmm, this shouldn't be displayed #2<br>\n"; + if (1) { + $j = ++$i; + if (0) { + $j = $i*2+$j*($i++); + if (1) { + $i++; + echo "damn, this shouldn't be displayed<br>\n"; + } else { + $j++; + echo "this shouldn't be displayed either<br>\n"; + } + } else if (1) { + ++$j; + echo "this isn't supposed to be displayed<br>\n"; + } + } elseif (0) { + $j++; + echo "this definitely shouldn't be displayed<br>\n"; + } else { + $i++; + echo "and this too shouldn't be displayed<br>\n"; + } +} else { + $j=$i++; /* this should set $i to 1, but shouldn't change $j (it's assigned $i's previous values, zero) */ + echo "this should be displayed. should be: \$i=1, \$j=0. is: \$i=$i, \$j=$j<br>\n"; + if (1) { + $j += ++$i; /* ++$i --> $i==2, $j += 2 --> $j==2 */ + if (0) { + $j += 40; + if (1) { + $i += 50; + echo "damn, this shouldn't be displayed<br>\n"; + } else { + $j += 20; + echo "this shouldn't be displayed either<br>\n"; + } + } else if (1) { + $j *= $i; /* $j *= 2 --> $j == 4 */ + echo "this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=$i, \$j=$j<br>\n"; + echo "3 loop iterations should follow:<br>\n"; + while ($i<=$j) { + echo $i++." $j<br>\n"; + } + } + } elseif (0) { + echo "this definitely shouldn't be displayed<br>\n"; + } else { + echo "and this too shouldn't be displayed<br>\n"; + } + echo "**********************************<br>\n"; +} +?> + +*** C-style else-if's ***<br> +<?php + /* looks like without we even tried, C-style else-if structure works fine! */ + if ($a=0) { + echo "This shouldn't be displayed<br>\n"; + } else if ($a++) { + echo "This shouldn't be displayed either<br>\n"; + } else if (--$a) { + echo "No, this neither<br>\n"; + } else if (++$a) { + echo "This should be displayed<br>\n"; + } else { + echo "This shouldn't be displayed at all<br>\n"; + } +?> +*************************<br> + +*** WHILE tests ***<br> +<?php +$i=0; +$j=20; +while ($i<(2*$j)) { + if ($i>$j) { + echo "$i is greater than $j<br>\n"; + } else if ($i==$j) { + echo "$i equals $j<br>\n"; + } else { + echo "$i is smaller than $j<br>\n"; + } + $i++; +} +?> +*******************<br> + + +*** Nested WHILEs ***<br> +<?php +$arr_len=3; + +$i=0; +while ($i<$arr_len) { + $j=0; + while ($j<$arr_len) { + $k=0; + while ($k<$arr_len) { + ${"test$i$j"}[$k] = $i+$j+$k; + $k++; + } + $j++; + } + $i++; +} + +echo "Each array variable should be equal to the sum of its indices:<br>\n"; + +$i=0; +while ($i<$arr_len) { + $j=0; + while ($j<$arr_len) { + $k=0; + while ($k<$arr_len) { + echo "\${test$i$j}[$k] = ".${"test$i$j"}[$k]."<br>\n"; + $k++; + } + $j++; + } + $i++; +} +?> +*********************<br> + +*** hash test... ***<br> +<?php +/* +$i=0; + +while ($i<10000) { + $arr[$i]=$i; + $i++; +} + +$i=0; +while ($i<10000) { + echo $arr[$i++]."<br>\n"; +} +*/ +echo "commented out..."; +?> + +**************************<br> + +*** Hash resizing test ***<br> +<?php +$i = 10; +$a = 'b'; +while ($i > 0) { + $a = $a . 'a'; + echo "$a<br>\n"; + $resize[$a] = $i; + $i--; +} +$i = 10; +$a = 'b'; +while ($i > 0) { + $a = $a . 'a'; + echo "$a<br>\n"; + echo $resize[$a]."<br>\n"; + $i--; +} +?> +**************************<br> + + +*** break/continue test ***<br> +<?php +$i=0; + +echo "\$i should go from 0 to 2<br>\n"; +while ($i<5) { + if ($i>2) { + break; + } + $j=0; + echo "\$j should go from 3 to 4, and \$q should go from 3 to 4<br>\n"; + while ($j<5) { + if ($j<=2) { + $j++; + continue; + } + echo " \$j=$j<br>\n"; + for ($q=0; $q<=10; $q++) { + if ($q<3) { + continue; + } + if ($q>4) { + break; + } + echo " \$q=$q<br>\n"; + } + $j++; + } + $j=0; + echo "\$j should go from 0 to 2<br>\n"; + while ($j<5) { + if ($j>2) { + $k=0; + echo "\$k should go from 0 to 2<br>\n"; + while ($k<5) { + if ($k>2) { + break 2; + } + echo " \$k=$k<br>\n"; + $k++; + } + } + echo " \$j=$j<br>\n"; + $j++; + } + echo "\$i=$i<br>\n"; + $i++; +} +?> +***********************<br> + +*** Nested file include test ***<br> +<?php include("regression2.inc"); ?> +********************************<br> + +<?php +{ + echo "Tests completed.<br>\n"; # testing some PHP style comment... +} +?> diff --git a/debian/perl-framework/t/htdocs/php/regression2.inc b/debian/perl-framework/t/htdocs/php/regression2.inc new file mode 100644 index 0000000..a660307 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/regression2.inc @@ -0,0 +1,6 @@ +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +<?php echo "and this is PHP code, 2+2=".(2+2).""; ?> + +</html> diff --git a/debian/perl-framework/t/htdocs/php/regression2.php b/debian/perl-framework/t/htdocs/php/regression2.php new file mode 100644 index 0000000..0cd56bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/regression2.php @@ -0,0 +1,369 @@ +<?php +for ($jdk=0; $jdk<50; $jdk++) { +?><html> +<head> +<?php /* the point of this file is to intensively test various aspects of the parser. + * right now, each test focuses in one aspect only (e.g. variable aliasing, arithemtic operator, + * various control structures), while trying to combine code from other parts of the parser as well. + */ +?> +*** Testing assignments and variable aliasing: *** +<?php + /* This test tests assignments to variables using other variables as variable-names */ + $a = "b"; + $$a = "test"; + $$$a = "blah"; + ${$$$a}["associative arrays work too"] = "this is nifty"; +?> +This should read "blah": <?php echo "$test\n"; ?> +This should read "this is nifty": <?php echo $blah[$test="associative arrays work too"]."\n"; ?> +************************************************* + +*** Testing integer operators *** +<?php + /* test just about any operator possible on $i and $j (ints) */ + $i = 5; + $j = 3; +?> +Correct result - 8: <?php echo $i+$j; ?> + +Correct result - 8: <?php echo $i+$j; ?> + +Correct result - 2: <?php echo $i-$j; ?> + +Correct result - -2: <?php echo $j-$i; ?> + +Correct result - 15: <?php echo $i*$j; ?> + +Correct result - 15: <?php echo $j*$i; ?> + +Correct result - 2: <?php echo $i%$j; ?> + +Correct result - 3: <?php echo $j%$i; ?> + +********************************* + +*** Testing real operators *** +<?php + /* test just about any operator possible on $i and $j (floats) */ + $i = 5.0; + $j = 3.0; +?> +Correct result - 8: <?php echo $i+$j; ?> + +Correct result - 8: <?php echo $i+$j; ?> + +Correct result - 2: <?php echo $i-$j; ?> + +Correct result - -2: <?php echo $j-$i; ?> + +Correct result - 15: <?php echo $i*$j; ?> + +Correct result - 15: <?php echo $j*$i; ?> + +Correct result - 2: <?php echo $i%$j; ?> + +Correct result - 3: <?php echo $j%$i; ?> + +********************************* + +*** Testing if/elseif/else control *** + +<?php +/* sick if/elseif/else test by Andi :) */ +$a = 5; +if ($a == "4") { + echo "This "." does "." not "." work\n"; +} elseif ($a == "5") { + echo "This "." works\n"; + $a = 6; + if ("andi" == ($test = "andi")) { + echo "this_still_works\n"; + } elseif (1) { + echo "should_not_print\n"; + } else { + echo "should_not_print\n"; + } + if (44 == 43) { + echo "should_not_print\n"; + } else { + echo "should_print\n"; + } +} elseif ($a == 6) { + echo "this "."broken\n"; + if (0) { + echo "this_should_not_print\n"; + } else { + echo "TestingDanglingElse_This_Should_not_print\n"; + } +} else { + echo "This "."does "." not"." work\n"; +} +?> + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +<?php +/* yet another sick if/elseif/else test by Zeev */ +$i=$j=0; +echo "Only two lines of text should follow:\n"; +if (0) { /* this code is not supposed to be executed */ + echo "hmm, this shouldn't be displayed #1\n"; + $j++; + if (1) { + $i += $j; + if (0) { + $j = ++$i; + if (1) { + $j *= $i; + echo "damn, this shouldn't be displayed\n"; + } else { + $j /= $i; + ++$j; + echo "this shouldn't be displayed either\n"; + } + } elseif (1) { + $i++; $j++; + echo "this isn't supposed to be displayed\n"; + } + } elseif (0) { + $i++; + echo "this definitely shouldn't be displayed\n"; + } else { + --$j; + echo "and this too shouldn't be displayed\n"; + while ($j>0) { + $j--; + } + } +} elseif (2-2) { /* as long as 2-2==0, this isn't supposed to be executed either */ + $i = ++$j; + echo "hmm, this shouldn't be displayed #2\n"; + if (1) { + $j = ++$i; + if (0) { + $j = $i*2+$j*($i++); + if (1) { + $i++; + echo "damn, this shouldn't be displayed\n"; + } else { + $j++; + echo "this shouldn't be displayed either\n"; + } + } else if (1) { + ++$j; + echo "this isn't supposed to be displayed\n"; + } + } elseif (0) { + $j++; + echo "this definitely shouldn't be displayed\n"; + } else { + $i++; + echo "and this too shouldn't be displayed\n"; + } +} else { + $j=$i++; /* this should set $i to 1, but shouldn't change $j (it's assigned $i's previous values, zero) */ + echo "this should be displayed. should be: \$i=1, \$j=0. is: \$i=$i, \$j=$j\n"; + if (1) { + $j += ++$i; /* ++$i --> $i==2, $j += 2 --> $j==2 */ + if (0) { + $j += 40; + if (1) { + $i += 50; + echo "damn, this shouldn't be displayed\n"; + } else { + $j += 20; + echo "this shouldn't be displayed either\n"; + } + } else if (1) { + $j *= $i; /* $j *= 2 --> $j == 4 */ + echo "this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=$i, \$j=$j\n"; + echo "3 loop iterations should follow:\n"; + while ($i<=$j) { + echo $i++." $j\n"; + } + } + } elseif (0) { + echo "this definitely shouldn't be displayed\n"; + } else { + echo "and this too shouldn't be displayed\n"; + } + echo "**********************************\n"; +} +?> + +*** C-style else-if's *** +<?php + /* looks like without we even tried, C-style else-if structure works fine! */ + if ($a=0) { + echo "This shouldn't be displayed\n"; + } else if ($a++) { + echo "This shouldn't be displayed either\n"; + } else if (--$a) { + echo "No, this neither\n"; + } else if (++$a) { + echo "This should be displayed\n"; + } else { + echo "This shouldn't be displayed at all\n"; + } +?> +************************* + +*** WHILE tests *** +<?php +$i=0; +$j=20; +while ($i<(2*$j)) { + if ($i>$j) { + echo "$i is greater than $j\n"; + } else if ($i==$j) { + echo "$i equals $j\n"; + } else { + echo "$i is smaller than $j\n"; + } + $i++; +} +?> +******************* + + +*** Nested WHILEs *** +<?php +$arr_len=3; + +$i=0; +while ($i<$arr_len) { + $j=0; + while ($j<$arr_len) { + $k=0; + while ($k<$arr_len) { + ${"test$i$j"}[$k] = $i+$j+$k; + $k++; + } + $j++; + } + $i++; +} + +echo "Each array variable should be equal to the sum of its indices:\n"; + +$i=0; +while ($i<$arr_len) { + $j=0; + while ($j<$arr_len) { + $k=0; + while ($k<$arr_len) { + echo "\${test$i$j}[$k] = ".${"test$i$j"}[$k]."\n"; + $k++; + } + $j++; + } + $i++; +} +?> +********************* + +*** hash test... *** +<?php +/* +$i=0; + +while ($i<10000) { + $arr[$i]=$i; + $i++; +} + +$i=0; +while ($i<10000) { + echo $arr[$i++]."\n"; +} +*/ +echo "commented out..."; +?> + +************************** + +*** Hash resizing test *** +<?php +$i = 10; +$a = "b"; +while ($i > 0) { + $a = $a . "a"; + echo "$a\n"; + $resize[$a] = $i; + $i--; +} +$i = 10; +$a = "b"; +while ($i > 0) { + $a = $a . "a"; + echo "$a\n"; + echo $resize[$a]."\n"; + $i--; +} +?> +************************** + + +*** break/continue test *** +<?php +$i=0; + +echo "\$i should go from 0 to 2\n"; +while ($i<5) { + if ($i>2) { + break; + } + $j=0; + echo "\$j should go from 3 to 4, and \$q should go from 3 to 4\n"; + while ($j<5) { + if ($j<=2) { + $j++; + continue; + } + echo " \$j=$j\n"; + for ($q=0; $q<=10; $q++) { + if ($q<3) { + continue; + } + if ($q>4) { + break; + } + echo " \$q=$q\n"; + } + $j++; + } + $j=0; + echo "\$j should go from 0 to 2\n"; + while ($j<5) { + if ($j>2) { + $k=0; + echo "\$k should go from 0 to 2\n"; + while ($k<5) { + if ($k>2) { + break 2; + } + echo " \$k=$k\n"; + $k++; + } + } + echo " \$j=$j\n"; + $j++; + } + echo "\$i=$i\n"; + $i++; +} +?> +*********************** + +*** Nested file include test *** +<?php include("regression2.inc"); ?> +******************************** + +<?php +{ + echo "Tests completed.\n"; # testing some PHP style comment... +} + +} ?> diff --git a/debian/perl-framework/t/htdocs/php/regression3.php b/debian/perl-framework/t/htdocs/php/regression3.php new file mode 100644 index 0000000..703cf9b --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/regression3.php @@ -0,0 +1,22 @@ +<?php +old_function RekTest $nr ( + +echo " $nr "; + + +$j=$nr+1; +while ($j < 10) +{ + echo " a "; + RekTest($j); + $j++; + echo " b $j "; +}; +echo "\n"; + + + +); + +RekTest(0); +?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/badenv.php b/debian/perl-framework/t/htdocs/php/safemode/badenv.php new file mode 100644 index 0000000..97bcdfa --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/badenv.php @@ -0,0 +1,2 @@ +<?php putenv("FISH=HelloWorld"); +echo getenv("FISH"); ?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/error/mail.php b/debian/perl-framework/t/htdocs/php/safemode/error/mail.php new file mode 100644 index 0000000..cb6fdaa --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/error/mail.php @@ -0,0 +1,9 @@ +<?php +// fix for CAN-2002-0985: mail() must reject 5th argument in safe mode +if (mail("root@localhost", "httpd-test PHP mail", + "test mail from httpd-test", "", "-C/etc/passwd")) { + print("FAIL"); +} else { + print("OK"); +} +?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/hello.txt b/debian/perl-framework/t/htdocs/php/safemode/hello.txt new file mode 100644 index 0000000..39aaa32 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/hello.txt @@ -0,0 +1 @@ +This is Content. diff --git a/debian/perl-framework/t/htdocs/php/safemode/noexec/system.php b/debian/perl-framework/t/htdocs/php/safemode/noexec/system.php new file mode 100644 index 0000000..5a224c9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/noexec/system.php @@ -0,0 +1 @@ +<?php system("/bin/ls /"); ?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/nofile/readfile.php b/debian/perl-framework/t/htdocs/php/safemode/nofile/readfile.php new file mode 100644 index 0000000..bc2c731 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/nofile/readfile.php @@ -0,0 +1 @@ +<?php readfile("../hello.txt"); ?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/safemode/protected.php b/debian/perl-framework/t/htdocs/php/safemode/protected.php new file mode 100644 index 0000000..3f8b64a --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/protected.php @@ -0,0 +1,2 @@ +<?php putenv("FOO_FEE=HelloWorld"); +echo getenv("FOO_FEE"); ?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/putenv.php b/debian/perl-framework/t/htdocs/php/safemode/putenv.php new file mode 100644 index 0000000..575e7f7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/putenv.php @@ -0,0 +1,2 @@ +<?php putenv("FOO_BAR=HelloWorld"); +echo getenv("FOO_BAR"); ?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/readfile.php b/debian/perl-framework/t/htdocs/php/safemode/readfile.php new file mode 100644 index 0000000..60eda17 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/readfile.php @@ -0,0 +1 @@ +<?php readfile("hello.txt"); ?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/readpass.php b/debian/perl-framework/t/htdocs/php/safemode/readpass.php new file mode 100644 index 0000000..e983308 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/readpass.php @@ -0,0 +1 @@ +<?php readfile("/etc/passwd"); ?> diff --git a/debian/perl-framework/t/htdocs/php/safemode/system.php b/debian/perl-framework/t/htdocs/php/safemode/system.php new file mode 100644 index 0000000..62be01a --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/safemode/system.php @@ -0,0 +1,2 @@ +<?php system("printf HelloWorld"); ?> + diff --git a/debian/perl-framework/t/htdocs/php/stack.php b/debian/perl-framework/t/htdocs/php/stack.php new file mode 100644 index 0000000..04c3198 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/stack.php @@ -0,0 +1,13 @@ +<?php +old_function F ( + if(1): + return("Hello"); + endif; +); + +$i=0; +while($i<2): + echo F(); + $i++; +endwhile; +?> diff --git a/debian/perl-framework/t/htdocs/php/status.php b/debian/perl-framework/t/htdocs/php/status.php new file mode 100644 index 0000000..221aa2f --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/status.php @@ -0,0 +1,5 @@ +<?php +$rc = $_GET['code']; +header("HTTP/1.1 $rc Custom Status"); +flush(); +?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/strings.php b/debian/perl-framework/t/htdocs/php/strings.php new file mode 100644 index 0000000..f0febb9 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/strings.php @@ -0,0 +1 @@ +<?php echo "\"\t\\'" . '\n\\\'a\\\b\\' ?> diff --git a/debian/perl-framework/t/htdocs/php/strings2.php b/debian/perl-framework/t/htdocs/php/strings2.php new file mode 100644 index 0000000..ec10f4b --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/strings2.php @@ -0,0 +1,187 @@ +<?php + +error_reporting(0); + +echo "Testing strtok: "; + +$str = "testing 1/2\\3"; +$tok1 = strtok($str, " "); +$tok2 = strtok("/"); +$tok3 = strtok("\\"); +$tok4 = strtok("."); +if ($tok1 != "testing") { + echo("failed 1\n"); +} elseif ($tok2 != "1") { + echo("failed 2\n"); +} elseif ($tok3 != "2") { + echo("failed 3\n"); +} elseif ($tok4 != "3") { + echo("failed 4\n"); +} else { + echo("passed\n"); +} + +echo "Testing strstr: "; +$test = "This is a test"; +$found1 = strstr($test, 32); +$found2 = strstr($test, "a "); +if ($found1 != " is a test") { + echo("failed 1\n"); +} elseif ($found2 != "a test") { + echo("failed 2\n"); +} else { + echo("passed\n"); +} + +echo "Testing strrchr: "; +$test = "fola fola blakken"; +$found1 = strrchr($test, "b"); +$found2 = strrchr($test, 102); +if ($found1 != "blakken") { + echo("failed 1\n"); +} elseif ($found2 != "fola blakken") { + echo("failed 2\n"); +} +else { + echo("passed\n"); +} + +echo "Testing strtoupper: "; +$test = "abCdEfg"; +$upper = strtoupper($test); +if ($upper == "ABCDEFG") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing strtolower: "; +$test = "ABcDeFG"; +$lower = strtolower($test); +if ($lower == "abcdefg") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing substr: "; +$tests = $ok = 0; +$string = "string12345"; +$tests++; if (substr($string, 2, 10) == "ring12345") { $ok++; } +$tests++; if (substr($string, 4, 7) == "ng12345") { $ok++; } +$tests++; if (substr($string, 4) == "ng12345") { $ok++; } +$tests++; if (substr($string, 10, 2) == "5") { $ok++; } +$tests++; if (substr($string, 6, 0) == "") { $ok++; } +$tests++; if (substr($string, -2, 2) == "45") { $ok++; } +$tests++; if (substr($string, 1, -1) == "tring1234") { $ok++; } +$tests++; if (substr($string, -1, -2) == "") { $ok++; } +$tests++; if (substr($string, -3, -2) == "3") { $ok++; } + +if ($tests == $ok) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +$raw = ' !"#$%&\'()*+,-./0123456789:;<=>?' + . '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_' + . '`abcdefghijklmnopqrstuvwxyz{|}~' + . "\0"; + +echo "Testing rawurlencode: "; +$encoded = rawurlencode($raw); +$correct = '%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F' + . '%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_' + . '%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~' + . '%00'; +if ($encoded == $correct) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing rawurldecode: "; +$decoded = rawurldecode($correct); +if ($decoded == $raw) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing urlencode: "; +$encoded = urlencode($raw); +$correct = '+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F' + . '%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_' + . '%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E' + . '%00'; +if ($encoded == $correct) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing urldecode: "; +$decoded = urldecode($correct); +if ($decoded == $raw) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing quotemeta: "; +$raw = "a.\\+*?" . chr(91) . "^" . chr(93) . "b\$c"; +$quoted = quotemeta($raw); +if ($quoted == "a\\.\\\\\\+\\*\\?\\[\\^\\]b\\\$c") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing ufirst: "; +$str = "fahrvergnuegen"; +$uc = ucfirst($str); +if ($uc == "Fahrvergnuegen") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing strtr: "; +$str = "test abcdefgh"; +$tr = strtr($str, "def", "456"); +if ($tr == "t5st abc456gh") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing addslashes: "; +$str = "\"\\'"; +$as = addslashes($str); +if ($as == "\\\"\\\\\\'") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing stripslashes: "; +$str = "\$\\'"; +$ss = stripslashes($str); +if ($ss == "\$'") { + echo("passed\n"); +} else { + echo("failed!\n"); +} + + +echo "Testing uniqid: "; +$str = "prefix"; +$ui1 = uniqid($str); +$ui2 = uniqid($str); +if (strlen($ui1) == strlen($ui2) && strlen($ui1) == 19 && $ui1 != $ui2) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +?> diff --git a/debian/perl-framework/t/htdocs/php/strings3.php b/debian/perl-framework/t/htdocs/php/strings3.php new file mode 100644 index 0000000..e07ac2a --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/strings3.php @@ -0,0 +1,37 @@ +<?php + +error_reporting(0); + +printf("printf test 1:%s\n", "simple string"); +printf("printf test 2:%d\n", 42); +printf("printf test 3:%f\n", 10.0/3); +printf("printf test 4:%.10f\n", 10.0/3); +printf("printf test 5:%-10.2f\n", 2.5); +printf("printf test 6:%-010.2f\n", 2.5); +printf("printf test 7:%010.2f\n", 2.5); +printf("printf test 8:<%20s>\n", "foo"); +printf("printf test 9:<%-20s>\n", "bar"); +printf("printf test 10: 123456789012345\n"); +printf("printf test 10:<%15s>\n", "høyesterettsjustitiarius"); +printf("printf test 11: 123456789012345678901234567890\n"); +printf("printf test 11:<%30s>\n", "høyesterettsjustitiarius"); +printf("printf test 12:%5.2f\n", -12.34); +printf("printf test 13:%5d\n", -12); +printf("printf test 14:%c\n", 64); +printf("printf test 15:%b\n", 170); +printf("printf test 16:%x\n", 170); +printf("printf test 17:%X\n", 170); +printf("printf test 18:%16b\n", 170); +printf("printf test 19:%16x\n", 170); +printf("printf test 20:%16X\n", 170); +printf("printf test 21:%016b\n", 170); +printf("printf test 22:%016x\n", 170); +printf("printf test 23:%016X\n", 170); +printf("printf test 24:%.5s\n", "abcdefghij"); +printf("printf test 25:%-2s\n", "gazonk"); +printf("printf test 26:%2\$d %1\$d\n", 1, 2); +printf("printf test 27:%3\$d %d %d\n", 1, 2, 3); +printf("printf test 28:%2\$02d %1\$2d\n", 1, 2); +printf("printf test 29:%2\$-2d %1\$2d\n", 1, 2); + +?> diff --git a/debian/perl-framework/t/htdocs/php/strings4.php b/debian/perl-framework/t/htdocs/php/strings4.php new file mode 100644 index 0000000..e928920 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/strings4.php @@ -0,0 +1,5 @@ +<?php +setlocale (LC_CTYPE, "C"); +echo htmlspecialchars ("<>\"&åÄ\n", ENT_COMPAT, "ISO-8859-1"); +echo htmlentities ("<>\"&åÄ\n", ENT_COMPAT, "ISO-8859-1"); +?> diff --git a/debian/perl-framework/t/htdocs/php/subtract.php b/debian/perl-framework/t/htdocs/php/subtract.php new file mode 100644 index 0000000..acf18f4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/subtract.php @@ -0,0 +1 @@ +<?php $a=27; $b=7; $c=10; $d=$a-$b-$c; echo $d?> diff --git a/debian/perl-framework/t/htdocs/php/switch.php b/debian/perl-framework/t/htdocs/php/switch.php new file mode 100644 index 0000000..7f601c0 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/switch.php @@ -0,0 +1,13 @@ +<?php $a=1; + switch($a): + case 0; + echo "bad"; + break; + case 1; + echo "good"; + break; + default; + echo "bad"; + break; + endswitch?> + diff --git a/debian/perl-framework/t/htdocs/php/switch2.php b/debian/perl-framework/t/htdocs/php/switch2.php new file mode 100644 index 0000000..2cf3288 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/switch2.php @@ -0,0 +1,42 @@ +<?php + +$i="abc"; + +for ($j=0; $j<10; $j++) { +switch (1) { + case 1: + echo "In branch 1\n"; + switch ($i) { + case "ab": + echo "This doesn't work... :(\n"; + break; + case "abcd": + echo "This works!\n"; + break; + case "blah": + echo "Hmmm, no worki\n"; + break; + default: + echo "Inner default...\n"; + } + for ($blah=0; $blah<200; $blah++) { + if ($blah==100) { + echo "blah=$blah\n"; + } + } + break; + case 2: + echo "In branch 2\n"; + break; + case $i: + echo "In branch \$i\n"; + break; + case 4: + echo "In branch 4\n"; + break; + default: + echo "Hi, I'm default\n"; + break; + } +} +?> diff --git a/debian/perl-framework/t/htdocs/php/switch3.php b/debian/perl-framework/t/htdocs/php/switch3.php new file mode 100644 index 0000000..ac6c790 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/switch3.php @@ -0,0 +1,29 @@ +<?php + +for ($i=0; $i<=5; $i++) +{ + echo "i=$i\n"; + + switch($i) { + case 0: + echo "In branch 0\n"; + break; + case 1: + echo "In branch 1\n"; + break; + case 2: + echo "In branch 2\n"; + break; + case 3: + echo "In branch 3\n"; + break 2; + case 4: + echo "In branch 4\n"; + break; + default: + echo "In default\n"; + break; + } +} +echo "hi\n"; +?> diff --git a/debian/perl-framework/t/htdocs/php/switch4.php b/debian/perl-framework/t/htdocs/php/switch4.php new file mode 100644 index 0000000..24fb51f --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/switch4.php @@ -0,0 +1,29 @@ +<?php + +function switchtest ($i, $j) +{ + switch ($i): + case 0: + switch($j) { + case 0: + echo "zero"; + break; + case 1: + echo "one"; + break; + default: + echo $j; + break; + } + echo "\n"; + break; + default: + echo "Default taken\n"; + endswitch; +} +for ($i=0; $i<3; $i++) { + for ($k=0; $k<10; $k++) { + switchtest (0,$k); + } +} +?> diff --git a/debian/perl-framework/t/htdocs/php/target.php b/debian/perl-framework/t/htdocs/php/target.php new file mode 100644 index 0000000..fb17bd7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/target.php @@ -0,0 +1 @@ +<?php echo "target.php"; ?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/test-fpm.php b/debian/perl-framework/t/htdocs/php/test-fpm.php new file mode 100644 index 0000000..ccce0c3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/test-fpm.php @@ -0,0 +1 @@ +<?php var_export($_SERVER)?> diff --git a/debian/perl-framework/t/htdocs/php/umask.php b/debian/perl-framework/t/htdocs/php/umask.php new file mode 100644 index 0000000..ee36d53 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/umask.php @@ -0,0 +1 @@ +<? print umask(000); ?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/php/var1.php b/debian/perl-framework/t/htdocs/php/var1.php new file mode 100644 index 0000000..45741f5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/var1.php @@ -0,0 +1,12 @@ +<?php + switch ($_SERVER["REQUEST_METHOD"]) { + case "GET": + echo $_GET["variable"]; + break; + case "POST": + echo $_POST["variable"]; + break; + default: + echo "ERROR!"; + } +?> diff --git a/debian/perl-framework/t/htdocs/php/var2.php b/debian/perl-framework/t/htdocs/php/var2.php new file mode 100644 index 0000000..028e466 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/var2.php @@ -0,0 +1,14 @@ +<?php + switch ($_SERVER["REQUEST_METHOD"]) { + case "GET": + echo join(" ", array($_GET["v1"], + $_GET["v2"])); + break; + case "POST": + echo join(" ", array($_POST["v1"], + $_POST["v2"])); + break; + default: + echo "ERROR!"; + } +?> diff --git a/debian/perl-framework/t/htdocs/php/var3.php b/debian/perl-framework/t/htdocs/php/var3.php new file mode 100644 index 0000000..7e25163 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/var3.php @@ -0,0 +1,16 @@ +<?php + switch ($_SERVER["REQUEST_METHOD"]) { + case "GET": + echo join(" ", array($_GET["v1"], + $_GET["v2"], + $_GET["v3"])); + break; + case "POST": + echo join(" ", array($_POST["v1"], + $_POST["v2"], + $_POST["v3"])); + break; + default: + echo "ERROR!"; + } +?> diff --git a/debian/perl-framework/t/htdocs/php/var3u.php b/debian/perl-framework/t/htdocs/php/var3u.php new file mode 100644 index 0000000..1f90040 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/var3u.php @@ -0,0 +1 @@ +<?php echo "$V1 $V2 $V3"?> diff --git a/debian/perl-framework/t/htdocs/php/virtual.php b/debian/perl-framework/t/htdocs/php/virtual.php new file mode 100644 index 0000000..0d150d4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/virtual.php @@ -0,0 +1 @@ +before <?php virtual("multiviews/file"); ?> after diff --git a/debian/perl-framework/t/htdocs/php/while.php b/debian/perl-framework/t/htdocs/php/while.php new file mode 100644 index 0000000..7313b51 --- /dev/null +++ b/debian/perl-framework/t/htdocs/php/while.php @@ -0,0 +1,5 @@ +<?php $a=1; + while($a<10): + echo $a; + $a++; + endwhile?> diff --git a/debian/perl-framework/t/htdocs/security/CAN-2003-0542/.htaccess b/debian/perl-framework/t/htdocs/security/CAN-2003-0542/.htaccess new file mode 100644 index 0000000..35a74ec --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2003-0542/.htaccess @@ -0,0 +1,3 @@ +RewriteEngine On +RewriteRule ((((((((((((((((((((((.*)))))))))))))))))))))) - + diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0747/.htaccess b/debian/perl-framework/t/htdocs/security/CAN-2004-0747/.htaccess new file mode 100644 index 0000000..34092fa --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0747/.htaccess @@ -0,0 +1,2 @@ +# trigger the ap_resolve_env overflow +AuthName ${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH}${PATH} diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0747/index.html b/debian/perl-framework/t/htdocs/security/CAN-2004-0747/index.html new file mode 100644 index 0000000..3b452c3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0747/index.html @@ -0,0 +1 @@ +ap_resolve_env is good diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0811/.htaccess b/debian/perl-framework/t/htdocs/security/CAN-2004-0811/.htaccess new file mode 100644 index 0000000..59d9ffb --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0811/.htaccess @@ -0,0 +1,3 @@ +AuthType Basic +AuthName authany +require valid-user diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0811/index.html b/debian/perl-framework/t/htdocs/security/CAN-2004-0811/index.html new file mode 100644 index 0000000..c6cac69 --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0811/index.html @@ -0,0 +1 @@ +empty diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0811/sub/index.html b/debian/perl-framework/t/htdocs/security/CAN-2004-0811/sub/index.html new file mode 100644 index 0000000..c6cac69 --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0811/sub/index.html @@ -0,0 +1 @@ +empty diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0940.shtml b/debian/perl-framework/t/htdocs/security/CAN-2004-0940.shtml new file mode 100644 index 0000000..a06b7bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0940.shtml @@ -0,0 +1 @@ +<!--#echo var="ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab\aWAVEGOODBYETOYOURSTACKSCRIBBLESCRIBBLESCRIBBLE"--> diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0958.php b/debian/perl-framework/t/htdocs/security/CAN-2004-0958.php new file mode 100644 index 0000000..b328c31 --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0958.php @@ -0,0 +1 @@ +<?php print_r($_REQUEST); ?> diff --git a/debian/perl-framework/t/htdocs/security/CAN-2004-0959.php b/debian/perl-framework/t/htdocs/security/CAN-2004-0959.php new file mode 100644 index 0000000..0f36526 --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2004-0959.php @@ -0,0 +1,7 @@ +<?php + if (is_uploaded_file($_FILES['user_file']['tmp_name'])) { + print $_FILES['user_file']['name']; + } else { + print "FAILED"; + } +?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/security/CAN-2005-2491/one/.htaccess b/debian/perl-framework/t/htdocs/security/CAN-2005-2491/one/.htaccess new file mode 100644 index 0000000..608feba --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2005-2491/one/.htaccess @@ -0,0 +1 @@ +RewriteRule a{111111111111111111} /index.html diff --git a/debian/perl-framework/t/htdocs/security/CAN-2005-2491/two/.htaccess b/debian/perl-framework/t/htdocs/security/CAN-2005-2491/two/.htaccess new file mode 100644 index 0000000..67c62ab --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CAN-2005-2491/two/.htaccess @@ -0,0 +1 @@ +RewriteRule a{1,11111111111111111111} /index.html diff --git a/debian/perl-framework/t/htdocs/security/CVE-2005-3352.map b/debian/perl-framework/t/htdocs/security/CVE-2005-3352.map new file mode 100644 index 0000000..e867af4 --- /dev/null +++ b/debian/perl-framework/t/htdocs/security/CVE-2005-3352.map @@ -0,0 +1 @@ +default referer "Go Back" diff --git a/debian/perl-framework/t/htdocs/servlet/mapping.html b/debian/perl-framework/t/htdocs/servlet/mapping.html new file mode 100644 index 0000000..f0b7bc7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/servlet/mapping.html @@ -0,0 +1 @@ +hello servlet diff --git a/debian/perl-framework/t/http11/all.t b/debian/perl-framework/t/http11/all.t new file mode 100644 index 0000000..549cf64 --- /dev/null +++ b/debian/perl-framework/t/http11/all.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::TestRequest; +use Apache::Test; + +#skip all tests in this directory unless we have client http/1.1 support +plan tests => 1, \&need_http11; + +ok 1; diff --git a/debian/perl-framework/t/http11/basicauth.t b/debian/perl-framework/t/http11/basicauth.t new file mode 100644 index 0000000..1bd91dc --- /dev/null +++ b/debian/perl-framework/t/http11/basicauth.t @@ -0,0 +1,32 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +#test basic auth with keepalives + +Apache::TestRequest::user_agent(keep_alive => 1); + +Apache::TestRequest::scheme('http') + unless have_module 'LWP::Protocol::https10'; #lwp 5.60 + +plan tests => 3, need_module 'authany'; + +my $url = '/authany/index.html'; + +my $res = GET $url; + +ok $res->code == 401; + +$res = GET $url, username => 'guest', password => 'guest'; + +ok $res->code == 200; + +my $request_num = Apache::TestRequest::user_agent_request_num($res); + +ok $request_num == 3; #1 => no credentials + #2 => 401 response with second request + #3 => 200 with guest/guest credentials + + diff --git a/debian/perl-framework/t/http11/chunked.t b/debian/perl-framework/t/http11/chunked.t new file mode 100644 index 0000000..2331239 --- /dev/null +++ b/debian/perl-framework/t/http11/chunked.t @@ -0,0 +1,133 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +Apache::TestRequest::user_agent(keep_alive => 1); + +Apache::TestRequest::scheme('http') + unless have_module 'LWP::Protocol::https10'; #lwp 5.60 + +#In httpd-2.0, chunked encoding is optional and will only be used +#if response is > 4*AP_MIN_BYTES_TO_WRITE (see server/protocol.c) + +my @small_sizes = (100, 5000); +my @chunk_sizes = (25432, 75962, 100_000, 300_000); + +my $tests = (@chunk_sizes + @small_sizes) * 5; + +if (! have_module 'random_chunk') { + print "# Skipping; missing prerequisite module 'random_chunk'\n"; +} +plan tests => $tests, need_module 'random_chunk'; + +my $location = '/random_chunk'; +my $requests = 0; + +sub expect_chunked { + my $size = shift; + sok sub { + my $res = GET "/random_chunk?0,$size"; + my $body = $res->content; + my $length = 0; + + if ($body =~ s/__END__:(\d+)$//) { + $length = $1; + } + + ok t_cmp($res->protocol, + "HTTP/1.1", + "response protocol" + ); + + my $enc = $res->header('Transfer-Encoding') || + $res->header('Client-Transfer-Encoding') || #lwp 5.61+ + ''; + my $ct = $res->header('Content-Length') || 0; + + ok t_cmp($enc, + "chunked", + "response Transfer-Encoding" + ); + + ok t_cmp($ct, + 0, + "no Content-Length" + ); + + ok t_cmp(length($body), + $length, + "body length" + ); + + $requests++; + my $request_num = + Apache::TestRequest::user_agent_request_num($res); + + return t_cmp($request_num, + $requests, + "number of requests" + ); + }, 5; +} + +sub expect_not_chunked { + my $size = shift; + sok sub { + my $res = GET "/random_chunk?0,$size"; + my $body = $res->content; + my $content_length = length $res->content; + my $length = 0; + + if ($body =~ s/__END__:(\d+)$//) { + $length = $1; + } + + ok t_cmp($res->protocol, + "HTTP/1.1", + "response protocol" + ); + + my $enc = $res->header('Transfer-Encoding') || ''; + my $ct = $res->header('Content-Length') || ''; + + ok !t_cmp($enc, + "chunked", + "no Transfer-Encoding (test result inverted)" + ); + + ok t_cmp($ct, + (($ct eq '') ? $ct : $content_length), + "content length" + ); + + ok t_cmp(length($body), + $length, + "body length" + ); + + $requests++; + my $request_num = + Apache::TestRequest::user_agent_request_num($res); + + return t_cmp($request_num, + $requests, + "number of requests" + ); + }, 5; +} + +for my $size (@chunk_sizes) { + expect_chunked $size; +} + +for my $size (@small_sizes) { + if (have_apache 1) { + expect_chunked $size; + } + else { + expect_not_chunked $size; + } +} diff --git a/debian/perl-framework/t/http11/chunked2.t b/debian/perl-framework/t/http11/chunked2.t new file mode 100644 index 0000000..02ec212 --- /dev/null +++ b/debian/perl-framework/t/http11/chunked2.t @@ -0,0 +1,18 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2, need 'bucketeer'; + +Apache::TestRequest::user_agent(keep_alive => 1); + +# Regression test for ap_http_chunk_filter bug. + +my $r = GET("/apache/chunked/flush.html"); + +ok t_cmp($r->code, 200, "successful response"); + +ok t_cmp($r->content, "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbb"); diff --git a/debian/perl-framework/t/http11/clength.t b/debian/perl-framework/t/http11/clength.t new file mode 100644 index 0000000..14254f8 --- /dev/null +++ b/debian/perl-framework/t/http11/clength.t @@ -0,0 +1,27 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my %tests = ( + "/foobar.html" => "foobar", + # flushheap0 inserts a single FLUSH bucket after the content, before EOS + "/apache/chunked/flushheap0.html" => "bbbbbbbbbb", + ); + +plan tests => 3*scalar keys %tests, need 'bucketeer'; + +Apache::TestRequest::user_agent(keep_alive => 1); + +foreach my $path (sort keys %tests) { + my $expected = $tests{$path}; + my $r = GET($path); + + ok t_cmp($r->code, 200, "successful response"); + + ok t_cmp($r->header("Content-Length"), length $expected); + + ok t_cmp($r->content, $expected); +} diff --git a/debian/perl-framework/t/http11/post.t b/debian/perl-framework/t/http11/post.t new file mode 100644 index 0000000..3610e5c --- /dev/null +++ b/debian/perl-framework/t/http11/post.t @@ -0,0 +1,17 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestCommon (); + +local $ENV{APACHE_TEST_HTTP11} = 1; + +#same as t/apache/post but turn on HTTP/1.1 +Apache::TestRequest::user_agent(keep_alive => 1); + +my $module = 'eat_post'; +my $num = Apache::TestCommon::run_post_test_sizes(); + +plan tests => $num, [$module]; + +Apache::TestCommon::run_post_test($module); diff --git a/debian/perl-framework/t/modules/aaa.t b/debian/perl-framework/t/modules/aaa.t new file mode 100644 index 0000000..ffccec0 --- /dev/null +++ b/debian/perl-framework/t/modules/aaa.t @@ -0,0 +1,257 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); +use File::Spec; + +# test the possibility of doing authz by user id or envvar in conjunction +# with the different AuthTypes + +Apache::TestRequest::user_agent(keep_alive => 1); + +my @headers = qw(WWW-Authenticate Authentication-Info Location); + +my %do_tests = ( basic => 11, + digest => 11, + form => 16, + ); + +my $tests = 2; # AuthzSendForbiddenOnFailure tests +foreach my $t (keys %do_tests) { + $tests += $do_tests{$t}; +} + +plan tests => $tests, + need need_lwp, + need_module('mod_authn_core'), + need_module('mod_authz_core'), + need_module('mod_authn_file'), + need_module('mod_authz_host'), + need_min_apache_version('2.3.7'); + +foreach my $t (sort keys %do_tests) { + if (!have_module("mod_auth_$t")) { + skip("skipping mod_auth_$t tests") for (1 .. $do_tests{$t}); + delete $do_tests{$t}; + } +} + +write_htpasswd(); + +# the auth type we are currently testing +my $type; + +foreach my $t (qw/basic digest/) { + next unless exists $do_tests{$t}; + $type = $t; + my $url = "/authz/$type/index.html"; + + { + my $response = GET $url; + + ok($response->code, + 401, + "$type: no user to authenticate and no env to authorize"); + } + + { + # bad pass + my $response = GET $url, + username => "u$type", password => 'foo'; + + ok($response->code, + 401, + "$type: u$type:foo not found"); + } + + { + # authenticated + my $response = GET $url, + username => "u$type", password => "p$type"; + + ok($response->code, + 200, + "$type: u$type:p$type found"); + } + + { + # authorized by env + my $response = GET $url, 'X-Allowed' => 'yes'; + + ok($response->code, + 200, + "$type: authz by envvar"); + + check_headers($response, 200); + } + + { + # authorized by env / with error + my $response = GET "$url.foo", 'X-Allowed' => 'yes'; + + ok($response->code, + 404, + "$type: not found"); + + check_headers($response, 404); + } +} + +# +# Form based authentication works a bit differently +# +if (exists $do_tests{form} && !have_module("mod_session_cookie")) { + skip("skipping mod_auth_form tests (mod_session_cookie required)") + for (1 .. $do_tests{form}); +} +elsif (exists $do_tests{form}) { + $type = 'form'; + my $url = "/authz/$type/index.html"; + my $login_form_url='/authz/login.html'; + my $login_url='/authz/form/dologin.html'; + + my @params = ( reset => 1, cookie_jar => {}, requests_redirectable => 0 ); + Apache::TestRequest::user_agent(@params); + + { + my $response = GET $url; + + ok($response->code, + 302, + "$type: access without user/env should redirect with 302"); + + my $loc = $response->header("Location"); + if (defined $loc && $loc =~ m{^http://[^/]+(/.*)$}) { + $loc = $1; + } + ok($loc, + "/authz/login.html", + "form: login without user/env should redirect to login form"); + } + + { + Apache::TestRequest::user_agent(@params); + # bad pass + my $response = POST $login_url, + content => "httpd_username=uform&httpd_password=foo"; + ok($response->code, + 302, + "form: login with wrong passwd should redirect with 302"); + + my $loc = $response->header("Location"); + if (defined $loc && $loc =~ m{^http://[^/]+(/.*)$}) { + $loc = $1; + } + ok($loc, + "/authz/login.html", + "form: login with wrong passwd should redirect to login form"); + + $response = GET $url; + ok($response->code, + 302, + "$type: wrong passwd should not allow access"); + } + + { + # authenticated + Apache::TestRequest::user_agent(@params); + my $response = POST $login_url, + content => "httpd_username=uform&httpd_password=pform"; + ok($response->code, + 302, + "form: login with correct passwd should redirect with 302"); + + my $loc = $response->header("Location"); + if (defined $loc && $loc =~ m{^http://[^/]+(/.*)$}) { + $loc = $1; + } + ok($1, + "/authz/form/", + "form: login with correct passwd should redirect to SuccessLocation"); + + $response = GET $url; + ok($response->code, + 200, + "$type: correct passwd did not allow access"); + } + + { + # authorized by env + Apache::TestRequest::user_agent(@params); + my $response = GET $url, 'X-Allowed' => 'yes'; + + ok($response->code, + 200, + "$type: authz by envvar"); + + check_headers($response, 200); + } + + { + # authorized by env / with error + my $response = GET "$url.foo", 'X-Allowed' => 'yes'; + + ok($response->code, + 404, + "$type: not found"); + + check_headers($response, 404); + } +} + +# +# Test AuthzSendForbiddenOnFailure +# +if (have_min_apache_version("2.3.11")) { + foreach my $want (401, 403) { + my $response = GET "/authz/fail/$want", + username => "ubasic", + password => "pbasic"; + my $got = $response->code; + ok($got, $want, "Expected code $want, got $got"); + } +} +else { + skip "skipping tests with httpd <2.3.11" foreach (1..2); +} + +# +# check that none of the authentication related headers exists +# +sub check_headers +{ + my $response = shift; + my $code = shift; + + foreach my $h (@headers) { + ok($response->header($h), + undef, + "$type: $code response should have no $h header"); + } +} + +# +# write out the htpasswd files +# +sub write_htpasswd +{ + my $digest_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'realm2'); + t_write_file($digest_file, << 'EOF' ); +# udigest/pdigest +udigest:realm2:bccffb0d42943019acfbebf2039b8a3a +EOF + + my $basic_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'basic1'); + t_write_file($basic_file, << 'EOF' ); +# ubasic:pbasic +ubasic:$apr1$opONH1Fj$dX0sZdZ0rRWEk0Wj8y.Qv1 +EOF + + my $form_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'form1'); + t_write_file($form_file, << 'EOF' ); +# uform:pform +uform:$apr1$BzhDZ03D$U598kbSXGy/R7OhYXu.JJ0 +EOF +} diff --git a/debian/perl-framework/t/modules/access.t b/debian/perl-framework/t/modules/access.t new file mode 100644 index 0000000..0c8e34e --- /dev/null +++ b/debian/perl-framework/t/modules/access.t @@ -0,0 +1,191 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## +## mod_access test +## + +my $vars = Apache::Test::vars(); +my $localhost_name = $vars->{servername}; +my $remote_addr = $vars->{remote_addr}; +my(@addr) = split /\./, $remote_addr; +my $addr1 = $addr[0]; +my $addr2 = join '.', $addr[0], $addr[1]; + +my @localhost = ( + 'from all', + "from $localhost_name", + "from $remote_addr", + "from $addr2", + "from $remote_addr/255.255.0.0", + "from $remote_addr/16", + 'from somewhere.else.com', + 'from 66.6.6.6' +); +my @order = ('deny,allow', 'allow,deny', 'mutual-failure'); +my @allow = @localhost; +my @deny = @localhost; + +plan tests => (@order * @allow * @deny * 2) + (@order * @allow), \&need_access; + +my $dir = $vars->{t_dir}; +$dir .= "/htdocs/modules/access/htaccess"; + +sub write_htaccess { + my $conf_str = shift; + open (HT, ">$dir/.htaccess") or die "cant open htaccess: $!"; + print HT $conf_str; + close (HT); +} + +my ($config_string, $ok); +foreach my $order (@order) { + foreach my $allow (@allow) { + $config_string = "Order $order\nAllow $allow\n"; + write_htaccess($config_string); + + t_debug "---", $config_string; + + if ($order eq 'deny,allow') { + + ## if allowing by default, + ## there is no 'Deny' directive, so everything + ## is allowed. + t_debug "expecting access."; + ok GET_OK "/modules/access/htaccess/index.html"; + + + } else { + + ## denying by default + + if ($allow =~ /^from $addr1/ + || $allow eq "from $localhost_name" + || $allow eq 'from all') { + + ## if we are explicitly allowed, its ok + t_debug "expecting access."; + ok GET_OK "/modules/access/htaccess/index.html"; + + } else { + + ## otherwise, not ok + t_debug "expecting access denial."; + ok !GET_OK "/modules/access/htaccess/index.html"; + } + } + + + foreach my $deny (@deny) { + $config_string = "Order $order\nDeny $deny\n"; + write_htaccess($config_string); + + t_debug "---", $config_string; + + if ($order eq 'deny,allow') { + + ## allowing by default + + if ($deny =~ /^from $addr1/ + || $deny eq "from $localhost_name" + || $deny eq 'from all') { + + ## if we are denied explicitly + ## its not ok + t_debug "expecting access denial."; + ok !GET_OK "/modules/access/htaccess/index.html"; + + } else { + + ## otherwise, ok + t_debug "expecting access."; + ok GET_OK "/modules/access/htaccess/index.html"; + + } + } else { + + ## if denying by default + ## there is no 'Allow' directive, so + ## everything is denied. + t_debug "expecting access denial."; + ok !GET_OK "/modules/access/htaccess/index.html"; + + } + + $config_string = "Order $order\nAllow $allow\nDeny $deny\n"; + write_htaccess($config_string); + + t_debug "---", $config_string; + + if ($order eq 'deny,allow') { + + ## allowing by default + + if ($allow =~ /^from $addr1/ + || $allow eq "from $localhost_name" + || $allow eq 'from all') { + + ## we are explicitly allowed + ## so it is ok. + t_debug "expecting access."; + ok GET_OK "/modules/access/htaccess/index.html"; + + } elsif ($deny =~ /^from $addr1/ + || $deny eq "from $localhost_name" + || $deny eq 'from all') { + + ## if we are not explicitly allowed + ## and are explicitly denied, + ## we are denied access. + t_debug "expecting access denial."; + ok !GET_OK "/modules/access/htaccess/index.html"; + + } else { + + ## if we are not explicity allowed + ## or explicitly denied, + ## we get access. + t_debug "expecting access."; + ok GET_OK "/modules/access/htaccess/index.html"; + + } + } else { + + ## denying by default + + if ($deny =~ /^from $addr1/ + || $deny eq "from $localhost_name" + || $deny eq 'from all') { + + ## if we are explicitly denied, + ## we get no access. + t_debug "expecting access denial."; + ok !GET_OK "/modules/access/htaccess/index.html"; + + } elsif ($allow =~ /^from $addr1/ + || $allow eq "from $localhost_name" + || $allow eq 'from all') { + + ## if we are not explicitly denied + ## and are explicitly allowed, + ## we get access. + t_debug "expecting access."; + ok GET_OK "/modules/access/htaccess/index.html"; + + } else { + + ## if we are not explicitly denied + ## and not explicitly allowed, + ## we get no access. + t_debug "expecting access denial."; + ok !GET_OK "/modules/access/htaccess/index.html"; + + } + } + } + } +} diff --git a/debian/perl-framework/t/modules/actions.t b/debian/perl-framework/t/modules/actions.t new file mode 100644 index 0000000..337d4d8 --- /dev/null +++ b/debian/perl-framework/t/modules/actions.t @@ -0,0 +1,59 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## +## mod_action tests +## +my @tests_action = ( + [ "mod_actions/", 200, "nada"], # Handler for this location + + [ "modules/actions/action/test.xyz", 404], # No handler for .xyz + [ "modules/actions/action/test.xyz1", 404], # Handler for .xyz1, but not virtual + [ "modules/actions/action/test.xyz22", 404], # No Handler for .xyz2x (but one for .xyz2) + + [ "modules/actions/action/test.xyz2", 200, "nada"], # Handler for .xyz2, and virtual +); + +my @tests_script = ( + [ "modules/actions/script/test.x", 404], + [ "modules/actions/script/test.x?foo=bar", 200, "foo=bar"], +); + +my $r; + +plan tests => scalar @tests_action*2 + scalar @tests_script*(2+2+1), need_module('mod_actions'); + +foreach my $test (@tests_action) { + $r = GET($test->[0]); + ok t_cmp($r->code, $test->[1]); + if ($test->[1] == 200) { + ok t_cmp($r->content, $test->[2]); + } + else { + skip "RC=404, no need to check content", 1; + } +} + +foreach my $test (@tests_script) { + $r = GET($test->[0]); + ok t_cmp($r->code, $test->[1]); + if ($test->[1] == 200) { + ok t_cmp($r->content, $test->[2]); + } + else { + skip "RC=404, no need to check content", 1; + } + + $r = POST($test->[0], content => "foo2=bar2"); + ok t_cmp($r->code, 200); + ok t_cmp($r->content, "POST\nfoo2: bar2\n"); + + # Method not allowed + $r = PUT($test->[0], content => "foo2=bar2"); + ok t_cmp($r->code, 405); +} + diff --git a/debian/perl-framework/t/modules/alias.t b/debian/perl-framework/t/modules/alias.t new file mode 100644 index 0000000..957fccc --- /dev/null +++ b/debian/perl-framework/t/modules/alias.t @@ -0,0 +1,240 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +use constant WINFU => Apache::TestConfig::WINFU(); + +## +## mod_alias test +## + +## redirect codes for Redirect testing ## +my %redirect = ( + perm => '301', + perm2 => '301', + temp => '302', + temp2 => '302', + seeother => '303', + gone => '410', + forbid => '403' +); + +## RedirectMatch testing ## +my %rm_body = ( + p => '301', + t => '302' +); + +my %rm_rc = ( + s => '303', + g => '410', + f => '403' +); + + +my %relative_redirects = ( + "/redirect_relative/default" => "^http", # URL should be absolute + "/redirect_relative/on" => "^/out-on", # URL should be relative + "/redirect_relative/off" => "^http", # URL should be absolute + "/redirect_relative/off/fail" => undef, # 500 due to invalid URL +); + +#XXX: find something that'll on other platforms (/bin/sh aint it) +my $script_tests = WINFU ? 0 : 4 + have_min_apache_version("2.4.19"); + +my $tests = 12 + have_min_apache_version("2.4.19") * 10 + + (keys %redirect) + + (keys %rm_body) * (1 + have_min_apache_version("2.4.19")) * 10 + + (keys %rm_rc) * (1 + have_min_apache_version("2.4.19")) * 10 + + $script_tests; + +if (have_min_apache_version("2.5.1")) { + $tests += (keys %relative_redirects)*2; +} + +#LWP required to follow redirects +plan tests => $tests, need need_module('alias'), need_lwp; + +## simple alias ## +t_debug "verifying simple aliases"; +ok t_cmp((GET_RC "/alias/"), + 200, + "/alias/"); +## alias to a non-existant area ## +ok t_cmp((GET_RC "/bogu/"), + 404, + "/bogu/"); + + +t_debug "verifying alias match with /ali[0-9]."; +for (my $i=0 ; $i <= 9 ; $i++) { + ok t_cmp((GET_BODY "/ali$i"), + $i, + "/ali$i"); +} + +if (have_min_apache_version("2.4.19")) { + t_debug "verifying expression alias match with /expr/ali[0-9]."; + for (my $i=0 ; $i <= 9 ; $i++) { + ok t_cmp((GET_BODY "/expr/ali$i"), + $i, + "/ali$i"); + } +} + +my ($actual, $expected); +foreach (sort keys %redirect) { + ## make LWP not follow the redirect since we + ## are just interested in the return code. + local $Apache::TestRequest::RedirectOK = 0; + + $expected = $redirect{$_}; + $actual = GET_RC "/$_"; + ok t_cmp($actual, + $expected, + "/$_"); +} + +print "verifying body of perm and temp redirect match\n"; +foreach (sort keys %rm_body) { + for (my $i=0 ; $i <= 9 ; $i++) { + $expected = $i; + $actual = GET_BODY "/$_$i"; + ok t_cmp($actual, + $expected, + "/$_$i"); + } +} + +if (have_min_apache_version("2.4.19")) { + print "verifying body of perm and temp redirect match with expression support\n"; + foreach (sort keys %rm_body) { + for (my $i=0 ; $i <= 9 ; $i++) { + $expected = $i; + $actual = GET_BODY "/expr/$_$i"; + ok t_cmp($actual, + $expected, + "/$_$i"); + } + } +} + +print "verifying return code of seeother and gone redirect match\n"; +foreach (keys %rm_rc) { + ## make LWP not follow the redirect since we + ## are just interested in the return code. + local $Apache::TestRequest::RedirectOK = 0; + + $expected = $rm_rc{$_}; + for (my $i=0 ; $i <= 9 ; $i++) { + $actual = GET_RC "$_$i"; + ok t_cmp($actual, + $expected, + "$_$i"); + } +} + +if (have_min_apache_version("2.4.19")) { + print "verifying return code of seeother and gone redirect match with expression support\n"; + foreach (keys %rm_rc) { + ## make LWP not follow the redirect since we + ## are just interested in the return code. + local $Apache::TestRequest::RedirectOK = 0; + + $expected = $rm_rc{$_}; + for (my $i=0 ; $i <= 9 ; $i++) { + $actual = GET_RC "/expr/$_$i"; + ok t_cmp($actual, + $expected, + "$_$i"); + } + } +} + +## create a little cgi to test ScriptAlias and ScriptAliasMatch ## +my $string = "this is a shell script cgi."; +my $cgi =<<EOF; +#!/bin/sh +echo Content-type: text/plain +echo +echo $string +EOF + +my $vars = Apache::Test::vars(); +my $script = "$vars->{t_dir}/htdocs/modules/alias/script"; + +t_write_file($script,$cgi); +chmod 0755, $script; + +## if we get the script here it will be plain text ## +t_debug "verifying /modules/alias/script is plain text"; +ok t_cmp((GET_BODY "/modules/alias/script"), + $cgi, + "/modules/alias/script") unless WINFU; + +if (have_cgi) { + ## here it should be the result of the executed cgi ## + t_debug "verifying same file accessed at /cgi/script is executed code"; + ok t_cmp((GET_BODY "/cgi/script"), + "$string\n", + "/cgi/script") unless WINFU; +} +else { + skip "skipping test without CGI module"; +} + +if (have_cgi) { + ## with ScriptAliasMatch ## + t_debug "verifying ScriptAliasMatch with /aliascgi-script"; + ok t_cmp((GET_BODY "/aliascgi-script"), + "$string\n", + "/aliascgi-script") unless WINFU; +} +else { + skip "skipping test without CGI module"; +} + +if (have_min_apache_version("2.4.19")) { + if (have_cgi) { + ## with ScriptAlias in LocationMatch ## + t_debug "verifying ScriptAlias in LocationMatch with /expr/aliascgi-script"; + ok t_cmp((GET_BODY "/expr/aliascgi-script"), + "$string\n", + "/aliascgi-script") unless WINFU; + } + else { + skip "skipping test without CGI module"; + } +} + +## failure with ScriptAliasMatch ## +t_debug "verifying bad script alias."; +ok t_cmp((GET_RC "/aliascgi-nada"), + 404, + "/aliascgi-nada") unless WINFU; + +## clean up ## +t_rmtree("$vars->{t_logs}/mod_cgi.log"); + + +if (have_min_apache_version("2.5.1")) { + my ($path, $regex); + while (($path, $regex) = each (%relative_redirects)) { + local $Apache::TestRequest::RedirectOK = 0; + my $r; + $r = GET($path); + if (defined($regex)) { + ok t_cmp($r->code, "302"); + ok t_cmp($r->header("Location"), qr/$regex/, "failure on $path"); + } + else { + ok t_cmp($r->code, "500"); + ok t_cmp($r->header("Location"), undef, "failure on $path"); + } + } +} + diff --git a/debian/perl-framework/t/modules/allowmethods.t b/debian/perl-framework/t/modules/allowmethods.t new file mode 100644 index 0000000..d012554 --- /dev/null +++ b/debian/perl-framework/t/modules/allowmethods.t @@ -0,0 +1,64 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $r; +my $get = "Get"; +my $head = "Head"; +my $post = "Post"; +my $options = "Options"; + +## +## mod_allowmethods test +## +my @test_cases = ( + [ $get, $get, 200 ], + [ $head, $get, 200 ], + [ $post, $get, 405 ], + [ $get, $head, 200 ], + [ $head, $head, 200 ], + [ $post, $head, 405 ], + [ $get, $post, 405 ], + [ $head, $post, 405 ], + [ $post, $post, 200 ], +); + +my @new_test_cases = ( + [ $get, $post . '/reset', 200 ], + [ $post, $get . '/post', 200 ], + [ $get, $get . '/post', 200 ], + [ $options, $get . '/post', 405 ], + [ $get, $get . '/none', 405 ], + [ $get, "NoPost", 200 ], + [ $post, "NoPost", 405 ], + [ $options, "NoPost" , 200 ], +); + +if (have_min_apache_version('2.5.1')) { + push(@test_cases, @new_test_cases); +} + +plan tests => (scalar @test_cases), have_module 'allowmethods'; + +foreach my $case (@test_cases) { + my ($fct, $allowed, $rc) = @{$case}; + + if ($fct eq $get) { + $r = GET('/modules/allowmethods/' . $allowed . '/'); + } + elsif ($fct eq $head) { + $r = HEAD('/modules/allowmethods/' . $allowed . '/'); + } + elsif ($fct eq $post) { + $r = POST('/modules/allowmethods/' . $allowed . '/foo.txt'); + } + elsif ($fct eq $options) { + $r = OPTIONS('/modules/allowmethods/' . $allowed . '/'); + } + + ok t_cmp($r->code, $rc, "$fct request to /$allowed responds $rc"); +} + diff --git a/debian/perl-framework/t/modules/asis.t b/debian/perl-framework/t/modules/asis.t new file mode 100644 index 0000000..a8c300e --- /dev/null +++ b/debian/perl-framework/t/modules/asis.t @@ -0,0 +1,21 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## +## mod_asis tests +## + +plan tests => 3, need_module 'asis'; + +my $body = GET_BODY "/modules/asis/foo.asis"; +ok t_cmp($body, "This is asis content.\n", "asis content OK"); + +my $rc = GET_RC "/modules/asis/notfound.asis"; +ok t_cmp($rc, 404, "asis gave 404 error"); + +$rc = GET_RC "/modules/asis/forbid.asis"; +ok t_cmp($rc, 403, "asis gave 403 error"); diff --git a/debian/perl-framework/t/modules/authz_core.t b/debian/perl-framework/t/modules/authz_core.t new file mode 100644 index 0000000..6e43aa3 --- /dev/null +++ b/debian/perl-framework/t/modules/authz_core.t @@ -0,0 +1,360 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); +use File::Spec; + +# test RequireAll/RequireAny containers and AuthzMerging + +plan tests => 168 + 14*24, + need need_lwp, + need_module('mod_authn_core'), + need_module('mod_authz_core'), + need_module('mod_authz_host'), + need_module('mod_authz_groupfile'), + need_min_apache_version('2.3.6'); + + +my $text = ''; + +sub check +{ + my $rc = shift; + my $path = shift; + + my @args; + foreach my $e (@_) { + if ($e =~ /user/) { + push @args, username => $e, password => $e; + } + else { + push @args, "X-Allowed$e" => 'yes'; + } + } + my $res = GET "/authz_core/$path", @args; + my $got = $res->code; + print "# got $got, expected $rc [$text: $path @_]\n"; + ok($got == $rc); +} + +sub write_htaccess +{ + my $path = shift; + my $merging = shift || ""; + my $container = shift || ""; + + $text = "$path $merging $container @_"; + + my $need_auth; + my $content = ""; + $content .= "AuthMerging $merging\n" if $merging; + + if ($container) { + $content .= "<Require$container>\n"; + } + foreach (@_) { + my $req = $_; + my $not = ""; + if ($req =~ s/^\!//) { + $not = 'not'; + } + if ($req =~ /all/) { + $content .= "Require $not $req\n"; + } + elsif ($req =~ /user/) { + # 'group' is correct, see comment about mod_authany below + $content .= "Require $not group $req\n"; + $need_auth = 1; + } + else { + $content .= "Require $not env allowed$req\n"; + } + } + if ($container) { + $content .= "</Require$container>\n"; + } + + if ($need_auth) { + $content .= "AuthType basic\n"; + $content .= "AuthName basic1\n"; + $content .= "AuthUserFile basic1\n"; + $content .= "AuthGroupFile groups1\n"; + } + + my $file = File::Spec->catfile(Apache::Test::vars('documentroot'), + "/authz_core/$path/.htaccess"); + t_write_file($file, $content); +} + +# create some users (username == password) +my $basic_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'basic1'); +t_write_file($basic_file, << 'EOF' ); +user1:NYSYdf7MU5KpU +user2:KJ7Yxzr1VVzAI +user3:xnpSvZ2iqti/c +EOF + +# mod_authany overrides the 'user' provider, so we can't check users directly :-( +# create some groups instead: +my $group_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'groups1'); +t_write_file($group_file, << 'EOF' ); +user1:user1 +user2:user2 +user3:user3 +EOF + +write_htaccess("a/", undef, undef); +check(200, "a/"); +check(200, "a/", 1); +check(200, "a/", 2); +check(200, "a/", 1, 2); +check(200, "a/", 3); + +write_htaccess("a/", undef, undef, "user1"); +check(401, "a/"); +check(200, "a/", "user1"); +check(401, "a/", "user2"); + +write_htaccess("a/", undef, "Any", 1, 2); +check(403, "a/"); +check(200, "a/", 1); +check(200, "a/", 2); +check(200, "a/", 1, 2); +check(403, "a/", 3); + write_htaccess("a/b/", undef, "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "Off", "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "Or", "Any", 2, 3); + check(403, "a/b/"); + check(200, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "And", "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 1, 2); + check(200, "a/b/", 1, 3); + check(200, "a/b/", 2, 3); + write_htaccess("a/b/", undef, "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 2, 3); + check(403, "a/b/", 1, 3); + write_htaccess("a/b/", "Off", "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 2, 3); + check(403, "a/b/", 1, 3); + write_htaccess("a/b/", "Or", "All", 3, 4); + check(403, "a/b/"); + check(200, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 2, 3); + check(200, "a/b/", 3, 4); + check(403, "a/b/", 3); + check(403, "a/b/", 4); + write_htaccess("a/b/", "And", "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(403, "a/b/", 1, 2); + check(403, "a/b/", 1, 3); + check(200, "a/b/", 2, 3); + + +write_htaccess("a/", undef, "All", 1, "!2"); +check(403, "a/"); +check(200, "a/", 1); +check(403, "a/", 2); +check(403, "a/", 1, 2); +check(403, "a/", 3); + write_htaccess("a/b/", undef, "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "Off", "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "Or", "Any", 3, 4); + check(403, "a/b/"); + check(200, "a/b/", 1); + check(403, "a/b/", 1, 2); + check(200, "a/b/", 1, 2, 3); + check(200, "a/b/", 1, 2, 4); + check(200, "a/b/", 4); + write_htaccess("a/b/", "And", "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(403, "a/b/", 1, 2); + check(200, "a/b/", 1, 3); + check(403, "a/b/", 2, 3); + # should not inherit AuthMerging And from a/b/ + write_htaccess("a/b/c/", undef, "Any", 4); + check(403, "a/b/c/", 1, 3); + check(200, "a/b/c/", 4); + check(200, "a/b/c/", 1, 2, 4); + write_htaccess("a/b/", undef, "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 2, 3); + check(403, "a/b/", 1, 3); + write_htaccess("a/b/", "Off", "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 2, 3); + check(403, "a/b/", 1, 3); + write_htaccess("a/b/", "Or", "All", 3, 4); + check(403, "a/b/"); + check(200, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 2, 3); + check(200, "a/b/", 3, 4); + check(403, "a/b/", 3); + check(403, "a/b/", 4); + write_htaccess("a/b/", "And", "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(403, "a/b/", 1, 2); + check(403, "a/b/", 1, 3); + check(403, "a/b/", 2, 3); + + +write_htaccess("a/", undef, "All", 1, 2); +check(403, "a/"); +check(403, "a/", 1); +check(403, "a/", 2); +check(200, "a/", 1, 2); + write_htaccess("a/b/", undef, "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "Off", "Any", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(200, "a/b/", 2); + check(200, "a/b/", 3); + write_htaccess("a/b/", "Or", "Any", 3, 4); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(200, "a/b/", 1, 2); + check(200, "a/b/", 3); + check(200, "a/b/", 4); + write_htaccess("a/b/", "And", "Any", 3, 4); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(403, "a/b/", 4); + check(403, "a/b/", 1, 2); + check(200, "a/b/", 1, 2, 3); + check(200, "a/b/", 1, 2, 4); + check(403, "a/b/", 1, 3, 4); + write_htaccess("a/b/", undef, "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 2, 3); + check(403, "a/b/", 1, 3); + write_htaccess("a/b/", "Off", "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(200, "a/b/", 2, 3); + check(403, "a/b/", 1, 3); + write_htaccess("a/b/", "Or", "All", 3, 4); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(403, "a/b/", 4); + check(403, "a/b/", 2, 3); + check(200, "a/b/", 3, 4); + check(200, "a/b/", 1, 2); + write_htaccess("a/b/", "And", "All", 2, 3); + check(403, "a/b/"); + check(403, "a/b/", 1); + check(403, "a/b/", 2); + check(403, "a/b/", 3); + check(403, "a/b/", 1, 2); + check(403, "a/b/", 1, 3); + check(403, "a/b/", 2, 3); + check(200, "a/b/", 1, 2, 3); + +# +# To test merging of a mix of user and non-user authz providers, +# we should test all orders. +# + +# helper function to get all permutations of an array +# returns array of references +sub permutations +{ + my @results = [shift]; + + foreach my $el (@_) { + my @new_results; + foreach my $arr (@results) { + my $len = scalar(@{$arr}); + foreach my $i (0 .. $len) { + my @new = @{$arr}; + splice @new, $i, 0, $el; + push @new_results, \@new; + } + } + @results = @new_results; + } + return @results; +} + + +my @perms = permutations(qw/user1 user2 1 2/); +foreach my $p (@perms) { + write_htaccess("a/", undef, "All", @{$p}); + check(403, "a/"); + check(403, "a/", 1); + check(403, "a/", "user1"); + check(401, "a/", 1, 2); + check(401, "a/", 1, 2, "user1"); + check(401, "a/", 1, 2, "user3"); + check(403, "a/", 1, "user1"); + + write_htaccess("a/", undef, "Any", @{$p}); + check(401, "a/"); + check(200, "a/", 1); + check(200, "a/", "user1"); + check(401, "a/", "user3"); + check(200, "a/", 1, 2); + check(200, "a/", 1, "user1"); + check(200, "a/", 1, "user3"); +} diff --git a/debian/perl-framework/t/modules/autoindex.t b/debian/perl-framework/t/modules/autoindex.t new file mode 100644 index 0000000..76c9af4 --- /dev/null +++ b/debian/perl-framework/t/modules/autoindex.t @@ -0,0 +1,444 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## +## mod_autoindex test +## +## 9-4-01 +## this only tests for a very limited set of functionality +## in the autoindex module. namely, file sorting and display +## with IndexOrderDefault directive and FancyIndexing. +## more to come... + +my $htdocs = Apache::Test::vars('documentroot'); +my $ai_dir = "/modules/autoindex"; +my $uri_prefix = "$ai_dir/htaccess"; +my $dir = "$htdocs$uri_prefix"; +my $htaccess = "$dir/.htaccess"; +my $readme = 'autoindex test README'; +my $s = 'HITHERE'; +my $uri = "$uri_prefix/"; +my $file_prefix = 'ai-test'; +my ($C,$O); +my $cfg = Apache::Test::config(); +my $have_apache_2 = have_apache 2; +my $hr = $have_apache_2 ? '<hr>' : '<hr />'; + +my %file = +( + README => + { + size => length($readme), + date => 998932210 + }, + txt => + { + size => 5, + date => 998934398 + }, + jpg => + { + size => 15, + date => 998936491 + }, + gif => + { + size => 1568, + date => 998932291 + }, + html => + { + size => 9815, + date => 922934391 + }, + doc => + { + size => 415, + date => 998134391 + }, + gz => + { + size => 1, + date => 998935991 + }, + tar => + { + size => 1009845, + date => 997932391 + }, + php => + { + size => 913515, + date => 998434391 + } +); + +plan tests => 84, ['autoindex']; + +## set up environment ## +$cfg->gendir("$htdocs/$ai_dir"); +$cfg->gendir("$dir"); +test_content('create'); + +## run tests ## +foreach my $fancy (0,1) { + + ## test default order requests ## + foreach my $order (qw(Ascending Descending)) { + $O = substr($order, 0, 1); + + foreach my $component (qw(Name Date Size)) { + $C = substr($component, 0, 1); + $C = 'M' if $C eq 'D'; + my $config_string = ''; + $config_string = "IndexOptions FancyIndexing\n" if $fancy; + $config_string .= "IndexOrderDefault $order $component\n"; + + print "---\n$config_string\n"; + sok { ai_test($config_string,$C,$O,$uri) }; + + ## test explicit order requests ## + foreach $C (qw(N M S)) { + foreach $O (qw(A D)) { + my $test_uri; + if ($have_apache_2) { + $test_uri = "$uri?C=$C\&O=$O"; + } else { + $test_uri = "$uri?$C=$O"; + } + + print "---\n$config_string\n(C=$C O=$O)\n"; + sok { ai_test($config_string,$C,$O,$test_uri) }; + + } + } + } + } +} + +sub ai_test ($$$$) { + my ($htconf,$c,$o,$t_uri) = @_; + + my $html_head; + + if (have_min_apache_version('2.5.1')) { + $html_head = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'; + } + else { + $html_head = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'; + } + + $html_head .= <<HEAD; + +<html> + <head> + <title>Index of $uri_prefix</title> + </head> + <body> +<h1>Index of $uri_prefix</h1> +HEAD + my $html_foot = "${hr}</pre>\n</body></html>\n"; + + my $i; + my $fail = 0; + my $FancyIndexing = ($htconf =~ /FancyIndex/); + + write_htaccess($htconf); + my $actual = GET_BODY $t_uri; + print "GET $t_uri\n"; + + ################################ + ## this may not be ok! ## + ##----------------------------## + ## should you be able to sort ## + ## by components other than ## + ## name when FancyIndexing is ## + ## not on? ## + ################################ + $c = 'N' unless $FancyIndexing;# + ################################ + ## end questionable block ## + ################################ + + my @file_list; + if ($o =~ /^A$/i) { + ## sort ascending ## + if ($c =~ /^N$/i) { + ## by name ## + @file_list = sort keys %file; + } elsif ($c =~ /^S$/i) { + ## by size ## + @file_list = + sort {$file{$a}{size} <=> $file{$b}{size}} keys %file; + } elsif ($c =~ /^M$/i) { + ## by date ## + @file_list = + sort {$file{$a}{date} <=> $file{$b}{date}} keys %file; + } else { + print "big error: C=$c, O=$o\n"; + return 0; + } + } elsif ($o =~ /^D$/i) { + ## sort decending ## + if ($c =~ /^N$/i) { + ## by name ## + @file_list = reverse sort keys %file; + } elsif ($c =~ /^S$/i) { + ## by size ## + @file_list = + sort {$file{$b}{size} <=> $file{$a}{size}} keys %file; + } elsif ($c =~ /^M$/i) { + ## by date ## + @file_list = + sort {$file{$b}{date} <=> $file{$a}{date}} keys %file; + } else { + print "big error: C=$c, O=$o\n"; + return 0; + } + } else { + print "big error: C=$c, O=$o\n"; + return 0; + } + + my $sep = '&'; + + if ($have_apache_2 && $actual =~ /\?C=.\;/) { + ## cope with new 2.1-style headers which use a semi-colon + ## to separate query segment parameters + $sep = ';'; + } + + if ($actual =~ /<hr \/>/) { + ## cope with new-fangled <hr /> tags + $hr = '<hr />'; + } + + ## set up html for fancy indexing ## + if ($FancyIndexing) { + my $name_href; + my $date_href; + my $size_href; + if ($have_apache_2) { + $name_href = 'C=N'.$sep.'O=A'; + $date_href = 'C=M'.$sep.'O=A'; + $size_href = 'C=S'.$sep.'O=A'; + } else { + $name_href = 'N=A'; + $date_href = 'M=A'; + $size_href = 'S=A'; + } + foreach ($name_href, $date_href, $size_href) { + if ($have_apache_2) { + if ($_ =~ /^C=$c/i) { + #print "changed ->$_<- to "; + $_ = "C=$c$sep"."O=A" if $o =~ /^D$/i; + $_ = "C=$c$sep"."O=D" if $o =~ /^A$/i; + last; + } + } else { + if ($_ =~ /^$c=/i) { + $_ = "$c=A" if $o =~ /^D$/i; + $_ = "$c=D" if $o =~ /^A$/i; + last; + } + } + } + + if ($have_apache_2) { + + $html_head .= + "<pre> <a href=\"?$name_href\">Name</a> <a href=\"?$date_href\">Last modified</a> <a href=\"?$size_href\">Size</a> <a href=\"?C=D$sep"."O=A\">Description</a>${hr} <a href=\"/modules/autoindex/\">Parent Directory</a> - \n"; + + $html_foot = "${hr}</pre>\n</body></html>\n"; + + } else { + + $html_head .= + "<pre><a href=\"?$name_href\">name</a> <a href=\"?$date_href\">last modified</a> <a href=\"?$size_href\">size</a> <a href=\"?d=a\">description</a>\n<hr>\n<parent>\n"; + + $html_foot = "</pre><hr>\n</body></html>\n"; + + } + + } else { + ## html for non fancy indexing ## + + if ($have_apache_2) { + + $html_head .= + "<ul><li><a href=\"/modules/autoindex/\"> Parent Directory</a></li>\n"; + + $html_foot = "</ul>\n</body></html>\n"; + + } else { + + $html_head .= + "<ul><li><a href=\"/modules/autoindex/\"> Parent Directory</a>\n"; + + $html_foot = "</ul></body></html>\n"; + + } + } + + ## verify html heading ## + my @exp_head = split /\n/, $html_head; + my @actual = split /\n/, $actual; + for ($i=0;$i<@exp_head;$i++) { + + $actual[$i] = lc($actual[$i]); + $exp_head[$i] = lc($exp_head[$i]); + + if ($actual[$i] eq $exp_head[$i]) { + next; + } else { + if (!$have_apache_2 && $actual[$i] =~ /parent directory/ && + $exp_head[$i] eq "<parent>") { + ## cursory check on this one due to timestamp + ## in parent directory line in 1.3 + next; + } + + print "expect:\n->$exp_head[$i]<-\n"; + print "actual:\n->$actual[$i]<-\n"; + $fail = 1; + last; + } + } + + if ($fail) { + print "failed on html head (C=$c\&O=$o"; + print " FancyIndexing" if $FancyIndexing; + print ")\n"; + return 0; + } + + ## file list verification ## + my $e = 0; + for ($i=$i;$file_list[$e] && $actual;$i++) { + my $cmp_string = "<li><a href=\"$file_prefix.$file_list[$e]\"> $file_prefix.$file_list[$e]</a></li>"; + $cmp_string = "<li><a href=\"$file_prefix.$file_list[$e]\"> $file_prefix.$file_list[$e]</a>" unless ($have_apache_2); + + $cmp_string = + "<a href=\"$file_prefix.$file_list[$e]\">$file_prefix.$file_list[$e]</a>" + if $FancyIndexing; + + if ($file_list[$e] eq 'README' or + $file_list[$e] eq '.htaccess') { + $cmp_string = + "<a href=\"$file_list[$e]\">$file_list[$e]</a>" + if $FancyIndexing; + $cmp_string = + "<li><a href=\"$file_list[$e]\"> $file_list[$e]</a>" + unless $FancyIndexing; + } + + $actual[$i] = lc($actual[$i]); + $cmp_string = lc($cmp_string); + + if ($actual[$i] =~ /$cmp_string/i) { + $e++; + next; + } else { + print "expect:\n->$cmp_string<-\n"; + print "actual:\n->$actual[$i]<-\n"; + $fail = 1; + last; + } + } + + if ($fail) { + print "failed on file list (C=$c\&O=$o"; + print " FancyIndexing" if $FancyIndexing; + print ")\n"; + exit; + return 0; + } + + ## the only thing left in @actual should be the foot + my @foot = split /\n/, $html_foot; + $e = 0; + for ($i=$i;$foot[$e];$i++) { + $actual[$i] = lc($actual[$i]); + $foot[$e] = lc($foot[$e]); + if ($actual[$i] ne $foot[$e]) { + $fail = 1; + print "expect:\n->$foot[$e]<-\nactual:\n->$actual[$i]<-\n"; + last; + } + $e++; + } + + if ($fail) { + print "failed on html footer (C=$c\&O=$o"; + print " FancyIndexing" if $FancyIndexing; + print ")\n"; + return 0; + } + + ## and at this point there should be no more @actual + if ($i != @actual) { + print "thats not all! there is more than we expected!\n"; + print "i = $i\n"; + print "$actual[$i]\n"; + print "$actual[$i+1]\n"; + return 0; + } + + return 1; +} + + +## clean up ## +test_content('destroy'); +rmdir $dir or print "warning: cant rmdir $dir: $!\n"; +rmdir "$htdocs/$ai_dir"; + +sub write_htaccess { + open (HT, ">$htaccess") or die "cant open $htaccess: $!"; + print HT shift; + close(HT); + + ## add/update .htaccess to the file hash ## + ($file{'.htaccess'}{date}, $file{'.htaccess'}{size}) = + (stat($htaccess))[9,7]; +} + +## manage test content ## +sub test_content { + my $what = shift || 'create'; + return undef if ($what ne 'create' and $what ne 'destroy'); + + foreach (sort keys %file) { + my $file = "$dir/$_"; + $file = "$dir/$file_prefix.$_" unless ($_ eq 'README' + or $_ eq '.htaccess'); + + if ($what eq 'destroy') { + unlink $file or print "warning: cant unlink $file: $!\n"; + next; + } + + open (FILE, ">$file") or die "cant open $file: $!"; + if ($_ eq 'README') { + ## README file will contain actual text ## + print FILE $readme; + } else { + ## everything else is just x's ## + print FILE "x"x$file{$_}{size}; + } + close(FILE); + + if ($file{$_}{date} == 0) { + $file{$_}{date} = (stat($file))[9]; + } else { + utime($file{$_}{date}, $file{$_}{date}, $file) + or die "cant utime $file: $!"; + } + + } + +} + diff --git a/debian/perl-framework/t/modules/autoindex2.t b/debian/perl-framework/t/modules/autoindex2.t new file mode 100644 index 0000000..b4b72f7 --- /dev/null +++ b/debian/perl-framework/t/modules/autoindex2.t @@ -0,0 +1,70 @@ +use strict; +use warnings FATAL => 'all'; + +use File::Spec::Functions qw(catfile catdir); + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +## +## mod_autoindex test part II +## +## this tests how mod_autoindex handles sub-dirs: +## normal, with protected access, with broken .htaccess, etc... + +#my $cfg = Apache::Test::config(); +my $vars = Apache::Test::config()->{vars}; +my $documentroot = $vars->{documentroot}; +my $base_dir = catdir $documentroot, "modules", "autoindex2"; +my $base_uri = "/modules/autoindex2"; +my $have_apache_2 = have_apache 2; + +# which sub-dir listings should be seen in mod_autoindex's output +# 1 == should appear +# 0 == should not appear +my %dirs = ( + dir_normal => 1, # obvious + dir_protected => $have_apache_2?0:1, # + dir_broken => $have_apache_2?0:1, # +); + +plan tests => 3, ['autoindex']; + +setup(); + +my $res = GET_BODY "$base_uri/"; + +# simply test whether we get the sub-dir listed or not +for my $dir (sort keys %dirs) { + my $found = $res =~ /$dir/ ? 1 : 0; + ok t_cmp($found, + $dirs{$dir}, + "$dir should @{[$dirs{$dir}?'':'not ']}be listed"); +} + +sub setup { + t_mkdir $base_dir; + + ### normal dir + t_mkdir catdir $base_dir, "dir_normal"; + + ### passwd protected dir + my $prot_dir = catdir $base_dir, "dir_protected"; + # htpasswd file + t_write_file catfile($prot_dir, "htpasswd"), "nobody:HIoD8SxAgkCdQ"; + # .htaccess file + my $content = <<CONTENT; +AuthType Basic +AuthName "Restricted Directory" +AuthUserFile $prot_dir/htpasswd +Require valid user +CONTENT + t_write_file catfile($prot_dir, ".htaccess"), $content; + + ### dir with a broken .htaccess + my $broken_dir = catdir $base_dir, "dir_broken"; + t_write_file catfile($broken_dir, ".htaccess"), + "This_is_a_broken_on_purpose_.htaccess_file"; + +} diff --git a/debian/perl-framework/t/modules/brotli.t b/debian/perl-framework/t/modules/brotli.t new file mode 100644 index 0000000..0f9dc13 --- /dev/null +++ b/debian/perl-framework/t/modules/brotli.t @@ -0,0 +1,115 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @qvalue = ( + [ '' , 1], + [ ' ' , 1], + [ ';' , 1], + [';q=' , 1], + [';q=0' , 0], + [';q=0.' , 0], + [';q=0.0' , 0], + [';q=0.00' , 0], + [';q=0.000' , 0], + [';q=0.0000' , 1], # invalid qvalue format +); + +plan tests => (6 * scalar @qvalue) + 4, need_module 'brotli', need_module 'alias'; + +my $r; + +foreach my $q (@qvalue) { + # GET request against the location with Brotli. + print "qvalue: " . $q->[0] . "\n"; + $r = GET("/only_brotli/index.html", "Accept-Encoding" => "br" . $q->[0]); + ok t_cmp($r->code, 200); + if ($q->[1] == 1) { + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + } + else { + ok t_cmp($r->header("Content-Encoding"), undef, "response without Content-Encoding is OK"); + } + + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } + + # GET request for a zero-length file. + print "qvalue: " . $q->[0] . "\n"; + $r = GET("/only_brotli/zero.txt", "Accept-Encoding" => "br" . $q->[0]); + ok t_cmp($r->code, 200); + if ($q->[1] == 1) { + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + } + else { + ok t_cmp($r->header("Content-Encoding"), undef, "response without Content-Encoding is OK"); + } + + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } + + # HEAD request against the location with Brotli. + print "qvalue: " . $q->[0] . "\n"; + $r = HEAD("/only_brotli/index.html", "Accept-Encoding" => "br" . $q->[0]); + ok t_cmp($r->code, 200); + if ($q->[1] == 1) { + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + } + else { + ok t_cmp($r->header("Content-Encoding"), undef, "response without Content-Encoding is OK"); + } + + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } +} + + +if (have_module('deflate')) { + # GET request against the location with fallback to deflate (test that + # Brotli is chosen due to the order in SetOutputFilter). + $r = GET("/brotli_and_deflate/apache_pb.gif", "Accept-Encoding" => "gzip,br"); + ok t_cmp($r->code, 200); + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } + $r = GET("/brotli_and_deflate/apache_pb.gif", "Accept-Encoding" => "gzip"); + ok t_cmp($r->code, 200); + ok t_cmp($r->header("Content-Encoding"), "gzip", "response Content-Encoding is OK"); + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } +} else { + skip "skipping tests without mod_deflate" foreach (1..4); +} diff --git a/debian/perl-framework/t/modules/buffer.t b/debian/perl-framework/t/modules/buffer.t new file mode 100644 index 0000000..e508f37 --- /dev/null +++ b/debian/perl-framework/t/modules/buffer.t @@ -0,0 +1,38 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @testcases = ( + ['/apache/buffer_in/', 'foo'], + ['/apache/buffer_out/', 'foo'], + ['/apache/buffer_in_out/', 'foo'], +); + +plan tests => scalar @testcases * 4, need 'mod_reflector', 'mod_buffer'; + +foreach my $t (@testcases) { + ## Small query ## + my $r = POST($t->[0], content => $t->[1]); + + # Checking for return code + ok t_cmp($r->code, 200, "Checking return code is '200'"); + # Checking for content + ok t_is_equal($r->content, $t->[1]); + + ## Big query ## + # 'foo' is 3 bytes, so 'foo' x 1000000 is ~3M, which is way over the default 'BufferSize' + ### FIXME - testing with to x 10000 is confusing LWP's full-duplex + ### handling: https://github.com/libwww-perl/libwww-perl/issues/299 + ### throttled down to a size which seems to work reliably for now + my $bigsize = 100000; + + $r = POST($t->[0], content => $t->[1] x $bigsize); + + # Checking for return code + ok t_cmp($r->code, 200, "Checking return code is '200'"); + # Checking for content + ok t_is_equal($r->content, $t->[1] x $bigsize); +} diff --git a/debian/perl-framework/t/modules/cache.t b/debian/perl-framework/t/modules/cache.t new file mode 100644 index 0000000..f235de1 --- /dev/null +++ b/debian/perl-framework/t/modules/cache.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +plan tests => 3, need 'cache', need_cache_disk, need_min_apache_version('2.1.9'); + +Apache::TestRequest::module('mod_cache'); + +t_mkdir(Apache::Test::vars('serverroot') . '/conf/cacheroot/'); + +my $r = GET("/cache/"); +ok t_cmp($r->code, 200, "non-cached call to index.html"); + +$r = GET("/cache/index.html"); +ok t_cmp($r->code, 200, "call to cache index.html"); + +$r = GET("/cache/"); +ok t_cmp($r->code, 200, "cached call to index.html"); diff --git a/debian/perl-framework/t/modules/cgi.t b/debian/perl-framework/t/modules/cgi.t new file mode 100644 index 0000000..9b6edc2 --- /dev/null +++ b/debian/perl-framework/t/modules/cgi.t @@ -0,0 +1,279 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use File::stat; + +my $have_apache_2 = have_apache 2; +my $have_apache_2050 = have_min_apache_version "2.0.50"; + +my $script_log_length = 40960; + +## mod_cgi test +## +## extra.conf.in: +## <IfModule mod_cgi.c> +## AddHandler cgi-script .sh +## AddHandler cgi-script .pl +## ScriptLog logs/mod_cgi.log +## ScriptLogLength 40960 +## ScriptLogBuffer 256 +## <Directory @SERVERROOT@/htdocs/modules/cgi> +## Options +ExecCGI +## [some AcceptPathInfo stuff] +## </Directory> +## </IfModule> +## + +my @post_content = (10, 99, 250, 255, 256, 257, 258, 1024); + +my %test = ( + 'perl.pl' => { + 'rc' => 200, + 'expect' => 'perl cgi' + }, + 'bogus-perl.pl' => { + 'rc' => 500, + 'expect' => 'none' + }, + 'nph-test.pl' => { + 'rc' => 200, + 'expect' => 'ok' + }, + 'sh.sh' => { + 'rc' => 200, + 'expect' => 'sh cgi' + }, + 'bogus-sh.sh' => { + 'rc' => 500, + 'expect' => 'none' + }, + 'acceptpathinfoon.sh' => { + 'rc' => 200, + 'expect' => '' + }, + 'acceptpathinfoon.sh/foo' => { + 'rc' => 200, + 'expect' => '/foo' + }, + 'acceptpathinfooff.sh' => { + 'rc' => 200, + 'expect' => '' + }, + 'acceptpathinfooff.sh/foo' => { + 'rc' => 404, + 'expect' => 'none' + }, + 'acceptpathinfodefault.sh' => { + 'rc' => 200, + 'expect' => '' + }, + 'acceptpathinfodefault.sh/foo' => { + 'rc' => 200, + 'expect' => '/foo' + }, + 'stderr1.pl' => { + 'rc' => 200, + 'expect' => 'this is stdout' + }, + 'stderr2.pl' => { + 'rc' => 200, + 'expect' => 'this is also stdout' + }, + 'stderr3.pl' => { + 'rc' => 200, + 'expect' => 'this is more stdout' + }, + 'nph-stderr.pl' => { + 'rc' => 200, + 'expect' => 'this is nph-stdout' + }, +); + +#XXX: find something that'll on other platforms (/bin/sh aint it) +if (Apache::TestConfig::WINFU()) { + delete @test{qw(sh.sh bogus-sh.sh)}; +} +if (Apache::TestConfig::WINFU() || !$have_apache_2) { + delete @test{qw(acceptpathinfoon.sh acceptpathinfoon.sh/foo)}; + delete @test{qw(acceptpathinfooff.sh acceptpathinfooff.sh/foo)}; + delete @test{qw(acceptpathinfodefault.sh acceptpathinfodefault.sh/foo)}; +} + +# CGI stderr handling works in 2.0.50 and later only on Unixes. +if (!$have_apache_2050 || Apache::TestConfig::WINFU()) { + delete @test{qw(stderr1.pl stderr2.pl stderr3.pl nph-stderr.pl)}; +} + +my $tests = ((keys %test) * 2) + (@post_content * 3) + 4; +plan tests => $tests, \&need_cgi; + +my ($expected, $actual); +my $path = "/modules/cgi"; +my $vars = Apache::Test::vars(); +my $t_logs = $vars->{t_logs}; +my $cgi_log = "$t_logs/mod_cgi.log"; +my ($bogus,$log_size,$stat) = (0,0,0); + +unlink $cgi_log if -e $cgi_log; + +foreach (sort keys %test) { + $expected = $test{$_}{rc}; + $actual = GET_RC "$path/$_"; + ok t_cmp($actual, + $expected, + "return code for $_" + ); + + if ($test{$_}{expect} ne 'none') { + $expected = $test{$_}{expect}; + $actual = GET_BODY "$path/$_"; + chomp $actual if $actual =~ /\n$/; + + ok t_cmp($actual, + $expected, + "body for $_" + ); + } + elsif ($_ !~ /^bogus/) { + print "# no body test for this one\n"; + ok 1; + } + + ## verify bogus cgi's get handled correctly + ## logging to the cgi log + if ($_ =~ /^bogus/) { + $bogus++; + if ($bogus == 1) { + + ## make sure cgi log got created, get size. + if (-e $cgi_log) { + print "# cgi log created ok.\n"; + ok 1; + $stat = stat($cgi_log); + $log_size = $$stat[7]; + } else { + print "# error: cgi log not created!\n"; + ok 0; + } + } else { + + ## make sure log got bigger. + if (-e $cgi_log) { + $stat = stat($cgi_log); + print "# checking that log size ($$stat[7]) is bigger than it used to be ($log_size)\n"; + ok ($$stat[7] > $log_size); + $log_size = $$stat[7]; + } else { + print "# error: cgi log does not exist!\n"; + ok 0; + } + } + } +} + +## post lots of content to a bad cgi, so we can verify +## ScriptLogBuffer is working. +my $content = 0; +foreach my $length (@post_content) { + $content++; + $expected = '500'; + $actual = POST_RC "$path/bogus-perl.pl", content => "$content"x$length; + + print "# posted content (length $length) to bogus-perl.pl\n"; + ## should get rc 500 + ok t_cmp($actual, $expected, "POST to $path/bogus-perl.pl [content: $content x $length]"); + + if (-e $cgi_log) { + ## cgi log should be bigger. + ## as long as it's under ScriptLogLength + $stat = stat($cgi_log); + if ($log_size < $script_log_length) { + print "# checking that log size ($$stat[7]) is greater than $log_size\n"; + ok ($$stat[7] > $log_size); + } else { + ## should not fall in here at this point, + ## but just in case... + print "# verifying log did not increase in size...\n"; + ok t_cmp($$stat[7], $log_size, "log size should not have increased"); + } + $log_size = $$stat[7]; + + ## there should be less than ScriptLogBuffer (256) + ## characters logged from the post content + open (LOG, $cgi_log) or die "died opening cgi log: $!"; + my $multiplier = 256; + my $log; + { + local $/; + $log = <LOG>; + } + close (LOG); + $multiplier = $length unless $length > $multiplier; + print "# verifying that logged content is $multiplier characters\n"; + if ($log =~ /^(?:$content){$multiplier}\n?$/m) { + ok 1; + } + else { + $log =~ s{^}{# }m; + print "# no log line found with $multiplier '$content' characters\n"; + print "# log is:\n'$log'\n"; + ok 0; + } + } else { + ## log does not exist ## + print "# cgi log does not exist, test fails.\n"; + ok 0; + } +} + +## make sure cgi log does not +## keep logging after it is bigger +## than ScriptLogLength +for (my $i=1 ; $i<=40 ; $i++) { + + ## get out if log does not exist ## + last unless -e $cgi_log; + + ## request the 1k bad cgi + ## (1k of data logged per request) + GET_RC "$path/bogus1k.pl"; + + ## when log goes over max size stop making requests + $stat = stat($cgi_log); + $log_size = $$stat[7]; + last if ($log_size > $script_log_length); + +} +## make sure its over (or equal) our ScriptLogLength +print "# verifying log is greater than $script_log_length bytes.\n"; +ok ($log_size >= $script_log_length); + +## make sure it does not grow now. +GET_RC "$path/bogus1k.pl"; +print "# verifying log did not grow after making bogus request.\n"; +if (-e $cgi_log) { + $stat = stat($cgi_log); + ok ($log_size eq $$stat[7]); +} else { + print "# log does not exist!\n"; + ok 0; +} + +GET_RC "$path/bogus-perl.pl"; +print "# verifying log did not grow after making another bogus request.\n"; +if (-e $cgi_log) { + $stat = stat($cgi_log); + ok ($log_size eq $$stat[7]); +} else { + print "# log does not exist!\n"; + ok 0; +} + +print "# checking that HEAD $path/perl.pl returns 200.\n"; +ok HEAD_RC("$path/perl.pl") == 200; + +## clean up +unlink $cgi_log; diff --git a/debian/perl-framework/t/modules/data.t b/debian/perl-framework/t/modules/data.t new file mode 100644 index 0000000..ef62967 --- /dev/null +++ b/debian/perl-framework/t/modules/data.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @testcases = ( + ['/modules/data/SupportApache-small.png', "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAACXBIWXMAABcSAAAXEgFnn9JSAAA6G2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMTEgNzkuMTU4MzI1LCAyMDE1LzA5LzEwLTAxOjEwOjIwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTctMDMtMjRUMjA6NDU6MTItMDQ6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNy0wMi0yMlQxMTo0NjoxODwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTctMDMtMjRUMjA6NDU6MTItMDQ6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6YjY5OTdlMWYtNjFlOC0yZDQ0LWIwNzAtMmM3Mzc5MzcxNjJlPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6NDgxMWVmNzEtMTBmNC0xMWU3LTlmZDMtODYwODE2ZGE5NDUxPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NmJmZGM3ZDktZDhiZC1iNzQzLWE1ZmYtOTExNTY3YjA0NTYyPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo2YmZkYzdkOS1kOGJkLWI3NDMtYTVmZi05MTE1NjdiMDQ1NjI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTctMDMtMjRUMjA6NDU6MTItMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6YjY5OTdlMWYtNjFlOC0yZDQ0LWIwNzAtMmM3Mzc5MzcxNjJlPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE3LTAzLTI0VDIwOjQ1OjEyLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+MTUwMDAwMC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTUwMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MzAwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMwMDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+53R3BQAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAE+s0lEQVR42uyddbwkZ5X+v+d9q6rtuo37ZOKKJbhrcNmFJYv7YovsLziLO8F2cQ2BRRLc3QIECHGbyLhev21V9Z7fH21V1X1nJiSBAabyuZm+t7urq0ueOuc5z3mO/B+P5fBchBrCmiVbGB+sUY58RB2KogJ5CdhZnURVWVaYwF/YTzXvEYlPbA2CIGFEPaoypsKsp5hcCZxSqdZZkCrrWEYU1ykXaxi1qBMEiGwMzc+SOMBXBd+gAohDMQSVGrH1UDGoCCKKKhgcViwV4yiWpzHBIPMSY0LBOg8XRJRKBWouZte+fazoH0FFCGsQOsEWFOsUJ4oBkJha2eBbD68YM1urk8fH+II1FgmVWGPECiYW9tbmyJX6WVqpUIkc2z1LKa6zyrNM5ot4anAIXhQTixIZwSqAIp5C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"], +); + +plan tests => scalar @testcases * 2, need 'mod_data'; + +foreach my $t (@testcases) { + ## Small query ## + my $r = GET($t->[0]); + + # Checking for return code + ok t_cmp($r->code, 200, "Checking return code is '200'"); + # Checking for content + ok t_is_equal($r->content, $t->[1]); +} diff --git a/debian/perl-framework/t/modules/dav.t b/debian/perl-framework/t/modules/dav.t new file mode 100644 index 0000000..73046cd --- /dev/null +++ b/debian/perl-framework/t/modules/dav.t @@ -0,0 +1,168 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use HTTP::Date; + +## +## mod_dav tests +## + +plan tests => 19, [qw(dav HTTP::DAV)]; +require HTTP::DAV; + +my $vars = Apache::Test::vars(); +my $dav = HTTP::DAV->new; +my $server = "$vars->{servername}:$vars->{port}"; + +my $htdocs = Apache::Test::vars('documentroot'); +my $response; +my $dir = "modules/dav"; +my $uri = "/$dir/dav.html"; +my $body = <<CONTENT; +<html> + <body> + <center> + <h1>mod_dav test page</h1> + this is a page generated by<br> + the mod_dav test in the Apache<br> + perl test suite.<br> + </center> + </body> +</html> +CONTENT + +## make sure its clean before we begin ## +unlink "$htdocs$uri" if -e "$htdocs$uri"; +mkdir "$htdocs/$dir", oct('755') unless -e "$htdocs/$dir"; + +Apache::TestUtil::t_chown("$htdocs/$dir"); + +## set up resource and lock it ## +my $resource = $dav->new_resource( -uri => "http://$server$uri"); +$response = $resource->lock; +print "resource lock test:\n"; +ok $response->is_success; + +## write new resource ## +$response = $resource->put($body); +print "DAV put test:\n"; +ok $response->is_success; + +## get properties ## +## Wait until none of the returned time +## properties equals "now" +sleep(2); +$response = $resource->propfind; +print "getting DAV resource properties:\n"; +ok $response->is_success; + +my $createdate = $resource->get_property( "creationdate" ); +my $lastmodified = $resource->get_property( "getlastmodified" ); +my $now = HTTP::Date::time2str(time()); +print "created: $createdate\n"; +print "modified: $lastmodified\n"; +print "now: $now\n"; +ok $createdate ne $now; +ok $createdate eq $lastmodified; + +## should be locked ## +print "resource lock status test:\n"; +ok $resource->is_locked; + +## unlock ## +print "resource unlock test:\n"; +$response = $resource->unlock; +ok $response->is_success; + +## should be unlocked ## +print "resource lock status test:\n"; +$response = $resource->is_locked; +ok !$resource->is_locked; + +## verify new resource using regular http get ## +my $actual = GET_BODY $uri; +print "getting uri...\nexpect:\n->$body<-\ngot:\n->$actual<-\n"; +ok $actual eq $body; + + +## testing with second dav client ## +my $d2 = HTTP::DAV->new; +my $r2 = $d2->new_resource( -uri => "http://$server$uri"); + +## put an unlocked resource (will work) ## +$response = $r2->get; +my $b2 = $r2->get_content; +$b2 =~ s#<h1>mod_dav test page</h1>#<h1>mod_dav test page take two</h1>#; + +print "putting with 2nd dav client (on unlocked resource)\n"; +$response = $r2->put($b2); +ok $response->is_success; + +$actual = GET_BODY $uri; +print "getting new uri...\nexpect:\n->$b2<-\ngot:\n->$actual<-\n"; +ok $actual eq $b2; + +## client 1 locks, client 2 should not be able to lock ## +print "client 1 locking resource\n"; +$response = $resource->lock +( + -owner => 'mod_dav test client 1', + -depth => 'Infinity', + -scope => 'exclusive', + -type => 'write', + -timeout => 120 +); +ok $response->is_success; + +print "client 2 attempting to lock same resource\n"; +$response = $r2->lock +( + -owner => 'mod_dav test client 2', + -depth => 'Infinity', + -scope => 'exclusive', + -type => 'write', + -timeout => 120 +); +ok !$response->is_success; + +## client 2 should not be able to put because the resource is already locked by client 1 ## +$response = $r2->get; +my $b3 = $r2->get_content; +$b3 =~ s#mod_dav#f00#g; + +print "client 2 attempting to put resource locked by client 1\n"; +$response = $r2->put($b3); +ok !$response->is_success; + +print "verifying all is well through http\n"; +$actual = GET_BODY $uri; +print "getting new uri...\nexpect:\n->$b2<-\ngot:\n->$actual<-\n"; +ok $actual ne $b3; +ok $actual eq $b2; + +## delete resource ## +$response = $resource->forcefully_unlock_all; ## trusing this will work +$response = $resource->delete; +print "resource delete test:\n"; +ok $response->is_success; + +$actual = GET_RC $uri; +print "expect 404 not found got: $actual\n"; +ok $actual == 404; + +## PR 49825 ## +my $user_agent = $dav->get_user_agent; +# invalid content-range header +$user_agent->default_header('Content-Range' => 'bytes 1-a/44' ); +$response = $resource->put($body); +$actual = $response->code; +print "PR 49825: expect 400 bad request got: $actual\n"; +ok $actual == 400; +$user_agent->default_header('Content-Range' => undef); + +## clean up ## +rmdir "$htdocs/$dir/.DAV" or print "warning: could not remove .DAV dir: $!"; +rmdir "$htdocs/$dir" or print "warning: could not remove dav dir: $!"; diff --git a/debian/perl-framework/t/modules/deflate.t b/debian/perl-framework/t/modules/deflate.t new file mode 100644 index 0000000..3b368ce --- /dev/null +++ b/debian/perl-framework/t/modules/deflate.t @@ -0,0 +1,137 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @server_deflate_uris=("/modules/deflate/index.html", + "/modules/deflate/apache_pb.gif", + "/modules/deflate/asf_logo_wide.jpg", + "/modules/deflate/zero.txt", + ); +my $server_inflate_uri="/modules/deflate/echo_post"; +my @server_bucketeer_uri = ("/modules/deflate/bucketeer/P.txt", + "/modules/deflate/bucketeer/F.txt", + "/modules/deflate/bucketeer/FP.txt", + "/modules/deflate/bucketeer/FBP.txt", + "/modules/deflate/bucketeer/BB.txt", + "/modules/deflate/bucketeer/BBF.txt", + "/modules/deflate/bucketeer/BFB.txt" + ); + +my $cgi_tests = 3; +my $tests_per_uri = 4; +my $tests = $tests_per_uri * (@server_deflate_uris + @server_bucketeer_uri) + $cgi_tests; +my $vars = Apache::Test::vars(); +my $module = 'default'; + +plan tests => $tests, need 'deflate', 'echo_post'; + +print "testing $module\n"; + +my @deflate_headers; +push @deflate_headers, "Accept-Encoding" => "gzip"; + +my @deflate_headers_q0; +push @deflate_headers_q0, "Accept-Encoding" => "gzip;q=0"; + +my @inflate_headers; +push @inflate_headers, "Content-Encoding" => "gzip"; + +if (have_module('bucketeer')) { + push @server_deflate_uris, @server_bucketeer_uri; +} +else { + skip "skipping bucketing deflate tests without mod_bucketeer" + foreach (1 .. ($tests_per_uri * @server_bucketeer_uri)); +} +for my $server_deflate_uri (@server_deflate_uris) { + my $original_str = GET_BODY($server_deflate_uri); + + my $deflated_str = GET_BODY($server_deflate_uri, @deflate_headers); + my $deflated_str_q0 = GET_BODY($server_deflate_uri, @deflate_headers_q0); + + my $inflated_str = POST_BODY($server_inflate_uri, @inflate_headers, + content => $deflated_str); + + ok $original_str eq $inflated_str; + ok $original_str eq $deflated_str_q0; + my $resp = POST($server_inflate_uri, @inflate_headers, + content => "foo123456789012346"); + if (have_min_apache_version("2.5")) { + ok($resp->code, 400, "did not detect invalid compressed request body for $server_deflate_uri"); + } + elsif (have_min_apache_version("2.4.5")) { + ok($resp->content, '!!!ERROR!!!', "did not detect invalid compressed request body for $server_deflate_uri"); + } + else { + ok($resp->code, 200, "invalid response for $server_deflate_uri"); + } + + # Disabled because not working reliably. + # If the compressed data it big enough, a partial response + # will get flushed to the client before the trailing spurious data + # is found. + # + #if (have_min_apache_version("2.5")) { + # $resp = POST($server_inflate_uri, @inflate_headers, + # content => $deflated_str . "foobarfoo"); + # ok($resp->code, 400, "did not detect spurious data after compressed request body for $server_deflate_uri"); + #} + #elsif (have_min_apache_version("2.4.5")) { + # # The "x 1000" can be removed, once r1502772 is ported back to 2.4.x + # $resp = POST($server_inflate_uri, @inflate_headers, + # content => $deflated_str . ("foobarfoo" x 1000)); + # ok($resp->content, '/.*!!!ERROR!!!$/', "did not detect spurious data after compressed request body for $server_deflate_uri"); + #} + #else { + # ok($resp->code, 200, "invalid response for $server_deflate_uri"); + #} + + my $broken = $deflated_str; + my $offset = (length($broken) > 35) ? 20 : -15; + substr($broken, $offset, 15, "123456789012345"); + $resp = POST($server_inflate_uri, @inflate_headers, + content => $broken); + if (have_min_apache_version("2.5")) { + ok($resp->code, 400, "did not detect broken compressed request body for $server_deflate_uri"); + } + elsif (have_min_apache_version("2.4.5")) { + ok($resp->content, '/.*!!!ERROR!!!$/', "did not detect broken compressed request body for $server_deflate_uri"); + } + else { + ok($resp->code, 200, "invalid response for $server_deflate_uri"); + } +} + +# mod_deflate fixes still pending to make this work... +if (have_module('cgi') && have_min_apache_version('2.1.0')) { + my $sock = Apache::TestRequest::vhost_socket('default'); + + ok $sock; + + Apache::TestRequest::socket_trace($sock); + + $sock->print("GET /modules/cgi/not-modified.pl HTTP/1.0\r\n"); + $sock->print("Accept-Encoding: gzip\r\n"); + $sock->print("\r\n"); + + # Read the status line + chomp(my $response = Apache::TestRequest::getline($sock) || ''); + $response =~ s/\s$//; + + ok t_cmp($response, qr{HTTP/1\.. 304}, "response was 304"); + + do { + chomp($response = Apache::TestRequest::getline($sock) || ''); + $response =~ s/\s$//; + } + while ($response ne ""); + + # now try and read any body: should return 0, EOF. + my $ret = $sock->read($response, 1024); + ok t_cmp($ret, 0, "expect EOF after 304 header"); +} else { + skip "skipping 304/deflate tests without mod_cgi and httpd >= 2.1.0" foreach (1..$cgi_tests); +} diff --git a/debian/perl-framework/t/modules/digest.t b/debian/perl-framework/t/modules/digest.t new file mode 100644 index 0000000..4d2e76c --- /dev/null +++ b/debian/perl-framework/t/modules/digest.t @@ -0,0 +1,176 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_cmp t_write_file); +use File::Spec; + +plan tests => 13, need need_lwp, + need_module('mod_auth_digest'), + need_min_apache_version('2.0.51'); + +my ($no_query_auth, $query_auth, $bad_query); + +# write out the authentication file +my $file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'realm1'); +t_write_file($file, <DATA>); + +my $url = '/digest/index.html'; +my $query = 'try=til%7Ede'; + +{ + my $response = GET $url; + + ok t_cmp($response->code, + 401, + 'no user to authenticate'); +} + +{ + # bad pass + my $response = GET $url, + username => 'user1', password => 'foo'; + + ok t_cmp($response->code, + 401, + 'user1:foo not found'); +} + +{ + # authenticated + my $response = GET $url, + username => 'user1', password => 'password1'; + + ok t_cmp($response->code, + 200, + 'user1:password1 found'); + + # set up for later + $no_query_auth = $response->request->headers->authorization; +} + +# now that we know normal digest auth works, play with the query string + +{ + # add a query string + my $response = GET "$url?$query", + username => 'user1', password => 'password1'; + + ok t_cmp($response->code, + 200, + 'user1:password1 with query string found'); + + # set up for later + $query_auth = $response->request->headers->authorization; +} + +{ + # do the auth header ourselves + my $response = GET "$url?$query", Authorization => $query_auth; + + ok t_cmp($response->code, + 200, + 'manual Authorization header query string'); +} + +{ + # remove the query string from the uri - bang! + (my $noquery = $query_auth) =~ s!$query!!; + + my $response = GET "$url?$query", + Authorization => $noquery; + + ok t_cmp($response->code, + 400, + 'manual Authorization with no query string in header'); +} + +{ + # same with changing the query string in the header + ($bad_query = $query_auth) =~ s!$query!something=else!; + + my $response = GET "$url?$query", + Authorization => $bad_query; + + ok t_cmp($response->code, + 400, + 'manual Authorization header with mismatched query string'); +} + +{ + # another mismatch + my $response = GET $url, + Authorization => $query_auth; + + ok t_cmp($response->code, + 400, + 'manual Authorization header with mismatched query string'); +} + +# finally, the MSIE tests + +{ + if (have_min_apache_version("2.5.0")) { + skip "'AuthDigestEnableQueryStringHack' has been removed in r1703305"; + } + else + { + # fake current MSIE behavior - this should work as of 2.0.51 + my $response = GET "$url?$query", + Authorization => $no_query_auth, + 'X-Browser' => 'MSIE'; + + ok t_cmp($response->code, + 200, + 'manual Authorization with no query string in header + MSIE'); + } +} + +{ + # pretend MSIE fixed itself + my $response = GET "$url?$query", + username => 'user1', password => 'password1', + 'X-Browser' => 'MSIE'; + + ok t_cmp($response->code, + 200, + 'a compliant response coming from MSIE'); +} + +{ + # this still bombs + my $response = GET "$url?$query", + Authorization => $bad_query, + 'X-Browser' => 'MSIE'; + + ok t_cmp($response->code, + 400, + 'manual Authorization header with mismatched query string + MSIE'); +} + +{ + # as does this + my $response = GET $url, + Authorization => $query_auth, + 'X-Browser' => 'MSIE'; + + ok t_cmp($response->code, + 400, + 'manual Authorization header with mismatched query string + MSIE'); +} + +{ + # no hack required + my $response = GET $url, + username => 'user1', password => 'password1', + 'X-Browser' => 'MSIE'; + + ok t_cmp($response->code, + 200, + 'no query string + MSIE'); +} + +__DATA__ +# user1/password1 +user1:realm1:4b5df5ee44449d6b5fbf026a7756e6ee diff --git a/debian/perl-framework/t/modules/dir.t b/debian/perl-framework/t/modules/dir.t new file mode 100644 index 0000000..51e632e --- /dev/null +++ b/debian/perl-framework/t/modules/dir.t @@ -0,0 +1,115 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## +## mod_dir tests +## + +my @index = qw(1 2 3 4 5 6 7 8 9 0); +my @bad_index = qw(foo goo moo bleh); +my $htdocs = Apache::Test::vars('documentroot'); +my $htaccess = "$htdocs/modules/dir/htaccess/.htaccess"; +my $url = "/modules/dir/htaccess/"; +my ($actual, $expected); + +#XXX: this is silly; need a better way to be portable +sub my_chomp { + $actual =~ s/[\r\n]+$//s; +} + +plan tests => @bad_index * @index * 5 + @bad_index + 5 + 3, need_module 'dir'; + +foreach my $bad_index (@bad_index) { + + print "expecting 403 (forbidden) using DirectoryIndex $bad_index\n"; + $expected = (have_module 'autoindex') ? 403 : 404; + write_htaccess("$bad_index"); + $actual = GET_RC $url; + ok ($actual == $expected); + + foreach my $index (@index) { + + print "running 5 test gambit for \"$index.html\"\n"; + ## $index will be expected for all + ## tests at this level + $expected = $index; + + write_htaccess("$index.html"); + $actual = GET_BODY $url; + ok ($actual eq $expected); + + write_htaccess("$bad_index $index.html"); + $actual = GET_BODY $url; + ok ($actual eq $expected); + + write_htaccess("$index.html $bad_index"); + $actual = GET_BODY $url; + ok ($actual eq $expected); + + write_htaccess("/modules/alias/$index.html"); + $actual = GET_BODY $url; + ok ($actual eq $expected); + + write_htaccess("$bad_index /modules/alias/$index.html"); + $actual = GET_BODY $url; + ok ($actual eq $expected); + } +} + +print "DirectoryIndex /modules/alias/index.html\n"; +$expected = "alias index"; +write_htaccess("/modules/alias/index.html"); +$actual = GET_BODY $url; +my_chomp(); +ok ($actual eq $expected); + +print "expecting 403 for DirectoryIndex @bad_index\n"; +$expected = (have_module 'autoindex') ? 403 : 404; +write_htaccess("@bad_index"); +$actual = GET_RC $url; +ok ($actual == $expected); + +$expected = $index[0]; +my @index_html = map { "$_.html" } @index; +print "expecting $expected with DirectoryIndex @index_html\n"; +write_htaccess("@index_html"); +$actual = GET_BODY $url; +ok ($actual eq $expected); + +print "expecting $expected with DirectoryIndex @bad_index @index_html\n"; +write_htaccess("@bad_index @index_html"); +$actual = GET_BODY $url; +ok ($actual eq $expected); + +unlink $htaccess; +print "removed .htaccess (no DirectoryIndex), expecting default (index.html)\n"; +$expected = "dir index"; +$actual = GET_BODY $url; +my_chomp(); +ok ($actual eq $expected); + +# DirectorySlash stuff +my $res = GET "/modules/dir", redirect_ok => 0; +ok ($res->code == 301); +$res = GET "/modules/dir/htaccess", redirect_ok => 0; +ok ($res->code == 403); + +if (!have_min_apache_version('2.5.1')) { + skip("missing DirectorySlash NotFound"); +} +else { + $res = GET "/modules/dir/htaccess/sub", redirect_ok => 0; + ok ($res->code == 404); +} + + +sub write_htaccess { + my $string = shift; + + open (HT, ">$htaccess") or die "cannot open $htaccess: $!"; + print HT "DirectoryIndex $string"; + close (HT); +} diff --git a/debian/perl-framework/t/modules/directorymatch.t b/debian/perl-framework/t/modules/directorymatch.t new file mode 100644 index 0000000..7b4fa38 --- /dev/null +++ b/debian/perl-framework/t/modules/directorymatch.t @@ -0,0 +1,26 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +## +## directorymatch tests +## + +my @ts = ( + { url => "/index.html", code => 200, hname => "DMMATCH1"}, + # TODO: PR41867 (DirectoryMatch matches files) +); + +plan tests => 2* scalar @ts, have_module 'headers'; + +for my $t (@ts) { + my $r = GET $t->{'url'}; + ok t_cmp($r->code, $t->{code}, "code for " . $t->{'url'}); + ok t_cmp($r->header($t->{'hname'}), "1", "check for " . $t->{'hname'}); +} + + diff --git a/debian/perl-framework/t/modules/env.t b/debian/perl-framework/t/modules/env.t new file mode 100644 index 0000000..c1de003 --- /dev/null +++ b/debian/perl-framework/t/modules/env.t @@ -0,0 +1,40 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## +## mod_env tests +## + +my %test = ( + 'host' => $ENV{APACHE_TEST_HOSTNAME}, + 'set' => "mod_env test environment variable", + 'setempty' => '', + 'unset' => '(none)', + 'type' => '(none)', + 'nothere' => '(none)' +); + +if (Apache::TestConfig::WIN32) { + #what looks like a bug in perl 5.6.1 prevents %ENV + #settings to be inherited by process created with + #Win32::Process::Create. the test works fine if APACHE_TEST_HOSTNAME + #is set in the command shell environment + delete $test{'host'}; +} + +plan tests => (keys %test) * 1, need_module('env', 'include'); + +my ($actual, $expected); +foreach (sort keys %test) { + $expected = $test{$_}; + sok { + $actual = GET_BODY "/modules/env/$_.shtml"; + $actual =~ s/[\r\n]+$//s; + print "# $_: /modules/env/$_.shtml\n", + "# $_: EXPECT ->$expected<- ACTUAL ->$actual<-\n"; + return $actual eq $expected; + }; +} diff --git a/debian/perl-framework/t/modules/expires.t b/debian/perl-framework/t/modules/expires.t new file mode 100644 index 0000000..5c992c2 --- /dev/null +++ b/debian/perl-framework/t/modules/expires.t @@ -0,0 +1,307 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Time::Local; + +## mod_expires tests +## +## extra.conf.in: +## +## <Directory @SERVERROOT@/htdocs/modules/expires> +## ExpiresActive On +## ExpiresDefault "modification plus 10 years 6 months 2 weeks 3 days 12 hours 30 minutes 19 seconds" +## ExpiresByType text/plain M60 +## ExpiresByType image/gif A120 +## ExpiresByType image/jpeg A86400 +## </Directory> +## + +## calculate "modification plus 10 years 6 months 2 weeks 3 days 12 hours 30 minutes 19 seconds" +my $expires_default = calculate_seconds(10,6,2,3,12,30,19); + +my $htdocs = Apache::Test::vars('documentroot'); +my $htaccess = "$htdocs/modules/expires/htaccess/.htaccess"; +my @page = qw(index.html text.txt image.gif foo.jpg); +my @types = qw(text/plain image/gif image/jpeg); +my @directive = qw(ExpiresDefault ExpiresByType); + +## first the settings in extra.conf.in (server level) +my %exp = default_exp(); + +my %names = + ( + 'Date' => 'access', + 'Expires' => 'expires', + 'Last-Modified' => 'modified', + 'Content-Type' => 'type', + ); + +my %month = (); +my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); +@month{@months} = 0..@months-1; + +plan tests => (@page * 2) + ((((@page * 3) * @types) + @page) * 2) + @page, + have_module 'expires'; + +foreach my $page (@page) { + my $head = HEAD_STR "/modules/expires/$page"; + $head = '' unless defined $head; + print "# debug: $page\n$head\n"; + ok ($head =~ /^HTTP\/1\.[1|0] 200 OK/); + ok expires_test(1,$head); +} + +unlink $htaccess if -e $htaccess; +## with no .htaccess file, everything should be inherited here ## +foreach my $page (@page) { + my $head = HEAD_STR "/modules/expires/htaccess/$page"; + ok expires_test(1,$head); +} + +## testing with .htaccess ## +foreach my $on_off (qw(On Off)) { + + my $ExpiresActive = "ExpiresActive $on_off\n"; + write_htaccess($ExpiresActive); + %exp = default_exp(); + + ## if ExpiresActive is 'On', everything else will be inherited ## + foreach my $page (@page) { + my $head = HEAD_STR "/modules/expires/htaccess/$page"; + print "# ---\n# $ExpiresActive"; + ok expires_test(($on_off eq 'On'),$head); + } + + foreach my $t (@types) { + + my ($head, $directive_string, $gmsec, $a_m, + $ExpiresDefault, $ExpiresByType); + + ## testing with just ExpiresDefault directive ## + $a_m = (qw(A M))[int(rand(2))]; + ($gmsec, $ExpiresDefault) = get_rand_time_str($a_m); + %exp = default_exp(); + set_exp('default', "$a_m$gmsec"); + $directive_string = $ExpiresActive . + "ExpiresDefault $ExpiresDefault\n"; + write_htaccess($directive_string); + foreach my $page (@page) { + $head = HEAD_STR "/modules/expires/htaccess/$page"; + print "#---\n# $directive_string"; + ok expires_test(($on_off eq 'On'), $head); + } + + ## just ExpiresByType directive ## + $a_m = (qw(A M))[int(rand(2))]; + ($gmsec, $ExpiresByType) = get_rand_time_str($a_m); + %exp = default_exp(); + set_exp($t, "$a_m$gmsec"); + $directive_string = $ExpiresActive . + "ExpiresByType $t $ExpiresByType\n"; + write_htaccess($directive_string); + foreach my $page (@page) { + $head = HEAD_STR "/modules/expires/htaccess/$page"; + print "# ---\n# $directive_string"; + ok expires_test(($on_off eq 'On'), $head); + } + + ## both ## + $a_m = (qw(A M))[int(rand(2))]; + ($gmsec, $ExpiresDefault) = get_rand_time_str($a_m); + %exp = default_exp(); + set_exp('default', "$a_m$gmsec"); + $a_m = (qw(A M))[int(rand(2))]; + ($gmsec, $ExpiresByType) = get_rand_time_str($a_m); + set_exp($t, "$a_m$gmsec"); + $directive_string = $ExpiresActive . + "ExpiresDefault $ExpiresDefault\n" . + "ExpiresByType $t $ExpiresByType\n"; + write_htaccess($directive_string); + foreach my $page (@page) { + $head = HEAD_STR "/modules/expires/htaccess/$page"; + print "# ---\n# $directive_string"; + ok expires_test(($on_off eq 'On'), $head); + } + } +} + +## clean up ## +unlink $htaccess if -e $htaccess; + +sub set_exp { + my $key = shift; + my $exp = shift; + + if ($key eq 'all') { + foreach (keys %exp) { + $exp{$_} = $exp; + } + } else { + $exp{$key} = $exp; + } +} + +sub get_rand_time_str { + my $a_m = shift; + my ($y, $m, $w, $d, $h, $mi, $s, $rand_time_str); + $y = int(rand(2)); + $m = int(rand(4)); + $w = int(rand(3)); + $d = int(rand(20)); + $h = int(rand(9)); + $mi = int(rand(50)); + $s = int(rand(50)); + my $gmsec = calculate_seconds($y,$m,$w,$d,$h,$mi,$s); + + ## whether to write it out or not ## + if (int(rand(2))) { + ## write it out ## + + ## access or modification ## + if ($a_m eq 'A') { + $rand_time_str = "\"access plus"; + } else { + $rand_time_str = "\"modification plus"; + } + + $rand_time_str .= " $y years" if $y; + $rand_time_str .= " $m months" if $m; + $rand_time_str .= " $w weeks" if $w; + $rand_time_str .= " $d days" if $d; + $rand_time_str .= " $h hours" if $h; + $rand_time_str .= " $mi minutes" if $mi; + $rand_time_str .= " $s seconds" if $s; + $rand_time_str .= "\""; + + } else { + ## easy format ## + $rand_time_str = "$a_m$gmsec"; + } + + return ($gmsec, $rand_time_str); +} + +sub write_htaccess { + open (HT, ">$htaccess") or die "cant open $htaccess: $!"; + print HT shift; + close(HT); +} + +sub expires_test { + my $expires_active = shift; + my $head_str = shift; + my %headers = (); + + foreach my $header (split /\n/, $head_str) { + if ($header =~ /^([\-\w]+): (.*)$/) { + print "# debug: [$1] [$2]\n"; + $headers{$names{$1}} = $2 if exists $names{$1}; + } + } + + ## expires header should not exist if ExpiresActive is Off ## + return !$headers{expires} unless ($expires_active); + + for my $h (grep !/^type$/, values %names) { + print "# debug: $h @{[$headers{$h}||'']}\n"; + if ($headers{$h}) { + $headers{$h} = convert_to_time($headers{$h}) || 0; + } else { + $headers{$h} = 0; + } + print "# debug: $h $headers{$h}\n"; + } + + my $exp_conf = ''; + if ( exists $exp{ $headers{type} } and $exp{ $headers{type} }) { + $exp_conf = $exp{ $headers{type} }; + } else { + $exp_conf = $exp{'default'}; + } + + ## if expect is set to '0', Expire header should not exist. ## + if ($exp_conf eq '0') { + return !$headers{expires}; + } + + my $expected = ''; + my $exp_type = ''; + if ($exp_conf =~ /^([A|M])(\d+)$/) { + $exp_type = $1; + $expected = $2; + ## With modification date as base expire times can be in the past + ## Correct behaviour for the server in this case is to set expires + ## time equal to access time. + if (($exp_type eq 'M') + && ($headers{access} > $headers{modified} + $expected)) { + $expected = $headers{access} - $headers{modified}; + } + } else { + print STDERR "\n\ndoom: $exp_conf\n\n"; + return 0; + } + + my $actual = 0; + if ($exp_type eq 'M') { + $actual = $headers{expires} - $headers{modified}; + } elsif ($exp_type eq 'A') { + $actual = $headers{expires} - $headers{access}; + } + + print "# debug: expected: $expected\n"; + print "# debug: actual : $actual\n"; + return ($actual == $expected); + +} + +sub convert_to_time { + my $timestr = shift; + return undef unless $timestr; + + my ($sec,$min,$hours,$mday,$mon,$year); + if ($timestr =~ /^\w{3}, (\d+) (\w{3}) (\d{4}) (\d{2}):(\d{2}):(\d{2}).*$/) { + $mday = $1; + $mon = $month{$2}; + $year = $3; + $hours = $4; + $min = $5; + $sec = $6; + } + + return undef + unless + defined $sec && + defined $min && + defined $hours && + defined $mday && + defined $mon && + defined $year; + + return Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year); +} + +sub calculate_seconds { + ## takes arguments: + ## years, months, weeks, days, hours, minutes, seconds + my $exp_years = shift() * 60 * 60 * 24 * 365; + my $exp_months = shift() * 60 * 60 * 24 * 30; + my $exp_weeks = shift() * 60 * 60 * 24 * 7; + my $exp_days = shift() * 60 * 60 * 24; + my $exp_hours = shift() * 60 * 60; + my $exp_minutes = shift() * 60; + return $exp_years + $exp_months + $exp_weeks + + $exp_days + $exp_hours + $exp_minutes + shift; +} + +sub default_exp { + ## set the exp hash to the defaults as defined in the conf file. + return + ( + 'default' => "M$expires_default", + 'text/plain' => 'M60', + 'image/gif' => 'A120', + 'image/jpeg' => 'A86400' + ); +} diff --git a/debian/perl-framework/t/modules/ext_filter.t b/debian/perl-framework/t/modules/ext_filter.t new file mode 100644 index 0000000..79622ae --- /dev/null +++ b/debian/perl-framework/t/modules/ext_filter.t @@ -0,0 +1,40 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +Apache::TestRequest::user_agent(keep_alive => 1); + +my $iters = 10; +if (!have_min_apache_version("2.4.0")) { + # Not interested in 2.2 + $iters = 0; +} +my $tests = 4 + $iters * 2; + +plan tests => $tests, need + need_module('ext_filter'), need_cgi; + +my $content = GET_BODY("/apache/extfilter/out-foo/foobar.html"); +chomp $content; +ok t_cmp($content, "barbar", "sed output filter"); + +$content = GET_BODY("/apache/extfilter/out-slow/foobar.html"); +chomp $content; +ok t_cmp($content, "foobar", "slow filter process"); + +my $r = POST "/apache/extfilter/in-foo/modules/cgi/perl_echo.pl", content => "foobar\n"; +ok t_cmp($r->code, 200, "echo worked"); +ok t_cmp($r->content, "barbar\n", "request body filtered"); + + + +# PR 60375 -- appears to be intermittent failure with 2.4.x ... but works with trunk? +foreach (1..$iters) { + $r = POST "/apache/extfilter/out-limit/modules/cgi/perl_echo.pl", content => "foo and bar\n"; + + ok t_cmp($r->code, 413, "got 413 error"); + ok t_cmp($r->content, qr/413 Request Entity Too Large/, "got 413 error body"); +} diff --git a/debian/perl-framework/t/modules/filter.t b/debian/perl-framework/t/modules/filter.t new file mode 100644 index 0000000..3ab7796 --- /dev/null +++ b/debian/perl-framework/t/modules/filter.t @@ -0,0 +1,25 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_cmp t_write_file); +use File::Spec; + +my @testcases = ( + ['/modules/cgi/xother.pl' => 'HELLOWORLD'], + ['/modules/filter/bytype/test.txt' => 'HELLOWORLD'], + ['/modules/filter/bytype/test.xml' => 'HELLOWORLD'], + ['/modules/filter/bytype/test.css' => 'helloworld'], + ['/modules/filter/bytype/test.html' => 'helloworld'], +); + +plan tests => scalar @testcases, need need_cgi, + need_module('mod_filter'), + need_module('mod_case_filter'); + +foreach my $t (@testcases) { + my $r = GET_BODY($t->[0]); + chomp $r; + ok t_cmp($r, $t->[1]); +} diff --git a/debian/perl-framework/t/modules/headers.t b/debian/perl-framework/t/modules/headers.t new file mode 100644 index 0000000..c72c690 --- /dev/null +++ b/debian/perl-framework/t/modules/headers.t @@ -0,0 +1,311 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +## +## mod_headers tests +## + +my $htdocs = Apache::Test::vars('documentroot'); +my $htaccess = "$htdocs/modules/headers/htaccess/.htaccess"; +my @header_types = ('set', 'append', 'add', 'unset'); + +my @testcases = ( + ## htaccess + ## Header to set in the request + ## Expected result + + # echo + [ + "Header echo Test-Header\nHeader echo ^Aaa\$\nHeader echo ^Aa\$", + [ 'Test-Header' => 'value', 'Aaa' => 'b' , 'Aa' => 'bb' ], + [ 'Test-Header' => 'value', 'Aaa' => 'b' , 'Aa' => 'bb' ], + ], + [ + "Header echo Test-Header\nHeader echo XXX\nHeader echo ^Aa\$", + [ 'Test-Header' => 'foo', 'aaa' => 'b', 'aa' => 'bb' ], + [ 'Test-Header' => 'foo', 'aa' => 'bb' ], + ], + [ + "Header echo Test-Header.*", # regex + [ 'Test-Header' => 'foo', 'Test-Header1' => 'value1', 'Test-Header2' => 'value2' ], + [ 'Test-Header' => 'foo', 'Test-Header1' => 'value1', 'Test-Header2' => 'value2' ], + ], + # edit + [ + "Header echo Test-Header\nHeader edit Test-Header foo bar", # sizeof(foo) = sizeof(bar) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'barfoo' ], + ], + [ + "Header echo Test-Header\nHeader edit Test-Header foo2 bar", # sizeof(foo2) > sizeof(bar) + [ 'Test-Header' => 'foo2foo2' ], + [ 'Test-Header' => 'barfoo2' ], + ], + [ + "Header echo Test-Header\nHeader edit Test-Header foo bar2", # sizeof(foo) < sizeof(bar2) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'bar2foo' ], + ], + # edit* + [ + "Header echo Test-Header\nHeader edit* Test-Header foo bar", # sizeof(foo) = sizeof(bar) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'barbar' ], + ], + [ + "Header echo Test-Header\nHeader edit* Test-Header foo2 bar", # sizeof(foo2) > sizeof(bar) + [ 'Test-Header' => 'foo2foo2' ], + [ 'Test-Header' => 'barbar' ], + ], + [ + "Header echo Test-Header\nHeader edit* Test-Header foo bar2", # sizeof(foo) < sizeof(bar2) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'bar2bar2' ], + ], + # merge + [ + "Header merge Test-Header foo", # missing header + [ ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header echo Test-Header\nHeader merge Test-Header foo", # already existing, same value + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header echo Test-Header\nHeader merge Test-Header foo", # already existing, same value, but with "" + [ 'Test-Header' => '"foo"' ], + [ 'Test-Header' => '"foo", foo' ], + ], + [ + "Header echo Test-Header\nHeader merge Test-Header bar", # already existing, different value + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo, bar' ], + ], + # setifempty + [ + "Header echo Test-Header\nHeader setifempty Test-Header bar", # already existing + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header echo Test-Header\nHeader setifempty Test-Header2 bar", # missing header + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo', 'Test-Header2' => 'bar' ], + ], + # env= + [ + "SetEnv MY_ENV\nHeader set Test-Header foo env=MY_ENV", # env defined + [ ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header set Test-Header foo env=!MY_ENV", # env NOT defined + [ ], + [ 'Test-Header' => 'foo' ], + ], + # expr= + [ + "Header set Test-Header foo \"expr=%{REQUEST_URI} =~ m#htaccess#\"", # expr + [ ], + [ 'Test-Header' => 'foo' ], + ], +); + +plan tests => + @header_types**4 + @header_types**3 + @header_types**2 + @header_types**1 + scalar @testcases * 2, + have_module 'headers'; + +# Test various configurations +foreach my $header1 (@header_types) { + + ok test_header($header1); + foreach my $header2 (@header_types) { + + ok test_header($header1, $header2); + foreach my $header3 (@header_types) { + + ok test_header($header1, $header2, $header3); + foreach my $header4 (@header_types) { + + ok test_header($header1, $header2, $header3, $header4); + + } + + } + + } + +} + +# Test some other Header directives, including regex +my $ua = LWP::UserAgent->new(); +my $hostport = Apache::TestRequest::hostport(); +foreach my $t (@testcases) { + test_header2($t); +} + +## clean up ## +unlink $htaccess; + +sub test_header { + my @h = @_; + my $test_header = "Test-Header"; + my (@expected_value, @actual_value) = ((),()); + my ($expected_exists, $expected_value, $actual_exists) = (0,0,0); + + open (HT, ">$htaccess"); + foreach (@h) { + + ## create a unique header value ## + my $r = int(rand(9999)); + my $test_value = "mod_headers test header value $r"; + + ## evaluate $_ to come up with expected results + ## and write out the .htaccess file + if ($_ eq 'unset') { + print HT "Header $_ $test_header\n"; + @expected_value = (); + $expected_exists = 0; + $expected_value = 0; + } else { + print HT "Header $_ $test_header \"$test_value\"\n"; + + if ($_ eq 'set') { + + ## should 'set' work this way? + ## currently, even if there are multiple headers + ## with the same name, 'set' blows them all away + ## and sets a single one with this value. + @expected_value = (); + $expected_exists = 1; + + $expected_value = $test_value; + } elsif ($_ eq 'append') { + + ## should 'append' work this way? + ## currently, if there are multiple headers + ## with the same name, 'append' appends the value + ## to the FIRST instance of that header. + if (@expected_value) { + $expected_value[0] .= ", $test_value"; + + } elsif ($expected_value) { + $expected_value .= ", $test_value"; + } else { + $expected_value = $test_value; + } + $expected_exists++ unless $expected_exists; + + } elsif ($_ eq 'add') { + if ($expected_value) { + push(@expected_value, $expected_value); + $expected_value = 0; + } + $expected_value = $test_value; + $expected_exists++; + } + } + } + close(HT); + + push(@expected_value, $expected_value) if $expected_value; + + ## get the actual headers ## + my $h = HEAD_STR "/modules/headers/htaccess/"; + + ## parse response headers looking for our headers + ## and save the value(s) + my $exists = 0; + my $actual_value; + foreach my $head (split /\n/, $h) { + if ($head =~ /^$test_header: (.*)$/) { + $actual_exists++; + push(@actual_value, $1); + } + } + + ## ok if 'unset' and there are no headers ## + return 1 if ($actual_exists == 0 and $expected_exists == 0); + + if (($actual_exists == $expected_exists) && + (@actual_value == @expected_value)) { + + ## go through each actual header ## + foreach my $av (@actual_value) { + my $matched = 0; + + ## and each expected header ## + for (my $i = 0 ; $i <= @expected_value ; $i++) { + + if ($av eq $expected_value[$i]) { + + ## if we match actual and expected, + ## record it, and remove the header + ## from the expected list + $matched++; + splice(@expected_value, $i, 1); + last; + + } + } + + ## not ok if actual value does not match expected ## + return 0 unless $matched; + } + + ## if we made it this far, all is well. ## + return 1; + + } else { + + ## not ok if the number of expected and actual + ## headers do not match + return 0; + + } +} + +sub test_header2 { + my @test = @_; + my $h = HTTP::Headers->new; + + print "\n\n\n"; + for (my $i = 0; $i < scalar @{$test[0][1]}; $i += 2) { + print "Header sent n°" . $i/2 . ":\n"; + print " header: " . $test[0][1][$i] . "\n"; + print " value: " . $test[0][1][$i+1] . "\n"; + $h->header($test[0][1][$i] => $test[0][1][$i+1]); + } + + open (HT, ">$htaccess"); + print HT $test[0][0]; + close(HT); + + ## + my $r = HTTP::Request->new('GET', "http://$hostport/modules/headers/htaccess/", $h); + my $res = $ua->request($r); + ok t_cmp($res->code, 200, "Checking return code is '200'"); + + my $isok = 1; + for (my $i = 0; $i < scalar @{$test[0][2]}; $i += 2) { + print "\n"; + print "Header received n°" . $i/2 . ":\n"; + print " header: " . $test[0][2][$i] . "\n"; + print " expected: " . $test[0][2][$i+1] . "\n"; + if ($res->header($test[0][2][$i])) { + print " received: " . $res->header($test[0][2][$i]) . "\n"; + } else { + print " received: <undefined>\n"; + } + $isok = $isok && $res->header($test[0][2][$i]) && $test[0][2][$i+1] eq $res->header($test[0][2][$i]); + } + print "\nResponse received is:\n" . $res->as_string; + + ok $isok; +} diff --git a/debian/perl-framework/t/modules/heartbeat.t b/debian/perl-framework/t/modules/heartbeat.t new file mode 100644 index 0000000..d9f6f18 --- /dev/null +++ b/debian/perl-framework/t/modules/heartbeat.t @@ -0,0 +1,30 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw/t_start_error_log_watch t_finish_error_log_watch/; + +my $r; +my $line; +my $count = 0; +my $nb_seconds = 5; +# Because of timing, we may see less than what could be expected +my $nb_expected = $nb_seconds - 2; + +plan tests => 1, sub { need_module('mod_heartbeat', 'mod_heartmonitor') && !need_apache_mpm('prefork') }; + +# Give some time to the heart to beat a few times +t_start_error_log_watch(); +sleep($nb_seconds); +my @loglines = t_finish_error_log_watch(); + +# Heartbeat sent by mod_heartbeat and received by mod_heartmonitor are logged with DEBUG AH02086 message +foreach $line (@loglines) { + if ($line =~ "AH02086") { + $count++; + } +} + +print "Expecting at least " . $nb_expected . " heartbeat ; Seen: " . $count . "\n"; +ok($count >= $nb_expected); diff --git a/debian/perl-framework/t/modules/http2.t b/debian/perl-framework/t/modules/http2.t new file mode 100644 index 0000000..02725f5 --- /dev/null +++ b/debian/perl-framework/t/modules/http2.t @@ -0,0 +1,535 @@ +use strict; +use warnings FATAL => 'all'; + +use Net::SSLeay; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +my $tls_version_suite = 4; +my $num_suite = 24; +my $vhost_suite = 4; +my $total_tests = 2 * $num_suite + $vhost_suite + $tls_version_suite; + +Net::SSLeay::initialize(); + +my $sni_available = Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x01000000; +my $alpn_available = $sni_available && exists &Net::SSLeay::CTX_set_alpn_protos; + +plan tests => $total_tests, need 'Protocol::HTTP2::Client', 'AnyEvent', + need_module 'http2', need_min_apache_version('2.4.17'); + +# Check support for TLSv1_2 and later + +Apache::TestRequest::set_ca_cert(); + +# If we can, detect the SSL protocol the server speaks and do not run +# against anything pre-TLSv1.2 +# On some setups, we do not get a socket here (for not understood reasons) +# and run the tests. Better to fail visibly then. +# +my $tls_modern = 1; +my $tls_version = 0; + +my $sock = Apache::TestRequest::vhost_socket('h2'); +if ($sock) { + ok ($sock->connected); + + my $req = "GET / HTTP/1.1\r\n". + "Host: " . Apache::TestRequest::hostport() . "\r\n". + "\r\n"; + + ok $sock->print($req); + my $line = Apache::TestRequest::getline($sock) || ''; + ok t_cmp($line, qr{^HTTP/1\.. 200}, "read first response-line"); + $tls_version = $sock->get_sslversion(); + ok t_cmp($tls_version, qr{^(SSL|TLSv\d(_\d)?$)}, "TLS version in use"); + + if ($tls_version =~ /^(SSL|TLSv1(|_0|_1)$)/) { + print STDOUT "Disabling TLS tests due to TLS version $tls_version\n"; + $tls_modern = 0; + } +} +else { + skip "skipping test as socket not defined" foreach(1..$tls_version_suite); +} + +Apache::TestRequest::module("http2"); + +my $config = Apache::Test::config(); +my $host = $config->{vhosts}->{h2c}->{servername}; +my $port = $config->{vhosts}->{h2c}->{port}; + +my $shost = $config->{vhosts}->{h2}->{servername}; +my $sport = $config->{vhosts}->{h2}->{port}; +my $serverdir = $config->{vars}->{t_dir}; +my $htdocs = $serverdir . "/htdocs"; + +require Protocol::HTTP2::Client; +use AnyEvent; +use AnyEvent::Socket; +use AnyEvent::Handle; +use Net::SSLeay; +use AnyEvent::TLS; +use Carp qw( croak ); + +no warnings 'redefine'; +no strict 'refs'; +{ + my $old_ref = \&{ 'AnyEvent::TLS::new' }; + *{ 'AnyEvent::TLS::new' } = sub { + my ( $class, %param ) = @_; + + my $self = $old_ref->( $class, %param ); + + $self->{host_name} = $param{host_name} + if exists $param{host_name}; + + $self; + }; +} + +{ + my $old_ref = \&{ 'AnyEvent::TLS::_get_session' }; + *{ 'AnyEvent::TLS::_get_session' } = sub($$;$$) { + my ($self, $mode, $ref, $cn) = @_; + + my $session = $old_ref->( @_ ); + + if ( $mode eq 'connect' ) { + if ( $self->{host_name} ) { + print 'setting host_name to ' . $self->{host_name}; + Net::SSLeay::set_tlsext_host_name( $session, $self->{host_name} ); + } + } + + $session; + }; +} + + +sub connect_and_do { + my %args = ( + @_ + ); + my $scheme = $args{ctx}->{scheme}; + my $host = $args{ctx}->{host}; + my $port = $args{ctx}->{port}; + my $client = $args{ctx}->{client}; + my $host_name = $args{ctx}->{host_name}; + my $w = AnyEvent->condvar; + + tcp_connect $host, $port, sub { + my ($fh) = @_ or do { + print "connection failed: $!\n"; + $w->send; + return; + }; + + my $tls; + my $tls_ctx; + if ($scheme eq 'https') { + $tls = "connect"; + eval { + # ALPN (Net-SSLeay > 1.55, openssl >= 1.0.1) + if ( $alpn_available ) { + $tls_ctx = AnyEvent::TLS->new( method => "TLSv1_2", + host_name => $host_name ); + Net::SSLeay::CTX_set_alpn_protos( $tls_ctx->ctx, ['h2'] ); + } + else { + $tls_ctx = AnyEvent::TLS->new( host_name => $host_name ); + } + }; + if ($@) { + print "Some problem with SSL CTX: $@\n"; + $w->send; + return; + } + } + + my $handle; + $handle = AnyEvent::Handle->new( + fh => $fh, + tls => $tls, + tls_ctx => $tls_ctx, + autocork => 1, + on_error => sub { + $_[0]->destroy; + print "connection error\n"; + $w->send; + }, + on_eof => sub { + $handle->destroy; + $w->send; + } + ); + + # First write preface to peer + while ( my $frame = $client->next_frame ) { + $handle->push_write($frame); + } + + $handle->on_read(sub { + my $handle = shift; + + $client->feed( $handle->{rbuf} ); + $handle->{rbuf} = undef; + + while ( my $frame = $client->next_frame ) { + $handle->push_write($frame); + } + + # Terminate connection if all done + $handle->push_shutdown if $client->shutdown; + }); + }; + $w->recv; + +} + +################################################################################ +# +# Add a request to the client, will be started whenever a STREAM to +# the server is available. +# +sub add_request { + my ($scheme, $client, $host, $port); + my %args = ( + method => 'GET', + headers => [], + rc => 200, + on_done => sub { + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $req = $args{request}; + my $resp = $args{response}; + my $hr = $resp->{headers}; + my %headers = @$hr; + ok t_cmp($headers{':status'}, $req->{rc}, + "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}"); + }, + @_ + ); + $client = $args{ctx}->{client}; + $scheme = $args{ctx}->{scheme}; + $host = $args{ctx}->{host}; + $port = $args{ctx}->{port}; + + $client->request( + ':scheme' => $scheme, + ':authority' => $args{authority} || $host . ':' . $port, + ':path' => $args{path}, + ':method' => $args{method}, + headers => $args{headers}, + on_done => sub { + my ($headers, $data) = @_; + $args{on_done}( + ctx => $args{ctx}, + request => \%args, + response => { headers => \@$headers, data => $data } + ); + } + ); +} + +################################################################################ +# +# Add a list of request that will be processed in order. Only when the previous +# request is done, will a new one be started. +# +sub add_sequential { + my ($scheme, $client, $host, $port); + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $requests = $args{requests}; + + $client = $args{ctx}->{client}; + $scheme = $args{ctx}->{scheme}; + $host = $args{ctx}->{host}; + $port = $args{ctx}->{port}; + + my $request = shift @$requests; + + if ($request) { + my %r = ( + method => 'GET', + headers => [], + rc => 200, + on_done => sub { + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $req = $args{request}; + my $resp = $args{response}; + my $hr = $resp->{headers}; + my %headers = @$hr; + ok t_cmp($headers{':status'}, $req->{rc}, + "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}"); + }, + %$request + ); + + print "test case: $r{descr}: $r{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$r{path}\n"; + $client->request( + ':scheme' => $scheme, + ':authority' => $r{authority} || $host . ':' . $port, + ':path' => $r{path}, + ':method' => $r{method}, + headers => $r{headers}, + on_done => sub { + my ($headers, $data) = @_; + $r{on_done}( + ctx => ${ctx}, + request => \%r, + response => { headers => \@$headers, data => $data } + ); + add_sequential( + ctx => $ctx, + requests => $requests + ); + } + ); + } +} + +sub cmp_content_length { + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $req = $args{request}; + my $resp = $args{response}; + my $hr = $resp->{headers}; + my %headers = @$hr; + ok t_cmp($headers{':status'}, $req->{rc}, "response status"); + ok t_cmp(length $resp->{data}, $req->{content_length}, "content-length"); +} + +sub cmp_content { + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $req = $args{request}; + my $resp = $args{response}; + my $hr = $resp->{headers}; + my %headers = @$hr; + ok t_cmp($headers{':status'}, $req->{rc}, "response status"); + ok t_cmp($resp->{data}, $req->{content}, "content comparision"); +} + +sub cmp_file_response { + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $req = $args{request}; + my $resp = $args{response}; + my $hr = $resp->{headers}; + my %headers = @$hr; + ok t_cmp($headers{':status'}, $req->{rc}, "response status"); + open(FILE, "<$htdocs$req->{path}") or die "cannot open $req->{path}"; + undef $/; + my $content = <FILE>; + close(FILE); + ok t_is_equal($resp->{data}, $content); +} + +sub check_redir { + my %args = ( @_ ); + my $ctx = $args{ctx}; + my $req = $args{request}; + my $resp = $args{response}; + my $hr = $resp->{headers}; + my %headers = @$hr; + ok t_cmp($headers{':status'}, 302, "response status"); + ok t_cmp( + $headers{location}, + "$ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{redir_path}", + "location header" + ); +} + +################################################################################ +# +# Perform common tests to h2c + h2 hosts +# +sub do_common { + my %args = ( + scheme => 'http', + host => 'localhost', + port => 80, + @_ + ); + my $true_tls = ($args{scheme} eq 'https' and $sni_available); + + $args{client} = Protocol::HTTP2::Client->new( upgrade => 0 ); + + my $r = [ + { + descr => 'TC0001, expecting 200', + path => '/' + }, + { + descr => 'TC0002, expecting 404', + rc => 404, + path => '/not_here' + }, + { + descr => 'TC0005, cmp index.html file', + path => '/modules/h2/index.html', + on_done => \&cmp_file_response + }, + { + descr => 'TC0006, cmp image file', + path => '/modules/h2/003/003_img.jpg', + on_done => \&cmp_file_response + }, + ]; + + if (have_module 'mod_rewrite') { + push @$r, { + descr => 'TC0007, rewrite handling', + path => '/modules/h2/latest.tar.gz', + redir_path => "/modules/h2/xxx-1.0.2a.tar.gz", + on_done => \&check_redir + } + } + else { + skip "skipping test as mod_rewrite not available" foreach(1..2); + } + + if (have_cgi) { + # my $sni_host = $true_tls? 'localhost' : ''; + my $content = <<EOF; +<html><body> +<h2>Hello World!</h2> +</body></html> +EOF + + push @$r, { + descr => 'TC0008, hello.pl with ssl vars', + path => '/modules/h2/hello.pl', + content => $content, + on_done => \&cmp_content, + }; + + $content = <<EOF; +<html><body> +<p>No query was specified.</p> +</body></html> +EOF + push @$r, { + descr => 'TC0009, necho.pl without arguments', + path => '/modules/h2/necho.pl', + content => $content, + rc => 400, + on_done => \&cmp_content, + }; + push @$r, { + descr => 'TC0010, necho.pl 2x10', + path => '/modules/h2/necho.pl?count=2&text=0123456789', + content => "01234567890123456789", + on_done => \&cmp_content, + }; + push @$r, { + descr => 'TC0011, necho.pl 10x10', + path => '/modules/h2/necho.pl?count=10&text=0123456789', + content_length => 100, + on_done => \&cmp_content_length, + }; + push @$r, { + descr => 'TC0012, necho.pl 100x10', + path => '/modules/h2/necho.pl?count=100&text=0123456789', + content_length => 1000, + on_done => \&cmp_content_length, + }; + push @$r, { + descr => 'TC0013, necho.pl 1000x10', + path => '/modules/h2/necho.pl?count=1000&text=0123456789', + content_length => 10000, + on_done => \&cmp_content_length, + }; + push @$r, { + descr => 'TC0014, necho.pl 10000x10', + path => '/modules/h2/necho.pl?count=10000&text=0123456789', + content_length => 100000, + on_done => \&cmp_content_length, + }; + push @$r, { + descr => 'TC0015, necho.pl 100000x10', + path => '/modules/h2/necho.pl?count=100000&text=0123456789', + content_length => 1000000, + on_done => \&cmp_content_length, + }; + } + else { + skip "skipping test as mod_cgi not available" foreach(1..16); + } + + add_sequential( + ctx => \%args, + requests => $r + ); + connect_and_do( ctx => \%args ); +} + +################################################################################ +# +# Perform tests for virtual host setups, requires a client with SNI+ALPN +# +sub do_vhosts { + my %args = ( + scheme => 'http', + host => 'localhost', + port => 80, + @_ + ); + $args{client} = Protocol::HTTP2::Client->new( upgrade => 0 ); + + my $r = [ + { + descr => 'VHOST000, expecting 200', + path => '/' + }, + { + descr => 'VHOST001, expect 404 or 421 (using Host:)', + rc => 404, + path => '/misdirected', + header => [ 'host' => 'noh2.example.org' . $args{port} ] + }, + { + descr => 'VHOST002, expect 421 (using :authority)', + rc => 421, + path => '/misdirected', + authority => 'noh2.example.org:' . $args{port} + }, + { + descr => 'VHOST003, expect 421 ', + rc => (have_min_apache_version('2.4.18')? 404 : 421), + path => '/misdirected', + authority => 'test.example.org:' . $args{port} + }, + ]; + + add_sequential( + ctx => \%args, + requests => $r + ); + connect_and_do( ctx => \%args ); +} + +################################################################################ +# +# Bring it on +# +do_common( 'scheme' => 'http', 'host' => $host, 'port' => $port ); +if ($tls_modern) { + do_common( 'scheme' => 'https', 'host' => $shost, 'port' => $sport ); +} else { + skip "skipping test as TLS version '$tls_version' is not supported" foreach(1..$num_suite); +} +if ($sni_available) { + if ($tls_modern) { + do_vhosts( 'scheme' => 'https', 'host' => $shost, 'port' => $sport, host_name => "$shost:${sport}" ); + } else { + skip "skipping test as TLS version '$tls_version' is not supported" foreach(1..$vhost_suite); + } +} else { + skip "skipping test as SNI not available" foreach(1..$vhost_suite); +} diff --git a/debian/perl-framework/t/modules/include.t b/debian/perl-framework/t/modules/include.t new file mode 100644 index 0000000..9ff2411 --- /dev/null +++ b/debian/perl-framework/t/modules/include.t @@ -0,0 +1,661 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +use File::Spec::Functions qw(catfile splitpath); + +Apache::TestRequest::scheme('http'); #ssl not listening on this vhost +Apache::TestRequest::module('mod_include'); #use this module's port + +use constant WINFU => Apache::TestConfig::WINFU; + +## mod_include tests +my($res, $str, $doc); +my $dir = "/modules/include/"; +my $have_apache_1 = have_apache 1; +my $have_apache_2 = have_apache 2; +my $have_apache_21 = have_min_apache_version "2.1.0"; +my $have_apache_20 = $have_apache_2 && ! $have_apache_21; +my $htdocs = Apache::Test::vars('documentroot'); + +# these match the SSI files with their expected results. +# the expectations are set by the current 2.1 mod_include +# implementation. + +my %test = ( +"echo.shtml" => "echo.shtml", +"set.shtml" => "set works", +"comment.shtml" => "No comment here", +"include1.shtml" => "inc-two.shtml body include.shtml body", +"include2.shtml" => "inc-two.shtml body include.shtml body", +"include3.shtml" => "inc-two.shtml body inc-one.shtml body ". + "include.shtml body", +"include4.shtml" => "inc-two.shtml body inc-one.shtml body ". + "include.shtml body", +"include5.shtml" => "inc-two.shtml body inc-one.shtml body ". + "inc-three.shtml body include.shtml body", +"include6.shtml" => "inc-two.shtml body inc-one.shtml body ". + "inc-three.shtml body include.shtml body", +"foo.shtml" => "[an error occurred while processing this ". + "directive] foo.shtml body", +"foo1.shtml" => "[an error occurred while processing this ". + "directive] foo.shtml body", +"foo2.shtml" => "[an error occurred while processing this ". + "directive] foo.shtml body", +"encode.shtml" => "\# \%\^ \%23\%20\%25\%5e", +"errmsg1.shtml" => "errmsg", +"errmsg2.shtml" => "errmsg", +"errmsg3.shtml" => "errmsg", +"errmsg4.shtml" => "pass errmsg", +"errmsg5.shtml" => "<!-- pass -->", +"if1.shtml" => "pass", +"if2.shtml" => "pass pass", +"if3.shtml" => "pass pass pass", +"if4.shtml" => "pass pass", +"if5.shtml" => "pass pass pass", +"if6.shtml" => "[an error occurred while processing this ". + "directive]", +"if7.shtml" => "[an error occurred while processing this ". + "directive]", +"if8.shtml" => "pass", +"if9.shtml" => "pass pass", +"if10.shtml" => "pass", +"if11.shtml" => "pass", +"big.shtml" => "hello pass pass pass hello", +"newline.shtml" => "inc-two.shtml body", +"inc-rfile.shtml" => "inc-extra2.shtml body inc-extra1.shtml body ". + "inc-rfile.shtml body", +"inc-rvirtual.shtml" => "inc-extra2.shtml body inc-extra1.shtml body ". + "inc-rvirtual.shtml body", +"extra/inc-bogus.shtml" => "[an error occurred while processing this ". + "directive] inc-bogus.shtml body", +"abs-path.shtml" => "inc-extra2.shtml body inc-extra1.shtml body ". + "abs-path.shtml body", +"parse1.shtml" => "-->", +"parse2.shtml" => '"', +"regex.shtml" => "(none) 1 (none)", +"retagged1.shtml" => ["retagged1.shtml", "retagged1"], +"retagged2.shtml" => ["----retagged2.shtml", "retagged1"], +"echo1.shtml" => ["<!-- pass undefined echo -->", "echo1" ], +"echo2.shtml" => ["<!-- pass undefined echo --> pass config ". + " echomsg pass", "echo1"], +"echo3.shtml" => ['<!--#echo var="DOCUMENT_NAME" -->', "retagged1"], +"notreal.shtml" => "pass <!--", +"malformed.shtml" => "[an error occurred while processing this ". + "directive] malformed.shtml", +"exec/off/cmd.shtml" => "[an error occurred while processing this ". + "directive]", +"exec/on/cmd.shtml" => "pass", +"exec/off/cgi.shtml" => "[an error occurred while processing this ". + "directive]", +"exec/on/cgi.shtml" => "perl cgi", +"ranged-virtual.shtml" => "x"x32768, +"var128.shtml" => "x"x126 . "yz", # PR#32985 +"virtualq.shtml?foo=bar" => "foo=bar pass inc-two.shtml body foo=bar", # PR#12655 + +"inc-nego.shtml" => "index.html.en", # requires mod_negotiation +"mod_request/echo.shtml"=> "echo.shtml", +"mod_request/post.shtml?foo=bar&foo2=bar2" + => "GET foo: bar foo2: bar2", +"mod_request/post.shtml"=> "POST foo: bar foo2: bar2", # will be twice, only the first one succeed +); + +my %ap_expr_test = ( +"apexpr/if1.shtml" => "pass", +"apexpr/err.shtml" => "[an error occurred while processing this ". + "directive] err.shtml", +"apexpr/restrict.shtml" => "[an error occurred while processing this ". + "directive] restrict.shtml", +"apexpr/var.shtml" => "pass pass pass", +"apexpr/lazyvar.shtml" => "pass", +); + +if (have_min_apache_version "2.3.13") { + %test = (%test, %ap_expr_test); +} + +# now, assuming 2.1 has the proper behavior across the board, +# let's adjust our expectations for other versions + +# these tests are known to be broken in 2.0 +# we'll mark them as TODO tests in the hopes +# that the 2.1 fixes will be backported + +my %todo = ( +); + +# some behaviors will never be backported, for various +# reasons. these are the 1.3 legacy tests and expectations +my %legacy_1_3 = ( +"errmsg4.shtml" => "pass", +"malformed.shtml" => "", +"if6.shtml" => "", +"if7.shtml" => "", +); + +# 2.0 has no legacy tests at the moment +# but when it does, they will go here +my %legacy_2_0 = (); + +# ok, now that we have our hashes established, here are +# the manual tweaks +if ($have_apache_1) { + # apache 1.3 uses different semantics for some + # of the if.*shtml tests to achieve the same results + $test{"if8a.shtml"} = delete $test{"if8.shtml"}; + $test{"if9a.shtml"} = delete $test{"if9.shtml"}; + $test{"if10a.shtml"} = delete $test{"if10.shtml"}; + + # while other tests are for entirely new behaviors + # and don't make sense to test at all in 1.3 + delete $test{"echo1.shtml"}; + delete $test{"echo2.shtml"}; + delete $test{"echo3.shtml"}; + delete $test{"retagged1.shtml"}; + delete $test{"retagged2.shtml"}; + delete $test{"regex.shtml"}; + + # finally, these tests are only broken in 1.3 + $todo{"notreal.shtml"} = delete $test{"notreal.shtml"}; +} + +unless ($have_apache_20) { + # these tests are broken only in 2.0 - + # in 1.3 they work fine so shift them from %todo to %test + + # none at the moment, but the syntax here would be + # $test{"errmsg5.shtml"} = delete $todo{"errmsg5.shtml"}; +} + +unless (have_min_apache_version "2.0.53") { + # this test doesn't work in 2.0 yet but should work in 1.3 and 2.1 + delete $test{"ranged-virtual.shtml"}; +} + +unless ($have_apache_21) { + # apache 1.3 and 2.0 do not support these tests + delete $test{"echo2.shtml"}; +} + +unless (have_module 'mod_negotiation') { + delete $test{"inc-nego.shtml"}; +} + +# this test does not work on win32 (<!--#exec cmd="echo pass"-->) +if (WINFU) { + delete $test{'exec/on/cmd.shtml'}; +} + +my @patterns = ( + 'mod_include test', + 'Hello World', + 'footer', +); + +# with the tweaks out of the way, we can get on +# with planning the tests + +# first, total the number of hashed tests +# note that some legacy tests will redefine the main +# %test hash, so the total is not necessarily the sum +# of all the keys +my %tests = (); + +if ($have_apache_21) { + %tests = (%test, %todo); +} +elsif ($have_apache_2) { + %tests = (%test, %todo, %legacy_2_0); +} +else { + %tests = (%test, %todo, %legacy_1_3); +} + +# now for the TODO tests +my @todo = (); +unless ($have_apache_21) { + # if 1.3 or 2.0, dynamically determine which of %test + # will end up being TODO tests. + + my $counter = 0; + foreach my $test (sort keys %tests) { + $counter++; + push @todo, $counter if $todo{$test}; + } +} + +unless ($have_apache_2) { + # fsize comes immediately after the hashed tests + push @todo, (scalar keys %tests) + 1; +} + +# in addition to %tests, there are 1 mod_request expected failure, +# 1 fsize and 1 flastmod test, +# 1 GET test, 2 query string tests, 14 XBitHack tests and 14 +# tests that use mod_bucketeer to construct brigades for mod_include + +my $tests = (scalar keys %tests) + 1 + @patterns + 1 + 1 + 1 + 2 + 14 + 14; + +plan tests => $tests, + todo => \@todo, + need 'DateTime', need_lwp, need_module 'include'; + +foreach $doc (sort keys %tests) { + # do as much from %test as we can + if (ref $tests{$doc}) { + ok t_cmp(super_chomp(GET_BODY "$dir$doc", Host => $tests{$doc}[1]), + $tests{$doc}[0], + "GET $dir$doc" + ); + } + elsif ($doc =~ m/ranged/) { + if (have_cgi) { + ok t_cmp(GET_BODY("$dir$doc", Range => "bytes=0-"), + $tests{$doc}, + "GET $dir$doc with Range" + ); + } + else { + skip "Skipping virtual-range test; no cgi module", 1; + } + } + elsif ($doc =~ m/cgi/) { + if (have_cgi) { + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $tests{$doc}, + "GET $dir$doc" + ); + } + else { + skip "Skipping 'exec cgi' test; no cgi module.", 1; + } + } + elsif ($doc =~ m/mod_request.*\?/) { + # param in the url ==> use GET + if (have_cgi) { + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $tests{$doc}, + "GET $dir$doc" + ); + } + else { + skip "Skipping 'exec cgi' test; no cgi module.", 1; + } + } + elsif ($doc =~ m/mod_request/) { + # no param in the url ==> use POST with a content + if (have_cgi) { + ok t_cmp(super_chomp(POST_BODY "$dir$doc", content => "foo=bar&foo2=bar2"), + $tests{$doc}, + "POST $dir$doc" + ); + if ($doc =~ m/mod_request.*post/) { + # KeptBodySize is 32 + my $r = POST("$dir$doc", content => "foo=bar&foo2=bar2&foo3=bar3&foo4=bar4"); + ok t_cmp($r->code, 413, "sizeof(body) > KeptBodySize"); + } + } + else { + skip "Skipping 'exec cgi' test; no cgi module.", 2; + } + } + else { + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $tests{$doc}, + "GET $dir$doc" + ); + } +} + +### FLASTMOD/FSIZE TESTS + +# marked as TODO in 1.3 - hoping for a format backport +{ + my $file = catfile($htdocs, splitpath($dir), "size.shtml"); + my $size = (stat $file)[7]; + + # round perl's stat size for <!--#config sizefmt="abbrev"--> + # this assumes the size of size.shtml is such that it is + # rendered in K (which it is). if size.shtml is made much + # larger or smaller this formatting will need to change too + my $abbrev = sprintf("%.1fK", $size/1024); + + # and commify for <!--#config sizefmt="bytes"--> + my $bytes = commify($size); + + my $expected = join ' ', $bytes, $bytes, $abbrev, $abbrev; + + my $result = super_chomp(GET_BODY "${dir}size.shtml"); + + # trim output + $result =~ s/X//g; # the Xs were there just to pad the filesiez + $result = single_space($result); + + ok t_cmp("$result", + "$expected", + "GET ${dir}size.shtml" + ); +} + +unless(eval "require POSIX") { + skip "POSIX module not found", 1; +} +else { + # use DateTime and avoid the system locale messing things up + use DateTime; + # Only for checking, whether system strftime supports %s + use POSIX; + my $strftime_gnu = (POSIX::strftime("%s", gmtime()) eq '%s' ? 0 : 1); + + my $result = super_chomp(GET_BODY "${dir}file.shtml"); + $result = single_space($result); + + my $httpdtz = $1 if $result =~ /\w+, \d+-\w+-\d+ \d+:\d+:\d+ (\w+) /; + + my $file = catfile($htdocs, splitpath($dir), "file.shtml"); + my $mtime = (stat $file)[9]; + + my $dt = DateTime->from_epoch( epoch => $mtime, + locale => 'en_US', time_zone => $httpdtz||'UTC' ); + + my $expected = join ' ' => + $dt->strftime("%A, %B %e, %G"), + $dt->strftime("%A, %B %e, %G"), + $strftime_gnu ? $dt->strftime("%s") : '%s', + $strftime_gnu ? $dt->strftime("%s") : '%s'; + + # trim output + $expected = single_space($expected); + + ok t_cmp("$result", + "$expected", + "GET ${dir}file.shtml" + ); +} + +# some tests that can't be easily assimilated + +$doc = "printenv.shtml"; +ok t_cmp(GET("$dir$doc")->code, + "200", + "GET $dir$doc" + ); + +### test include + query string +$res = GET "${dir}virtual.shtml"; + +ok $res->is_success; + +$str = $res->content; + +ok $str; + +for my $pat (@patterns) { + ok t_cmp($str, qr/$pat/, "/$pat/"); +} + +### MOD_BUCKETEER+MOD_INCLUDE TESTS +if (WINFU) { + for (1..13) { + skip "Skipping XBitHack tests on this platform", 1; + } +} +else { + ### XBITHACK TESTS + # test xbithack off + $doc = "xbithack/off/test.html"; + foreach ("0444", "0544", "0554") { + chmod oct($_), "$htdocs/$dir$doc"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"),, + "<BODY> <!--#include virtual=\"../../inc-two.shtml\"--> </BODY>", + "XBitHack off [$_]" + ); + } + + # test xbithack on + $doc = "xbithack/on/test.html"; + chmod 0444, "$htdocs$dir$doc"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + "<BODY> <!--#include virtual=\"../../inc-two.shtml\"--> </BODY>", + "XBitHack on [0444]" + ); + + foreach ("0544", "0554") { + chmod oct($_), "$htdocs/$dir$doc"; + ok t_cmp(check_xbithack(GET "$dir$doc"), + "No Last-modified date ; <BODY> inc-two.shtml body </BODY>", + "XBitHack on [$_]" + ); + } + + # test timefmt - make sure filter only inserted once + # if Option Include and xbithack both say to process + $doc = "xbithack/both/timefmt.shtml"; + my @now = localtime(); + my $year = $now[5] + 1900; + chmod 0555, "$htdocs/$dir$doc"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + "xx${year}xx", + "XBitHack both [timefmt]" + ); + + # test xbithack full + $doc = "xbithack/full/test.html"; + chmod 0444, "$htdocs/$dir$doc"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + "<BODY> <!--#include virtual=\"../../inc-two.shtml\"--> </BODY>", + "XBitHack full [0444]" + ); + chmod 0544, "$htdocs/$dir$doc"; + ok t_cmp(check_xbithack(GET "$dir$doc"), + "No Last-modified date ; <BODY> inc-two.shtml body </BODY>", + "XBitHack full [0544]" + ); + + my $lm; + + chmod 0554, "$htdocs/$dir$doc"; + ok t_cmp(check_xbithack(GET("$dir$doc"), \$lm), + "Has Last-modified date ; <BODY> inc-two.shtml body </BODY>", + "XBitHack full [0554]" + ); + + ok t_cmp(check_xbithack_etag(GET("$dir$doc", 'If-Modified-Since' => $lm)), + "No ETag ; ", + "XBitHack full [0554] / ETag" + ); + + ok t_cmp(GET("$dir$doc", 'If-Modified-Since' => $lm)->code, 304, + "XBitHack full [0554] / If-Modified-Since" + ); + + chmod 0544, "$htdocs/$dir$doc"; + ok t_cmp(GET("$dir$doc", 'If-Modified-Since' => $lm)->code, 200, + "XBitHack full [0544] / If-Modified-Since" + ); + + ok t_cmp(check_xbithack_etag(GET("$dir$doc", 'If-Modified-Since' => $lm)), + "No ETag ; <BODY> inc-two.shtml body </BODY>", + "XBitHack full [0544] / ETag" + ); +} + +# we can use mod_bucketeer to create edge conditions for mod_include, since +# it allows us to create bucket and brigade boundaries wherever we want +if (have_module 'mod_bucketeer') { + + my $expected = "____ _____ _____ ___________________ </table> ". + "##################################1/8</tr> ". + "##################################2/8</tr> ". + "##################################3/8</tr> ". + "##################################4/8</tr> ". + "##################################5/8</tr> ". + "##################################6/8$htdocs</tr> ". + "##################################7/8</tr> ". + "##################################8/8</tr> ". + "@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@"; + + $doc = "bucketeer/y.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + $expected = "____ ___________________________________". + "________________________________________". + "___ ____________________________________". + "________________________________________". + "__________ ___________________ </table> ". + "#####################################</tr> ". + "#####################################</tr> ". + "#####################################</tr> ". + "#####################################</tr> ". + "#####################################</tr> ". + "#####################################</tr> ". + "#####################################</tr> ". + "#####################################</tr> ". + "@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@"; + + for (0..3) { + $doc = "bucketeer/y$_.shtml"; + my ($body) = super_chomp(GET_BODY "$dir$doc"); + $body =~ s/\002/^B/g; + $body =~ s/\006/^F/g; + $body =~ s/\020/^P/g; + ok t_cmp($body, + $expected, + "GET $dir$doc" + ); + } + + $expected = "[an error occurred while processing this directive]"; + $doc = "bucketeer/y4.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + + $expected= "pass [an error occurred while processing this directive] ". + "pass pass1"; + $doc = "bucketeer/y5.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + $expected= "BeforeIfElseBlockAfterIf"; + $doc = "bucketeer/y6.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + $expected= "Before If <!-- comment -->SomethingElse". + "<!-- right after if -->After if"; + $doc = "bucketeer/y7.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + $expected= "FalseSetDone"; + $doc = "bucketeer/y8.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + $expected= "FalseSetDone"; + $doc = "bucketeer/y9.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + $expected= "\"pass\""; + $doc = "bucketeer/y10.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $expected, + "GET $dir$doc" + ); + + ### exotic SSI(Start|End)Tags + + $expected= "----retagged3.shtml"; + $doc = "bucketeer/retagged3.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc", Host => 'retagged1'), + $expected, + "GET $dir$doc" + ); + + $expected= "---pass"; + $doc = "bucketeer/retagged4.shtml"; + ok t_cmp(super_chomp(GET_BODY "$dir$doc", Host => 'retagged2'), + $expected, + "GET $dir$doc" + ); +} +else { + for (1..14) { + skip "Skipping bucket boundary tests, no mod_bucketeer", 1; + } +} + +sub super_chomp { + my ($body) = shift; + + ## super chomp - all leading and trailing \n (and \r for win32) + $body =~ s/^[\n\r]*//; + $body =~ s/[\n\r]*$//; + ## and all the rest change to spaces + $body =~ s/\n/ /g; + $body =~ s/\r//g; #rip out all remaining \r's + + $body; +} + +sub check_xbithack { + my ($resp) = shift; + my ($body) = super_chomp($resp->content); + my ($lastmod) = ($resp->last_modified) + ? "Has Last-modified date" : "No Last-modified date"; + + my $data = shift; + $$data = $resp->header('Last-Modified') if $data; + + "$lastmod ; $body"; +} + +sub check_xbithack_etag { + my ($resp) = shift; + my ($body) = super_chomp($resp->content); + my ($etag) = ($resp->header('ETag')) + ? "Has ETag" : "No ETag"; + + my $data = shift; + $$data = $etag if $data; + + "$etag ; $body"; +} + +sub commify { + # add standard commas to numbers. from perlfaq5 + + local $_ = shift; + 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; + return $_; +} + +sub single_space { + # condense multiple spaces between values to a single + # space. also trim initial and trailing whitespace + + local $_ = shift; + s/\s+/ /g; + s/(^ )|( $)//; + return $_; +} diff --git a/debian/perl-framework/t/modules/info.t b/debian/perl-framework/t/modules/info.t new file mode 100644 index 0000000..21cee4e --- /dev/null +++ b/debian/perl-framework/t/modules/info.t @@ -0,0 +1,69 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## +## mod_info quick test +## + +plan tests => 1, need_module 'info'; + +my $uri = '/server-info'; +my $info = GET_BODY $uri; +my $config = Apache::Test::config(); +my $mods = $config->{modules}; +my (@actual,@expected) = ((),()); + +## extract module names from html ## +foreach (split /\n/, $info) { + if ($_ =~ /<a name=\"(\w+\.c)\">/) { + if ($1 eq 'util_ldap.c') { + push(@actual,'mod_ldap.c'); + } elsif ($1 eq 'mod_apreq2.c') { + push(@actual,'mod_apreq.c'); + } else { + push(@actual, $1); + } + } +} + +foreach (sort keys %$mods) { + ($mods->{$_} && !$config->should_skip_module($_)) or next; + if ($_ =~ /^mod_mpm_(eventopt|event|motorz|prefork|worker)\.c$/) { + push(@expected,"$1.c"); + } elsif ($_ eq 'mod_mpm_simple.c') { + push(@expected,'simple_api.c'); + # statically linked mod_ldap + } elsif ($_ eq 'util_ldap.c') { + push(@expected,'mod_ldap.c'); + # statically linked mod_apreq2 + } elsif ($_ eq 'mod_apreq2.c') { + push(@expected,'mod_apreq.c'); + } else { + push(@expected,$_); + } +} +@actual = sort @actual; +@expected = sort @expected; + +## verify all mods are there ## +my $ok = 1; +if (@actual == @expected) { + for (my $i=1 ; $i<@expected ; $i++) { + if ($expected[$i] ne $actual[$i]) { + $ok = 0; + print "comparing expected ->$expected[$i]<-\n"; + print "to actual ->$actual[$i]<-\n"; + print "actual:\n@actual\nexpect:\n@expected\n"; + last; + } + } +} else { + $ok = 0; + my $a = @actual; my $e = @expected; + print "actual($a modules):\n@actual\nexpect($e modules):\n@expected\n"; +} + +ok $ok; diff --git a/debian/perl-framework/t/modules/ldap.t b/debian/perl-framework/t/modules/ldap.t new file mode 100644 index 0000000..d3bb8e9 --- /dev/null +++ b/debian/perl-framework/t/modules/ldap.t @@ -0,0 +1,52 @@ +use strict; +use warnings FATAL => 'all'; + +# +# To run tests for mod_authnz_ldap: +# +# a) run an LDAP server with root DN of dc=example,dc=com on localhost port 8389 +# b) populate the directory with the LDIF from scripts/httpd.ldif +# c) configure & run the test suite passing "--defines LDAP" to ./t/TEST +# + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig; + +my $defs = Apache::Test->vars('defines'); +my $ldap_defined = $defs =~ /LDAP/; + +# URL -> username, password, expected-status +my @cases = ( + ['/modules/ldap/simple/' => '', '', 401], + ['/modules/ldap/simple/' => 'alpha', 'badpass', 401], + ['/modules/ldap/simple/' => 'alpha', 'Alpha', 200], + ['/modules/ldap/simple/' => 'gamma', 'Gamma', 200], + ['/modules/ldap/group/' => 'gamma', 'Gamma', 401], + ['/modules/ldap/group/' => 'delta', 'Delta', 200], + ['/modules/ldap/refer/' => 'alpha', 'Alpha', 401], + ['/modules/ldap/refer/' => 'beta', 'Beta', 200], +); + +plan tests => scalar @cases, + need need_module('authnz_ldap'), { "LDAP testing not configured" => $ldap_defined }; + +foreach my $t (@cases) { + my $url = $t->[0]; + my $username = $t->[1]; + my $password = $t->[2]; + my $response; + my $creds; + + if ($username) { + $response = GET $url, username => $username, password => $password; + $creds = "$username/$password"; + } + else { + $response = GET $url; + $creds = "no credentials"; + } + + ok t_cmp($response->code, $t->[3], "test for $url with $creds"); +} diff --git a/debian/perl-framework/t/modules/lua.t b/debian/perl-framework/t/modules/lua.t new file mode 100644 index 0000000..9e6836d --- /dev/null +++ b/debian/perl-framework/t/modules/lua.t @@ -0,0 +1,81 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +my $config = Apache::Test::config(); +my $server = $config->server; +my $version = $server->{version}; +my $scheme = Apache::Test::vars()->{scheme}; +my $hostport = Apache::TestRequest::hostport(); + +my $https = "nope"; +$https = "yep" if $scheme eq "https"; + +my $pfx = "/modules/lua"; + +my @ts = ( + { url => "$pfx/hello.lua", rcontent => "Hello Lua World!\n", + ctype => "text/plain" }, + { url => "$pfx/404?translateme=1", rcontent => "Hello Lua World!\n" }, + + { url => "$pfx/translate-inherit-before/404?translateme=1", rcontent => "other lua handler\n" }, + { url => "$pfx/translate-inherit-default-before/404?translateme=1", rcontent => "other lua handler\n" }, + { url => "$pfx/translate-inherit-after/404?translateme=1", rcontent => "Hello Lua World!\n" }, + + { url => "$pfx/translate-inherit-before/404?translateme=1&ok=1", rcontent => "other lua handler\n" }, + { url => "$pfx/translate-inherit-default-before/404?translateme=1&ok=1", rcontent => "other lua handler\n" }, + # the more specific translate_name handler will run first and return OK. + { url => "$pfx/translate-inherit-after/404?translateme=1&ok=1", rcontent => "other lua handler\n" }, + + { url => "$pfx/version.lua", rcontent => qr(^$version) }, + { url => "$pfx/method.lua", rcontent => "GET" }, + { url => "$pfx/201.lua", rcontent => "", code => 201 }, + { url => "$pfx/https.lua", rcontent => $https }, + { url => "$pfx/setheaders.lua", rcontent => "", + headers => { "X-Header" => "yes", + "X-Host" => $hostport } }, + { url => "$pfx/setheaderfromparam.lua?HeaderName=foo&HeaderValue=bar", + rcontent => "Header set", + headers => { "foo" => "bar" } }, + { url => "$pfx/filtered/foobar.html", + rcontent => "prefix\nbucket:foobar\nsuffix\n" }, +); + +plan tests => 4 * scalar @ts, need 'lua'; + +for my $t (@ts) { + my $url = $t->{"url"}; + my $r = GET $url; + my $code = $t->{"code"} || 200; + my $headers = $t->{"headers"}; + + ok t_cmp($r->code, $code, "code for $url"); + ok t_cmp($r->content, $t->{"rcontent"}, "response content for $url"); + + if ($t->{"ctype"}) { + ok t_cmp($r->header("Content-Type"), $t->{"ctype"}, "c-type for $url"); + } + else { + skip 1; + } + + if ($headers) { + my $correct = 1; + while (my ($name, $value) = each %{$headers}) { + my $actual = $r->header($name) || "<unset>"; + t_debug "'$name' header value is '$actual' (expected '$value')"; + + if ($actual ne $value) { + $correct = 0; + } + } + ok $correct; + } + else { + skip 1; + } +} diff --git a/debian/perl-framework/t/modules/negotiation.t b/debian/perl-framework/t/modules/negotiation.t new file mode 100644 index 0000000..9218aa1 --- /dev/null +++ b/debian/perl-framework/t/modules/negotiation.t @@ -0,0 +1,185 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## mod_negotiation test (see extra.conf.in) + +my ($en, $fr, $de, $fu, $bu, $zh) = qw(en fr de fu bu zh-TW); + +my @language = ($en, $fr, $de, $fu); +if (have_min_apache_version("2.4.38")) { + push @language, $zh; +} + +my @ct_tests = ( + # [ Accept header, Expected response ] + [ "*/*", "text/plain" ], + [ "text/*", "text/plain" ], + [ "text/html", "text/html" ], + [ "image/*", "image/jpeg" ], + [ "image/gif", "image/gif" ], + + [ "*", "text/plain" ], # Dubious + + # Tests which expect a 406 response + [ "", undef ], + [ "*bad", undef ], + [ "/*", undef ], + [ "*/", undef ], + [ "te/*", undef ], +); + +my $tests = (@language * 3) + (@language * @language * 5) + (scalar @ct_tests) + + 7; + +plan tests => $tests, need + need_module('negotiation') && need_cgi && need_module('mime'); + +my $actual; + +#XXX: this is silly; need a better way to be portable +sub my_chomp { + $actual =~ s/[\r\n]+$//s; +} + +foreach (@language) { + + ## verify that the correct default language content is returned + $actual = GET_BODY "/modules/negotiation/$_/"; + print "# GET /modules/negotiation/$_/\n"; + my_chomp(); + ok t_cmp($actual, "index.html.$_", + "Verify correct default language for index.$_.foo"); + + $actual = GET_BODY "/modules/negotiation/$_/compressed/"; + print "# GET /modules/negotiation/$_/compressed/\n"; + my_chomp(); + ok t_cmp($actual, "index.html.$_.gz", + "Verify correct default language for index.$_.foo.gz"); + + $actual = GET_BODY "/modules/negotiation/$_/two/index"; + print "# GET /modules/negotiation/$_/two/index\n"; + my_chomp(); + ok t_cmp($actual, "index.$_.html", + "Verify correct default language for index.$_.html"); + + foreach my $ext (@language) { + + ## verify that you can explicitly request all language files. + my $resp = GET("/modules/negotiation/$_/index.html.$ext"); + print "# GET /modules/negotiation/$_/index.html.$ext\n"; + ok t_cmp($resp->code, + 200, + "Explicitly request $_/index.html.$ext"); + $resp = GET("/modules/negotiation/$_/two/index.$ext.html"); + print "# GET /modules/negotiation/$_/two/index.$ext.html\n"; + ok t_cmp($resp->code, + 200, + "Explicitly request $_/two/index.$ext.html"); + + ## verify that even tho there is a default language, + ## the Accept-Language header is obeyed when present. + $actual = GET_BODY "/modules/negotiation/$_/", + 'Accept-Language' => $ext; + print "# GET /modules/negotiation/$_/\n# Accept-Language: $ext\n"; + my_chomp(); + ok t_cmp($actual, "index.html.$ext", + "Verify with a default language Accept-Language still obeyed"); + + $actual = GET_BODY "/modules/negotiation/$_/compressed/", + 'Accept-Language' => $ext; + print "# GET /modules/negotiation/$_/compressed/\n# Accept-Language: $ext\n"; + my_chomp(); + ok t_cmp($actual, "index.html.$ext.gz", + "Verify with a default language Accept-Language still ". + "obeyed (compression on)"); + + $actual = GET_BODY "/modules/negotiation/$_/two/index", + 'Accept-Language' => $ext; + print "# GET /modules/negotiation/$_/two/index\n# Accept-Language: $ext\n"; + my_chomp(); + ok t_cmp($actual, "index.$ext.html", + "Verify with a default language Accept-Language still obeyed"); + + } +} + +## more complex requests ## + +## 'fu' has a quality rating of 0.9 which is higher than the rest +## we expect Apache to return the 'fu' content. +$actual = GET_BODY "/modules/negotiation/$en/", + 'Accept-Language' => "$en; q=0.1, $fr; q=0.4, $fu; q=0.9, $de; q=0.2"; +print "# GET /modules/negotiation/$en/\n# Accept-Language: $en; q=0.1, $fr; q=0.4, $fu; q=0.9, $de; q=0.2\n"; +my_chomp(); +ok t_cmp($actual, "index.html.$fu", + "fu has a higher quality rating, so we expect fu"); + +$actual = GET_BODY "/modules/negotiation/$en/two/index", + 'Accept-Language' => "$en; q=0.1, $fr; q=0.4, $fu; q=0.9, $de; q=0.2"; +print "# GET /modules/negotiation/$en/two/index\n# Accept-Language: $en; q=0.1, $fr; q=0.4, $fu; q=0.9, $de; q=0.2\n"; +my_chomp(); +ok t_cmp($actual, "index.$fu.html", + "fu has a higher quality rating, so we expect fu"); + +$actual = GET_BODY "/modules/negotiation/$en/compressed/", + 'Accept-Language' => "$en; q=0.1, $fr; q=0.4, $fu; q=0.9, $de; q=0.2"; +print "# GET /modules/negotiation/$en/compressed/\n# Accept-Language: $en; q=0.1, $fr; q=0.4, $fu; q=0.9, $de; q=0.2\n"; +my_chomp(); +ok t_cmp($actual, "index.html.$fu.gz", + "fu has a higher quality rating, so we expect fu"); + +## 'bu' has the highest quality rating, but is non-existant, +## so we expect the next highest rated 'fr' content to be returned. +$actual = GET_BODY "/modules/negotiation/$en/", + 'Accept-Language' => "$en; q=0.1, $fr; q=0.4, $bu; q=1.0"; +print "# GET /modules/negotiation/$en/\n# Accept-Language: $en; q=0.1, $fr; q=0.4, $bu; q=1.0\n"; +my_chomp(); +ok t_cmp($actual, "index.html.$fr", + "bu has the highest quality but is non-existant, so fr is next best"); + +$actual = GET_BODY "/modules/negotiation/$en/two/index", + 'Accept-Language' => "$en; q=0.1, $fr; q=0.4, $bu; q=1.0"; +print "# GET /modules/negotiation/$en/two/index\n# Accept-Language: $en; q=0.1, $fr; q=0.4, $bu; q=1.0\n"; +my_chomp(); +ok t_cmp($actual, "index.$fr.html", + "bu has the highest quality but is non-existant, so fr is next best"); + +$actual = GET_BODY "/modules/negotiation/$en/compressed/", + 'Accept-Language' => "$en; q=0.1, $fr; q=0.4, $bu; q=1.0"; +print "# GET /modules/negotiation/$en/compressed/\n# Accept-Language: $en; q=0.1, $fr; q=0.4, $bu; q=1.0\n"; +my_chomp(); +ok t_cmp($actual, "index.html.$fr.gz", + "bu has the highest quality but is non-existant, so fr is next best"); + +$actual = GET_BODY "/modules/negotiation/query/test?foo"; +print "# GET /modules/negotiation/query/test?foo\n"; +my_chomp(); +ok t_cmp($actual, "QUERY_STRING --> foo", + "The type map gives the script the highest quality;" + . "\nthe request included a query string"); + +## Content-Type tests + +foreach my $test (@ct_tests) { + my $accept = $test->[0]; + my $expected = $test->[1]; + + my $r = GET "/modules/negotiation/content-type/test.var", + Accept => $accept; + + if ($expected) { + $actual = $r->content; + + # Strip whitespace from the body (we pad the variant map with spaces). + $actual =~ s/^\s+|\s+$//g; + + ok t_cmp $expected, $actual, "should send correct variant"; + } + else { + ok t_cmp $r->code, 406, "expect Not Acceptable for Accept: $accept"; + } +} diff --git a/debian/perl-framework/t/modules/proxy.t b/debian/perl-framework/t/modules/proxy.t new file mode 100644 index 0000000..0a81f4f --- /dev/null +++ b/debian/perl-framework/t/modules/proxy.t @@ -0,0 +1,233 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); +use Misc; + +my $num_tests = 46; +plan tests => $num_tests, need need_module 'proxy', need_module 'setenvif'; + +Apache::TestRequest::module("proxy_http_reverse"); +Apache::TestRequest::user_agent(requests_redirectable => 0); + +my $r = GET("/reverse/"); +ok t_cmp($r->code, 200, "reverse proxy"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body"); + +$r = GET("/reverse/index.html"); +ok t_cmp($r->code, 200, "reverse proxy to index.html"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body to index.html"); + +if (have_min_apache_version('2.4.49')) { + $r = GET("/reverse-match/"); + ok t_cmp($r->code, 200, "reverse proxy match"); + ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body match"); + + $r = GET("/reverse-match/index.html"); + ok t_cmp($r->code, 200, "reverse proxy match to index.html"); + ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body match to index.html"); +} +else { + skip "skipping reverse-match test with httpd <2.5.1" foreach (1..4); +} + +$r = GET("/reverse-slash"); +ok t_cmp($r->code, 200, "reverse proxy match no slash"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body no slash"); + +$r = GET("/reverse-slash/"); +ok t_cmp($r->code, 200, "reverse proxy match w/ slash"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body w/ slash"); + +$r = GET("/reverse-slash/index.html"); +ok t_cmp($r->code, 200, "reverse proxy match w/ slash to index.html"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body w/ slash to index.html"); + +if (have_min_apache_version('2.4.0')) { + $r = GET("/reverse/locproxy/"); + ok t_cmp($r->code, 200, "reverse Location-proxy to index.html"); + ok t_cmp($r->content, qr/^welcome to /, "reverse Location-proxied body"); +} +else { + skip "skipping per-location test with httpd <2.4" foreach (1..2); +} + +if (have_min_apache_version('2.4.26')) { + # This location should get trapped by the SetEnvIf and NOT be + # proxied, hence should get a 404. + $r = GET("/reverse/locproxy/index.html"); + ok t_cmp($r->code, 404, "reverse Location-proxy blocked by no-proxy env"); +} else { + skip "skipping no-proxy test with httpd <2.4.26"; +} + +if (have_cgi) { + $r = GET("/reverse/modules/cgi/env.pl"); + ok t_cmp($r->code, 200, "reverse proxy to env.pl"); + ok t_cmp($r->content, qr/^APACHE_TEST_HOSTNAME = /, "reverse proxied env.pl response"); + ok t_cmp($r->content, qr/HTTP_X_FORWARDED_FOR = /, "X-Forwarded-For enabled"); + + if (have_min_apache_version('2.4.28')) { + Apache::TestRequest::module("proxy_http_nofwd"); + $r = GET("/reverse/modules/cgi/env.pl"); + ok t_cmp($r->code, 200, "reverse proxy to env.pl without X-F-F"); + ok !t_cmp($r->content, qr/HTTP_X_FORWARDED_FOR = /, "reverse proxied env.pl w/o X-F-F"); + + Apache::TestRequest::module("proxy_http_reverse"); + } + else { + skip "skipping tests with httpd < 2.4.28" foreach (1..2); + } + + $r = GET("/reverse/modules/cgi/env.pl?reverse-proxy"); + ok t_cmp($r->code, 200, "reverse proxy with query string"); + ok t_cmp($r->content, qr/QUERY_STRING = reverse-proxy\n/s, "reverse proxied query string OK"); + + $r = GET("/reverse/modules/cgi/nph-dripfeed.pl"); + ok t_cmp($r->code, 200, "reverse proxy to dripfeed CGI"); + ok t_cmp($r->content, "abcdef", "reverse proxied to dripfeed CGI content OK"); + + if (have_min_apache_version('2.1.0')) { + $r = GET("/reverse/modules/cgi/nph-102.pl"); + ## Uncomment next 2 lines and comment out the subsequant 2 lines + ## when LWP is fixed to work w/ 1xx + ##ok t_cmp($r->code, 200, "reverse proxy to nph-102"); + ##ok t_cmp($r->content, "this is nph-stdout", "reverse proxy 102 response"); + ok t_cmp($r->code, 102, "reverse proxy to nph-102"); + ok t_cmp($r->content, "", "reverse proxy 102 response"); + } else { + skip "skipping tests with httpd <2.1.0" foreach (1..2); + } + +} else { + skip "skipping tests without CGI module" foreach (1..11); +} + +if (have_min_apache_version('2.0.55')) { + # trigger the "proxy decodes abs_path issue": with the bug present, the + # proxy URI-decodes on the way through, so the origin server receives + # an abs_path of "/reverse/nonesuch/file%", which it fails to parse and + # returns a 400 response. + $r = GET("/reverse/nonesuch/file%25"); + ok t_cmp($r->code, 404, "reverse proxy URI decoding issue, PR 15207"); +} else { + skip "skipping PR 15207 test with httpd < 2.0.55"; +} + +$r = GET("/reverse/notproxy/local.html"); +ok t_cmp($r->code, 200, "ProxyPass not-proxied request"); +my $c = $r->content; +chomp $c; +ok t_cmp($c, "hello world", "ProxyPass not-proxied content OK"); + +# Testing ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath +if (have_min_apache_version('2.4.34') && have_module('lua')) { + # '/' is escaped as %2F + # ';' is escaped as %3B + # '=' is escaped as %3D + $r = GET("/reverse/modules/lua/setheaderfromparam.lua?HeaderName=Set-Cookie&HeaderValue=fakedomain%3Dlocal%3Bdomain%3Dlocal"); + ok t_cmp($r->code, 200, "Lua executed"); + ok t_cmp($r->header("Set-Cookie"), "fakedomain=local;domain=remote", "'Set-Cookie domain=' wrongly updated by ProxyPassReverseCookieDomain, PR 61560"); + + $r = GET("/reverse/modules/lua/setheaderfromparam.lua?HeaderName=Set-Cookie&HeaderValue=fakepath%3D%2Flocal%3Bpath%3D%2Flocal"); + ok t_cmp($r->code, 200, "Lua executed"); + ok t_cmp($r->header("Set-Cookie"), "fakepath=/local;path=/remote", "'Set-Cookie path=' wrongly updated by ProxyPassReverseCookiePath, PR 61560"); + + $r = GET("/reverse/modules/lua/setheaderfromparam.lua?HeaderName=Set-Cookie&HeaderValue=domain%3Dlocal%3Bpath%3D%2Flocal%3bfoo%3Dbar"); + ok t_cmp($r->code, 200, "Lua executed"); + ok t_cmp($r->header("Set-Cookie"), "domain=remote;path=/remote;foo=bar", "'Set-Cookie path=' wrongly updated by ProxyPassReverseCookiePath and/or ProxyPassReverseCookieDomain"); +} +else { + skip "skipping tests which need mod_lua" foreach (1..6); +} + +if (have_module('alias')) { + $r = GET("/reverse/perm"); + ok t_cmp($r->code, 301, "reverse proxy of redirect"); + ok t_cmp($r->header("Location"), qr{http://[^/]*/reverse/alias}, "reverse proxy rewrote redirect"); + + if (have_module('proxy_balancer')) { + # More complex reverse mapping case with the balancer, PR 45434 + Apache::TestRequest::module("proxy_http_balancer"); + my $hostport = Apache::TestRequest::hostport(); + $r = GET("/pr45434/redirect-me"); + ok t_cmp($r->code, 301, "reverse proxy of redirect via balancer"); + ok t_cmp($r->header("Location"), "http://$hostport/pr45434/5.html", "reverse proxy via balancer rewrote redirect"); + Apache::TestRequest::module("proxy_http_reverse"); # flip back + } else { + skip "skipping tests without mod_proxy_balancer" foreach (1..2); + } + +} else { + skip "skipping tests without mod_alias" foreach (1..4); +} + +sub uds_script +{ + use Socket; + use strict; + + my $socket_path = shift; + my $sock_addr = sockaddr_un($socket_path); + socket(my $server, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!"; + bind($server, $sock_addr) || die "bind: $!"; + listen($server,1024) || die "listen: $!"; + open(MARKER, '>', $socket_path.'.marker') or die "Unable to open file $socket_path.marker : $!"; + close(MARKER); + if (accept(my $new_sock, $server)) { + my $data = <$new_sock>; + print $new_sock "HTTP/1.0 200 OK\r\n"; + print $new_sock "Content-Type: text/plain\r\n\r\n"; + print $new_sock "hello world\n"; + close $new_sock; + } + unlink($socket_path); + unlink($socket_path.'.marker'); +} + +if (have_min_apache_version('2.4.7')) { + my $socket_path = '/tmp/test-ptf.sock'; + unlink($socket_path); + my $pid = fork(); + unless (defined $pid) { + t_debug "couldn't fork UDS script"; + ok 0; + exit; + } + if ($pid == 0) { + uds_script($socket_path); + exit; + } + unless (Misc::cwait('-e "'.$socket_path.'.marker"', 10, 50)) { + ok 0; + exit; + } + sleep(1); + $r = GET("/uds/"); + ok t_cmp($r->code, 200, "ProxyPass UDS path"); + my $c = $r->content; + chomp $c; + ok t_cmp($c, "hello world", "UDS content OK"); + +} +else { + skip "skipping UDS tests with httpd < 2.4.7" foreach (1..2); +} + +if (have_min_apache_version('2.4.49')) { + + $r = GET("/notexisting/../mapping/mapping.html"); + ok t_cmp($r->code, 200, "proxy mapping=servlet map it to /servlet/mapping.html"); + + $r = GET("/notexisting/..;/mapping/mapping.html"); + ok t_cmp($r->code, 200, "proxy mapping=servlet map it to /servlet/mapping.html"); + + $r = GET("/mapping/mapping.html"); + ok t_cmp($r->code, 200, "proxy to /servlet/mapping.html"); +} +else { + skip "skipping tests with mapping=servlet" foreach (1..3); +} diff --git a/debian/perl-framework/t/modules/proxy_balancer.t b/debian/perl-framework/t/modules/proxy_balancer.t new file mode 100644 index 0000000..94753b7 --- /dev/null +++ b/debian/perl-framework/t/modules/proxy_balancer.t @@ -0,0 +1,125 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +my @echos = ('A'x8, 'A'x64, 'A'x2048, 'A'x4096); + +my $skipbodyfailover = !need_min_apache_version("2.4.42"); +my $referertest = 0; + +if (have_min_apache_version("2.4.41")) { + $referertest = 2; +} + +plan tests => 6+(2*scalar @echos)+$referertest, need 'proxy_balancer', 'proxy_http'; + +Apache::TestRequest::module("proxy_http_balancer"); +Apache::TestRequest::user_agent(requests_redirectable => 0); + +# Extract the nonce from response to the URL +sub GetNonce { + my $url = shift; + my $balancer = shift; + my $r; + $r = GET($url); + my $NONCE; + foreach my $query ( split( /\?b=/, $r->content ) ){ + if ($query =~ m/$balancer/) { + foreach my $var ( split( /&/, $query ) ){ + if ($var =~ m/nonce=/) { + foreach my $nonce ( split( /nonce=/, $var ) ){ + my $ind = index ($nonce, "\""); + $nonce = substr($nonce, 0, ${ind}); + if ( $nonce =~ m/^[0-9a-fA-F-]+$/ ) { + $NONCE = $nonce; + last; + } + } + last; + } + } + last; + } + } + return $NONCE; +} + +my $r; + +if (have_module('lbmethod_byrequests')) { + $r = GET("/baltest1/index.html"); + ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + skip "skipping tests without mod_lbmethod_byrequests" foreach (1..1); +} + +if (have_module('lbmethod_bytraffic')) { + $r = GET("/baltest2/index.html"); + ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + skip "skipping tests without mod_lbmethod_bytraffic" foreach (1..1); +} + +if (have_module('lbmethod_bybusyness')) { + $r = GET("/baltest3/index.html"); + ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + skip "skipping tests without mod_lbmethod_bybusyness" foreach (1..1); +} + +if (have_module('lbmethod_heartbeat')) { + #$r = GET("/baltest4/index.html"); + #ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + #skip "skipping tests without mod_lbmethod_heartbeat" foreach (1..1); +} + + + +# PR63891 +foreach my $t (@echos) { + $r = POST "/baltest_echo_post", content => $t; + skip $skipbodyfailover, t_cmp($r->code, 200, "failed over"); + skip $skipbodyfailover, t_cmp($r->content, $t, "response body echoed"); +} + +# test dynamic part +$r = GET("/balancer-manager"); +ok t_cmp($r->code, 200, "Can't find balancer-manager"); + +# get the nonce and add a worker +my $result = GetNonce("/balancer-manager", "dynproxy"); + +my $query = "b_lbm=byrequests&b_tmo=0&b_max=0&b_sforce=0&b_ss=&b_nwrkr=ajp%3A%2F%2F%5B0%3A0%3A0%3A0%3A0%3A0%3A0%3A1%5D%3A8080&b_wyes=1&b=dynproxy&nonce=" . $result; +my @proxy_balancer_headers; +my $vars = Apache::Test::vars(); +push @proxy_balancer_headers, "Referer" => "http://" . $vars->{servername} . ":" . $vars->{port} . "/balancer-manager"; + +# First try without the referer it should fail. +if (have_min_apache_version("2.4.41")) { + $r = POST("/balancer-manager", content => $query); + ok t_cmp($r->code, 200, "request failed"); + ok !t_cmp($r->content, qr/ajp/, "AJP worker created"); +} + +# Try with the referer and http (byrequests) +if (have_min_apache_version("2.4.49") && have_module('lbmethod_byrequests')) { + $r = GET("/dynproxy"); + ok t_cmp($r->code, 503, "request should fail for /dynproxy"); + # create it + $query = "b_lbm=byrequests&b_tmo=0&b_max=0&b_sforce=0&b_ss=&b_nwrkr=http%3A%2F%2Flocalhost%3A8529&b_wyes=1&b=dynproxy&nonce=" . $result; + $r = POST("/balancer-manager", content => $query, @proxy_balancer_headers); + # enable it. + $query = "w=http%3A%2F%2Flocalhost%3A8529&b=dynproxy&w_status_D=0&nonce=" . $result; + $r = POST("/balancer-manager", content => $query, @proxy_balancer_headers); + # make a query + $r = GET("/dynproxy"); + ok t_cmp($r->code, 200, "request failed to /dynproxy"); +} else { + skip "skipping tests without lbmethod_byrequests"; + skip "skipping tests without lbmethod_byrequests"; +} diff --git a/debian/perl-framework/t/modules/proxy_fcgi.t b/debian/perl-framework/t/modules/proxy_fcgi.t new file mode 100644 index 0000000..2f62580 --- /dev/null +++ b/debian/perl-framework/t/modules/proxy_fcgi.t @@ -0,0 +1,300 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Misc; + +my $have_fcgisetenvif = have_min_apache_version('2.4.26'); +my $have_fcgibackendtype = have_min_apache_version('2.4.26'); +# NOTE: This will fail if php-fpm is installed but not in $PATH +my $have_php_fpm = `php-fpm -v` =~ /fpm-fcgi/; + +plan tests => (7 * $have_fcgisetenvif) + (2 * $have_fcgibackendtype) + + (2 * $have_fcgibackendtype * have_module('rewrite')) + + (7 * have_module('rewrite')) + (7 * have_module('actions')) + + (15 * $have_php_fpm * have_module('actions')) + 2, + need ( + 'mod_proxy_fcgi', + 'FCGI', + 'IO::Select' + ); + +require FCGI; +require IO::Select; + +Apache::TestRequest::module("proxy_fcgi"); + +# Launches a short-lived FCGI daemon that will handle exactly one request with +# the given handler function. Returns the child PID; exits on failure. + +sub run_fcgi_handler($$) +{ + my $fcgi_port = shift; + my $handler_func = shift; + + # Use a pipe for ready-signalling between the child and parent. Much faster + # (and more reliable) than just sleeping for a few seconds. + pipe(READ_END, WRITE_END); + my $pid = fork(); + + unless (defined $pid) { + t_debug "couldn't fork FCGI process"; + ok 0; + exit; + } + + if ($pid == 0) { + # Child process. Open up a listening socket. + my $sock = FCGI::OpenSocket(":$fcgi_port", 10); + + # Signal the parent process that we're ready. + print WRITE_END 'x'; + close WRITE_END; + + # Listen for and respond to exactly one request from the client. + my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, + $sock, &FCGI::FAIL_ACCEPT_ON_INTR); + + if ($request->Accept() == 0) { + # Run the handler. + $handler_func->(); + $request->Finish(); + } + + # Clean up and exit. + FCGI::CloseSocket($sock); + exit; + } + + # Parent process. Wait for the daemon to launch. + unless (IO::Select->new((\*READ_END,))->can_read(2)) { + t_debug "timed out waiting for FCGI process to start"; + ok 0; + + kill 'TERM', $pid; + # Note that we don't waitpid() here because Perl's fork() implementation + # on some platforms (Windows) doesn't guarantee that the pseudo-TERM + # signal will be delivered. Just wait for the child to be cleaned up + # when we exit. + + exit; + } + + return $pid; +} + +# Convenience wrapper for run_fcgi_handler() that will echo back the envvars in +# the response. Returns the child PID; exits on failure. +sub launch_envvar_echo_daemon($) +{ + my $fcgi_port = shift; + + return run_fcgi_handler($fcgi_port, sub { + # Echo all the envvars back to the client. + print("Content-Type: text/plain\r\n\r\n"); + foreach my $key (sort(keys %ENV)) { + print($key, "=", $ENV{$key}, "\n"); + } + }); +} + +# Runs a single request using launch_envvar_echo_daemon(), then returns a +# hashref containing the environment variables that were echoed by the FCGI +# backend. +# +# Calling this function will run one test that must be accounted for in the test +# plan. +sub run_fcgi_envvar_request +{ + my $fcgi_port = shift; + my $uri = shift; + my $backend = shift || "FCGI"; + + # Launch the FCGI process. + my $child = launch_envvar_echo_daemon($fcgi_port) unless ($fcgi_port <= 0) ; + + # Hit the backend. + my $r = GET($uri); + ok t_cmp($r->code, 200, "proxy to $backend backend works (" . $uri . ")"); + + # Split the returned envvars into a dictionary. + my %envs = (); + + foreach my $line (split /\n/, $r->content) { + t_debug("> $line"); # log the response lines for debugging + + my @components = split /=/, $line, 2; + $envs{$components[0]} = $components[1]; + } + + if ($fcgi_port > 0) { + if ($r->code eq '500') { + # Unknown failure, probably the request didn't hit the FCGI child + # process, so it will hang waiting for our request + kill 'TERM', $child; + } else { + # Rejoin the child FCGI process. + waitpid($child, 0); + } + } + + return \%envs; +} + +# +# MAIN +# + +# XXX There appears to be no way to get the value of a dynamically-reserved +# @NextAvailablePort@ from Apache::Test. We assume here that the port reserved +# for the proxy_fcgi vhost is one greater than the reserved FCGI_PORT, but +# depending on the test conditions, that may not always be the case... +my $fcgi_port = Apache::Test::vars('proxy_fcgi_port') - 1; +my $envs; +my $docroot = Apache::Test::vars('documentroot'); +my $servroot = Apache::Test::vars('serverroot'); + +if ($have_fcgisetenvif) { + # ProxyFCGISetEnvIf tests. Query the backend. + $envs = run_fcgi_envvar_request($fcgi_port, "/fcgisetenv?query"); + + # Check the response values. + ok t_cmp($envs->{'QUERY_STRING'}, 'test_value', "ProxyFCGISetEnvIf can override an existing variable"); + ok t_cmp($envs->{'TEST_NOT_SET'}, undef, "ProxyFCGISetEnvIf does not set variables if condition is false"); + ok t_cmp($envs->{'TEST_EMPTY'}, '', "ProxyFCGISetEnvIf can set empty values"); + ok t_cmp($envs->{'TEST_DOCROOT'}, $docroot, "ProxyFCGISetEnvIf can replace with request variables"); + ok t_cmp($envs->{'TEST_CGI_VERSION'}, 'v1.1', "ProxyFCGISetEnvIf can replace with backreferences"); + ok t_cmp($envs->{'REMOTE_ADDR'}, undef, "ProxyFCGISetEnvIf can unset var"); +} + +# Tests for GENERIC backend type behavior. +if ($have_fcgibackendtype) { + # Regression test for PR59618. + $envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi-generic/index.php?query"); + + ok t_cmp($envs->{'SCRIPT_FILENAME'}, + $docroot . '/modules/proxy/fcgi-generic/index.php', + "GENERIC SCRIPT_FILENAME should have neither query string nor proxy: prefix"); +} + +if ($have_fcgibackendtype && have_module('rewrite')) { + # Regression test for PR59815. + $envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi-generic-rewrite/index.php?query"); + + ok t_cmp($envs->{'SCRIPT_FILENAME'}, + $docroot . '/modules/proxy/fcgi-generic-rewrite/index.php', + "GENERIC SCRIPT_FILENAME should have neither query string nor proxy: prefix"); +} + +if (have_module('rewrite')) { + # Regression test for general FPM breakage when using mod_rewrite for + # nice-looking URIs; see + # https://github.com/apache/httpd/commit/cab0bfbb2645bb8f689535e5e2834e2dbc23f5a5#commitcomment-20393588 + $envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi-rewrite-path-info/path/info?query"); + + # Not all of these values make sense, but unfortunately FPM expects some + # breakage and doesn't function properly without it, so we can't fully fix + # the problem by default. These tests verify that we follow the 2.4.20 way + # of doing things for the "rewrite-redirect PATH_INFO to script" case. + ok t_cmp($envs->{'SCRIPT_FILENAME'}, "proxy:fcgi://127.0.0.1:" . $fcgi_port + . $docroot + . '/modules/proxy/fcgi-rewrite-path-info/index.php', + "Default SCRIPT_FILENAME has proxy:fcgi prefix for compatibility"); + ok t_cmp($envs->{'SCRIPT_NAME'}, '/modules/proxy/fcgi-rewrite-path-info/index.php', + "Default SCRIPT_NAME uses actual path to script"); + ok t_cmp($envs->{'PATH_INFO'}, '/path/info', + "Default PATH_INFO is correct"); + ok t_cmp($envs->{'PATH_TRANSLATED'}, $docroot . '/path/info', + "Default PATH_TRANSLATED is correct"); + ok t_cmp($envs->{'QUERY_STRING'}, 'query', + "Default QUERY_STRING is correct"); + ok t_cmp($envs->{'REDIRECT_URL'}, '/modules/proxy/fcgi-rewrite-path-info/path/info', + "Default REDIRECT_URL uses original client URL"); +} + +if (have_module('actions')) { + # Regression test to ensure that the bizarre Action invocation for FCGI + # still works as it did in 2.4.20. Almost none of this follows any spec at + # all. As far as I can tell, this method does not work with FPM. + $envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi-action/index.php/path/info?query"); + + ok t_cmp($envs->{'SCRIPT_FILENAME'}, "proxy:fcgi://127.0.0.1:" . $fcgi_port + . $docroot + . '/fcgi-action-virtual', + "Action SCRIPT_FILENAME has proxy:fcgi prefix and uses virtual action Location"); + ok t_cmp($envs->{'SCRIPT_NAME'}, '/fcgi-action-virtual', + "Action SCRIPT_NAME is the virtual action Location"); + ok t_cmp($envs->{'PATH_INFO'}, '/modules/proxy/fcgi-action/index.php/path/info', + "Action PATH_INFO contains full URI path"); + ok t_cmp($envs->{'PATH_TRANSLATED'}, $docroot . '/modules/proxy/fcgi-action/index.php/path/info', + "Action PATH_TRANSLATED contains full URI path"); + ok t_cmp($envs->{'QUERY_STRING'}, 'query', + "Action QUERY_STRING is correct"); + ok t_cmp($envs->{'REDIRECT_URL'}, '/modules/proxy/fcgi-action/index.php/path/info', + "Action REDIRECT_URL uses original client URL"); + + # Testing using php-fpm directly + if ($have_php_fpm) { + my $pid_file = "/tmp/php-fpm-" . $$ . "-" . time . ".pid"; + my $pid = fork(); + unless (defined $pid) { + t_debug "couldn't start PHP-FPM"; + ok 0; + exit; + } + if ($pid == 0) { + system "php-fpm -n -D -g $pid_file -p $servroot/php-fpm"; + exit; + } + # Wait for php-fpm to start-up + unless ( Misc::cwait('-e "'.$pid_file.'"', 10, 50) ) { + ok 0; + exit; + } + sleep(1); + $envs = run_fcgi_envvar_request(0, "/php/fpm/action/sub2/test.php/foo/bar?query", "PHP-FPM"); + ok t_cmp($envs->{'SCRIPT_NAME'}, '/php/fpm/action/sub2/test.php', + "Handler PHP-FPM sets correct SCRIPT_NAME"); + ok t_cmp($envs->{'PATH_INFO'}, '/foo/bar', + "Handler PHP-FPM sets correct PATH_INFO"); + ok t_cmp($envs->{'QUERY_STRING'}, 'query', + "Handler PHP-FPM sets correct QUERY_STRING"); + ok t_cmp($envs->{'PATH_TRANSLATED'}, $docroot . '/foo/bar', + "Handler PHP-FPM sets correct PATH_TRANSLATED"); + ok t_cmp($envs->{'FCGI_ROLE'}, 'RESPONDER', + "Handler PHP-FPM sets correct FCGI_ROLE"); + + $envs = run_fcgi_envvar_request(0, "/php-fpm-pp/php/fpm/pp/sub1/test.php/foo/bar?query", "PHP-FPM"); + ok t_cmp($envs->{'SCRIPT_NAME'}, '/php-fpm-pp/php/fpm/pp/sub1/test.php', + "ProxyPass PHP-FPM sets correct SCRIPT_NAME"); + ok t_cmp($envs->{'PATH_INFO'}, '/foo/bar', + "ProxyPass PHP-FPM sets correct PATH_INFO"); + ok t_cmp($envs->{'QUERY_STRING'}, 'query', + "ProxyPass PHP-FPM sets correct QUERY_STRING"); + ok t_cmp($envs->{'PATH_TRANSLATED'}, $docroot . '/foo/bar', + "ProxyPass PHP-FPM sets correct PATH_TRANSLATED"); + ok t_cmp($envs->{'FCGI_ROLE'}, 'RESPONDER', + "ProxyPass PHP-FPM sets correct FCGI_ROLE"); + + $envs = run_fcgi_envvar_request(0, "/php-fpm-pp/php/fpm/pp/sub1/test.php", "PHP-FPM"); + ok t_cmp($envs->{'PATH_INFO'}, undef, + "ProxyPass PHP-FPM sets correct empty PATH_INFO"); + ok t_cmp($envs->{'PATH_TRANSLATED'}, undef, + "ProxyPass PHP-FPM does not set PATH_TRANSLATED w/ empty PATH_INFO"); + + # TODO: Add more tests here + + # Clean up php-fpm process(es) + kill 'TERM', $pid; # Kill child process + kill 'TERM', `cat $pid_file`; # Kill php-fpm daemon + waitpid($pid, 0); + } + +} + +# Regression test for PR61202. +$envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi/index.php"); +ok t_cmp($envs->{'SCRIPT_NAME'}, '/modules/proxy/fcgi/index.php', "Server sets correct SCRIPT_NAME by default"); + diff --git a/debian/perl-framework/t/modules/proxy_websockets.t b/debian/perl-framework/t/modules/proxy_websockets.t new file mode 100644 index 0000000..ed7ea97 --- /dev/null +++ b/debian/perl-framework/t/modules/proxy_websockets.t @@ -0,0 +1,53 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +my $total_tests = 1; + +plan tests => $total_tests, need 'AnyEvent::WebSocket::Client', + need_module('proxy_http', 'lua'), need_min_apache_version('2.4.47'); + +require AnyEvent; +require AnyEvent::WebSocket::Client; + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport(); + +my $client = AnyEvent::WebSocket::Client->new(timeout => 5); + +my $quit_program = AnyEvent->condvar; + +my $pingok = 0; + +$client->connect("ws://$hostport/proxy/wsoc")->cb(sub { + our $connection = eval { shift->recv }; + t_debug("wsoc connected"); + if($@) { + # handle error... + warn $@; + $quit_program->send(); + return; + } + + $connection->send('ping'); + + # recieve message from the websocket... + $connection->on(each_message => sub { + # $connection is the same connection object + # $message isa AnyEvent::WebSocket::Message + my($connection, $message) = @_; + t_debug("wsoc msg received: " . $message->body); + if ("ping" eq $message->body) { + $pingok = 1; + } + $connection->send('quit'); + $quit_program->send(); + }); +}); + +$quit_program->recv; +ok t_cmp($pingok, 1); diff --git a/debian/perl-framework/t/modules/ratelimit.t b/debian/perl-framework/t/modules/ratelimit.t new file mode 100644 index 0000000..27ce3a8 --- /dev/null +++ b/debian/perl-framework/t/modules/ratelimit.t @@ -0,0 +1,43 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use MIME::Base64; +use Data::Dumper; +use HTTP::Response; +use Socket; + +use LWP::UserAgent (); + + +my @testcases = ( + ['/apache/ratelimit/' => '200', "ratelimited small file"], + ['/apache/ratelimit/autoindex/' => '200', "ratelimited small autoindex output"], + ['/apache/ratelimit/chunk?0,8192' => '200', "ratelimited chunked response"], +); + +plan tests => scalar @testcases, need need_lwp, + need_module('mod_ratelimit'), + need_module('mod_autoindex'), + need_min_apache_version('2.4.35'); + +my $ua = LWP::UserAgent->new; +$ua->timeout(4); + +foreach my $t (@testcases) { + my $r; + + # trap a die() in WLP when the the status line is invalid to avoid + # 'dubious test...' instead of just a failure. + eval { $r = GET($t->[0]) ; + chomp $r; + t_debug "Status Line: '" . $r->status_line . "'"; + ok t_cmp($r->code, $t->[1], $t->[2]); + }; + # Check if the eval() die'ed + ok t_cmp($@, undef, $t->[2]) if $@ + +} + diff --git a/debian/perl-framework/t/modules/reflector.t b/debian/perl-framework/t/modules/reflector.t new file mode 100644 index 0000000..5d5c86b --- /dev/null +++ b/debian/perl-framework/t/modules/reflector.t @@ -0,0 +1,44 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @testcases = ( + ['/apache/reflector_nodeflate/', "Text that will not reach the DEFLATE filter"], + ['/apache/reflector_deflate/', "Text that should be gzipped"], +); + +my @headers; +push @headers, "header2reflect" => "1"; +push @headers, "header2update" => "1"; +push @headers, "header2delete" => "1"; +push @headers, "Content-Encoding" => "gzip"; +push @headers, "Accept-Encoding" => "gzip"; + +plan tests => scalar @testcases * 7, need 'mod_reflector', 'mod_deflate'; + +foreach my $t (@testcases) { + my $r = POST($t->[0], @headers, content => $t->[1]); + + # Checking for return code + ok t_cmp($r->code, 200, "Checking return code is '200'"); + + # Checking for content + if (index($t->[0], "_nodeflate") != -1) { + # With no filter, we should receive what we have sent + ok t_is_equal($r->content, $t->[1]); + ok t_cmp($r->header("Content-Encoding"), undef, "'Content-Encoding' has not been added because there was no filter"); + } else { + # With DEFLATE, input should have been updated and 'Content-Encoding' added + ok not t_is_equal($r->content, $t->[1]); + ok t_cmp($r->header("Content-Encoding"), "gzip", "'Content-Encoding' has been added by the DEFLATE filter"); + } + + # Checking for headers + ok t_cmp($r->header("header2reflect"), "1", "'header2reflect' is present"); + ok t_cmp($r->header("header2update"), undef, "'header2update' is absent"); + ok t_cmp($r->header("header2updateUpdated"), "1", "'header2updateUpdated' is present"); + ok t_cmp($r->header("header2delete"), undef, "'header2delete' is absent"); +} diff --git a/debian/perl-framework/t/modules/remoteip.t b/debian/perl-framework/t/modules/remoteip.t new file mode 100644 index 0000000..0fbadcd --- /dev/null +++ b/debian/perl-framework/t/modules/remoteip.t @@ -0,0 +1,97 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use HTTP::Response; + +## +## mod_remoteip tests +## +## PROXY protocol: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt +## +Apache::TestRequest::module("remote_ip"); +plan tests => 12, + need( + need_module('remoteip'), + need_min_apache_version('2.4.30') + ); + +sub slurp +{ + my $s = shift; + my $r = ""; + my $b; + while ($s->read($b, 10000) > 0) { + $r .= $b; + } + return $r; +} + +ok(my $sock = Apache::TestRequest::vhost_socket("remote_ip")); + +# +# Test human readable format: TCP4 +# +my $proxy = "PROXY TCP4 192.168.192.66 192.168.192.77 1111 2222\r\n"; +my $url = "GET /index.html HTTP/1.1\r\nConnection: close\r\n"; +$url .= "Host: dummy\r\n\r\n"; + +$sock->print($proxy . $url); +$sock->shutdown(1); + +my $response_data = slurp($sock); +my $r = HTTP::Response->parse($response_data); +chomp(my $content = $r->content); +ok t_cmp($r->code, 200, "PROXY human readable TCP4 protocol check"); +ok t_cmp($content, "PROXY-OK", "Content check"); +$sock->shutdown(2); + +# +# BAD format test +# +$proxy = "PROXY FOO 192.168.192.66 192.168.192.77 1111 2222\r\n"; +ok ($sock = Apache::TestRequest::vhost_socket("remote_ip")); +$sock->print($proxy . $url); +$sock->shutdown(1); + +# In httpd, a bad PROXY format simply results in the connection +# being dropped. So ensure we don't get anything that looks +# like a response +$response_data = slurp($sock); +$r = HTTP::Response->parse($response_data); +chomp($content = $r->content); +ok t_cmp($r->code, undef, "broken PROXY human readable protocol check"); +ok t_cmp($content, "", "Content check"); +$sock->shutdown(2); + +# +# Test human readable format: TCP6 +# +$proxy = "PROXY TCP6 2001:DB8::21f:5bff:febf:ce22:8a2e 2001:DB8::12f:8baa:eafc:ce29:6b2e 3333 4444\r\n"; +ok ($sock = Apache::TestRequest::vhost_socket("remote_ip")); +$sock->print($proxy . $url); +$sock->shutdown(1); +$response_data = slurp($sock); +$r = HTTP::Response->parse($response_data); +chomp($content = $r->content); +ok t_cmp($r->code, 200, "PROXY human readable TCP6 protocol check"); +ok t_cmp($content, "PROXY-OK", "Content check"); +$sock->shutdown(2); + +# Test binary format +$proxy = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"; # header +$proxy .= "\x21"; # protocol version and command (AF_INET STREAM) +$proxy .= "\x11"; # transport protocol and address family (TCP over IPv4) +$proxy .= "\x00\x0C"; # 12 bytes coming up +$proxy .= "\xC0\xA8\xC0\x42\xC0\xA8\xC0\x4D\x01\xF0\x01\xF1"; # IP addresses and ports +ok ($sock = Apache::TestRequest::vhost_socket("remote_ip")); +$sock->print($proxy . $url); +$sock->shutdown(1); +$response_data = slurp($sock); +$r = HTTP::Response->parse($response_data); +chomp($content = $r->content); +ok t_cmp($r->code, 200, "PROXY binary protocol TCP4 check"); +ok t_cmp($content, "PROXY-OK", "Content check"); +$sock->shutdown(2); diff --git a/debian/perl-framework/t/modules/rewrite.t b/debian/perl-framework/t/modules/rewrite.t new file mode 100644 index 0000000..30bb334 --- /dev/null +++ b/debian/perl-framework/t/modules/rewrite.t @@ -0,0 +1,186 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## mod_rewrite tests +## +## extra.conf.in: + +my @map = qw(txt rnd prg); #dbm XXX: howto determine dbm support is available? +my @num = qw(1 2 3 4 5 6); +my @url = qw(forbidden gone perm temp); +my @todo; +my $r; + +if (!have_min_apache_version('2.4.19')) { + # PR 50447, server context + push @todo, 26 +} +if (!have_min_apache_version('2.4')) { + # PR 50447, directory context (r1044673) + push @todo, 24 +} + +# Specific tests for PR 58231 +my $vary_header_tests = (have_min_apache_version("2.4.30") ? 9 : 0) + (have_min_apache_version("2.4.29") ? 4 : 0); +my $cookie_tests = have_min_apache_version("2.4.47") ? 6 : 0; + +plan tests => @map * @num + 16 + $vary_header_tests + $cookie_tests, todo => \@todo, need_module 'rewrite'; + +foreach (@map) { + foreach my $n (@num) { + ## throw $_ into upper case just so we can test out internal + ## 'tolower' map in mod_rewrite + $_=uc($_); + + $r = GET_BODY("/modules/rewrite/$n", 'Accept' => $_); + chomp $r; + $r =~ s/\r//g; + + if ($_ eq 'RND') { + ## check that $r is just a single digit. + unless ($r =~ /^[\d]$/) { + ok 0; + next; + } + + ok ($r =~ /^[$r-6]$/); + } else { + ok ($r eq $n); + } + } +} + +$r = GET_BODY("/modules/rewrite/", 'Accept' => 7); +chomp $r; +$r =~ s/\r//g; +ok ($r eq "BIG"); +$r = GET_BODY("/modules/rewrite/", 'Accept' => 0); +chomp $r; +$r =~ s/\r//g; +ok ($r eq "ZERO"); +$r = GET_BODY("/modules/rewrite/", 'Accept' => 'lucky13'); +chomp $r; +$r =~ s/\r//g; +ok ($r eq "JACKPOT"); + +$r = GET_BODY("/modules/rewrite/qsa.html?baz=bee"); +chomp $r; +ok t_cmp($r, qr/\nQUERY_STRING = foo=bar\&baz=bee\n/s, "query-string append test"); + +# PR 50447 (double URL-escaping of the query string) +my $hostport = Apache::TestRequest::hostport(); + +$r = GET("/modules/rewrite/redirect-dir.html?q=%25", redirect_ok => 0); +ok t_cmp($r->code, 301, "per-dir redirect response code is OK"); +ok t_cmp($r->header("Location"), "http://$hostport/foobar.html?q=%25", + "per-dir query-string escaping is OK"); + +$r = GET("/modules/rewrite/redirect.html?q=%25", redirect_ok => 0); +ok t_cmp($r->code, 301, "redirect response code is OK"); +ok t_cmp($r->header("Location"), "http://$hostport/foobar.html?q=%25", + "query-string escaping is OK"); + +if (have_module('mod_proxy')) { + $r = GET_BODY("/modules/rewrite/proxy.html"); + chomp $r; + ok t_cmp($r, "JACKPOT", "request was proxied"); + + # PR 46428 + $r = GET_BODY("/modules/proxy/rewrite/foo bar.html"); + chomp $r; + ok t_cmp($r, "foo bar", "per-dir proxied rewrite escaping worked"); +} else { + skip "Skipping rewrite to proxy; no proxy module." foreach (1..2); +} + +if (have_module('mod_proxy') && have_cgi) { + # regression in 1.3.32, see PR 14518 + $r = GET_BODY("/modules/rewrite/proxy2/env.pl?fish=fowl"); + chomp $r; + ok t_cmp($r, qr/QUERY_STRING = fish=fowl\n/s, "QUERY_STRING passed OK"); + + ok t_cmp(GET_RC("/modules/rewrite/proxy3/env.pl?horse=norman"), 404, + "RewriteCond QUERY_STRING test"); + + $r = GET_BODY("/modules/rewrite/proxy3/env.pl?horse=trigger"); + chomp $r; + ok t_cmp($r, qr/QUERY_STRING = horse=trigger\n/s, "QUERY_STRING passed OK"); + + $r = GET("/modules/rewrite/proxy-qsa.html?bloo=blar"); + ok t_cmp($r->code, 200, "proxy/QSA test success"); + + ok t_cmp($r->as_string, qr/QUERY_STRING = foo=bar\&bloo=blar\n/s, + "proxy/QSA test appended args correctly"); +} else { + skip "Skipping rewrite QUERY_STRING test; missing proxy or CGI module" foreach (1..5); +} + +if (have_min_apache_version('2.4')) { + # See PR 60478 and the corresponding config in extra.conf + $r = GET("/modules/rewrite/pr60478-rewrite-loop/a/X/b/c"); + ok t_cmp($r->code, 500, "PR 60478 rewrite loop is halted"); +} else { + skip "Skipping PR 60478 test; requires ap_expr in version 2.4" +} + +if (have_min_apache_version("2.4.29")) { + # PR 58231: Vary:Host header (was) mistakenly added to the response + $r = GET("/modules/rewrite/vary1.html", "Host" => "test1"); + ok t_cmp($r->content, qr/VARY2/, "Correct internal redirect happened, OK"); + ok t_cmp($r->header("Vary"), qr/(?!.*Host.*)/, "Vary:Host header not added, OK"); + + $r = GET("/modules/rewrite/vary1.html", "Host" => "test2"); + ok t_cmp($r->content, qr/VARY2/, "Correct internal redirect happened, OK"); + ok t_cmp($r->header("Vary"), qr/(?!.*Host.*)/, "Vary:Host header not added, OK"); +} + +if (have_min_apache_version("2.4.30")) { + # PR 58231: Vary header added when a condition evaluates to true and + # the RewriteRule happens in a directory context. + $r = GET("/modules/rewrite/vary3.html", "User-Agent" => "directory-agent"); + ok t_cmp($r->content, qr/VARY4/, "Correct internal redirect happened, OK"); + ok t_cmp($r->header("Vary"), qr/User-Agent/, "Vary:User-Agent header added, OK"); + + # Corner cases in which two RewriteConds are joined using the [OR] + # operator (or similar). + # 1) First RewriteCond condition evaluates to true, so only the related + # header value is added to the Vary list even though the second condition + # evaluates to true as well. + $r = GET("/modules/rewrite/vary3.html", + "Referer" => "directory-referer", + "Accept" => "directory-accept"); + ok t_cmp($r->content, qr/VARY4/, "Correct internal redirect happened, OK"); + ok t_cmp($r->header("Vary"), qr/Accept/, "Vary:Accept header added, OK"); + # 2) First RewriteCond condition evaluates to false and the second to true, + # so only the second condition's header value is added to the Vary list. + $r = GET("/modules/rewrite/vary3.html", + "Referer" => "directory-referer", + "Accept" => "this-is-not-the-value-in-the-rewritecond"); + ok t_cmp($r->content, qr/VARY4/, "Correct internal redirect happened, OK"); + ok t_cmp($r->header("Vary"), qr/Referer/, "Vary:Referer header added, OK"); + ok t_cmp($r->header("Vary"), qr/(?!.*Accept.*)/, "Vary:Accept header not added, OK"); + + # Vary:Host header (was) mistakenly added to the response + $r = GET("/modules/rewrite/vary3.html", "Host" => "directory-domain"); + ok t_cmp($r->content, qr/VARY4/, "Correct internal redirect happened, OK"); + ok t_cmp($r->header("Vary"), qr/(?!.*Host.*)/, "Vary:Host header not added, OK"); +} + +if (have_min_apache_version("2.4.47")) { + $r = GET("/modules/rewrite/cookie/"); + ok t_cmp($r->header("Set-Cookie"), qr/(?!.*SameSite=.*)/, "samesite not present with no arg"); + $r = GET("/modules/rewrite/cookie/0"); + ok t_cmp($r->header("Set-Cookie"), qr/(?!.*SameSite=.*)/, "samesite not present with 0"); + $r = GET("/modules/rewrite/cookie/false"); + ok t_cmp($r->header("Set-Cookie"), qr/(?!.*SameSite=.*)/, "samesite not present with false"); + $r = GET("/modules/rewrite/cookie/none"); + ok t_cmp($r->header("Set-Cookie"), qr/SameSite=none/, "samesite=none"); + $r = GET("/modules/rewrite/cookie/lax"); + ok t_cmp($r->header("Set-Cookie"), qr/SameSite=lax/, "samesite=lax"); + $r = GET("/modules/rewrite/cookie/foo"); + ok t_cmp($r->header("Set-Cookie"), qr/SameSite=foo/, "samesite=foo"); +} diff --git a/debian/perl-framework/t/modules/sed.t b/debian/perl-framework/t/modules/sed.t new file mode 100644 index 0000000..10edcd7 --- /dev/null +++ b/debian/perl-framework/t/modules/sed.t @@ -0,0 +1,26 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my @ts = ( + # see t/conf/extra.conf.in + { url => "/apache/sed/out-foo/foobar.html", content => 'barbar', msg => "sed output filter", code => 200 } +); + +my $tests = 2*scalar @ts; + +plan tests => $tests, need_module('sed'); + + +for my $t (@ts) { + my $req = GET $t->{'url'}; + ok t_cmp($req->code, $t->{'code'}, "status code for " . $t->{'url'}); + my $content = $req->content; + chomp($content); + ok t_cmp($content, $t->{content}, $t->{msg}); +} + + diff --git a/debian/perl-framework/t/modules/session.t b/debian/perl-framework/t/modules/session.t new file mode 100644 index 0000000..617239c --- /dev/null +++ b/debian/perl-framework/t/modules/session.t @@ -0,0 +1,208 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## +## mod_session tests +## + +# Code, session data, dirty, expiry, content. +my $checks_per_test = 5; + +# Session, API, Encoding, SessionEnv, SessionHeader, SessionMaxAge, +# SessionExpiryUpdateInterval, SessionInclude/Exclude. +my $num_tests = 2 + 4 + 5 + 2 + 1 + 4 + 7 + 3; + +my @todo = ( + # Session writable after decode failure - PR 58171 + 53, 54, + # Session writable after expired - PR 56052 + 88, 89 +); + +# Until the fix for PR 57300 is backported, sessions are always saved. +if (!have_min_apache_version('2.4.41')) { + my @todo_backport = ( 8, 18, 38, 43, 48, 58, 63, 133 ); + push(@todo, @todo_backport); +} + +plan tests => $num_tests * $checks_per_test, + todo => \@todo, + need need_module('session'), + need_min_apache_version('2.3.0'); + +# APR time is in microseconds. +use constant APR_TIME_PER_SEC => 1000000; + +# Don't use math ops, the result is too big for 32 Bit Perl +# Use adding of trailing "0"s instead +sub expiry_from_seconds +{ + my $seconds = shift; + return $seconds . "0" x (length(APR_TIME_PER_SEC) - 1); +} + +# check_result(name, res, session, dirty, expiry, response) +sub check_result +{ + my $name = shift; + my $res = shift; + my $session = shift // '(none)'; + my $dirty = shift // 0; + my $expiry = shift // 0; + my $response = shift // ''; + + ok t_cmp($res->code, 200, "response code ($name)"); + my $gotSession = $res->header('X-Test-Session') // '(none)'; + my $sessionData = $gotSession; + + if ($gotSession =~ /^(?:(.+)&)?expiry=([0-9]+)(?:&(.*))?$/i) { + # Don't use math ops, $2 is too big for 32 Bit Perl + # Use stripping of trailing "0"s instead + my $gotExpiry = substr($2, 0, -1 * (length(APR_TIME_PER_SEC) - 1)); + t_debug "expiry of $gotExpiry ($name)"; + ok $expiry && time() < $gotExpiry; + + # Combine the remaining data (if there is any) without the expiry. + $sessionData = join('&', grep(defined, ($1, $3))); + } + else { + t_debug "no expiry ($name)"; + ok !$expiry; + } + + ok t_cmp($sessionData, $session, "session header ($name)"); + my $got = $res->header('X-Test-Session-Dirty') // 0; + ok t_cmp($got, $dirty, "session dirty ($name)"); + $got = $res->content; + chomp($got); + ok t_cmp($got, $response, "body ($name)"); + return $gotSession; +} + +# check_get(name, path, session, dirty, expiry, response) +sub check_get +{ + my $name = shift; + my $path = shift; + + t_debug "$name: GET $path"; + my $res = GET "/sessiontest$path"; + return check_result $name, $res, @_; +} + +# check_post(name, path, data, session, dirty, expiry, response) +sub check_post +{ + my $name = shift; + my $path = shift; + my $data = shift; + + t_debug "$name: POST $path"; + my $res = POST "/sessiontest$path", content => $data; + return check_result $name, $res, @_; +} + +# check_custom(name, result, session, dirty, expiry, response) +sub check_custom +{ + my $name = shift; + my $res = shift; + + t_debug "$name"; + return check_result $name, $res, @_; +} + +my $session = 'test=value'; +my $encoded_prefix = 'TestEncoded:'; +my $encoded_session = $encoded_prefix . $session; +my $create_session = 'action=set&name=test&value=value'; +my $read_session = 'action=get&name=test'; + +# Session directive +check_post 'Cannot write session when off', '/', $create_session; +check_get 'New empty session is not saved', '/on'; + +# API optional functions +check_post 'Set session', '/on', $create_session, $session, 1; +check_post 'Get session', "/on?$session", $read_session, + undef, 0, 0, 'value'; +check_post 'Delete session', "/on?$session", 'action=set&name=test', '', 1; +check_post 'Edit session', "/on?$session", 'action=set&name=test&value=', + 'test=', 1; + +# Encoding hooks +check_post 'Encode session', '/on/encode', $create_session, + $encoded_session, 1; +check_post 'Decode session', "/on/encode?$encoded_session", $read_session, + undef, 0, 0, 'value'; +check_get 'Custom decoder failure', "/on/encode?$session"; +check_get 'Identity decoder failure', "/on?&=test"; +check_post 'Session writable after decode failure', "/on/encode?$session", + $create_session, $encoded_session, 1; + +# SessionEnv directive - requires mod_include +if (have_module('include')) { + check_custom 'SessionEnv Off', GET("/modules/session/env.shtml?$session"), + undef, 0, 0, '(none)'; + check_get 'SessionEnv On', "/on/env/on/env.shtml?$session", + undef, 0, 0, $session; +} +else { + for (1 .. 2 * $checks_per_test) { + skip "SessionEnv tests require mod_include", 1; + } +} + +# SessionHeader directive +check_custom 'SessionHeader', GET("/sessiontest/on?$session&another=1", + 'X-Test-Session-Override' => 'another=5&last=7'), + "$session&another=5&last=7", 1; + +# SessionMaxAge directive +my $future_expiry = expiry_from_seconds(time() + 200); + +check_get 'SessionMaxAge adds expiry', "/on/expire?$session", $session, 0, 1; +check_get 'Discard expired session', "/on/expire?$session&expiry=1", '', 0, 1; +check_get 'Keep non-expired session', + "/on/expire?$session&expiry=$future_expiry", $session, 0, 1; +check_post 'Session writable after expired', '/on/expire?expiry=1', + $create_session, $session, 1, 1; + +# SessionExpiryUpdateInterval directive - new in 2.4.41 +if (have_module('version') && have_min_apache_version('2.4.41')) { + my $max_expiry = expiry_from_seconds(time() + 100); + my $threshold_expiry = expiry_from_seconds(time() + 40); + + check_get 'SessionExpiryUpdateInterval off by default', + "/on/expire?$session&expiry=$max_expiry", $session, 0, 1; + check_get 'SessionExpiryUpdateInterval skips save', + "/on/expire/cache?$session&expiry=$max_expiry"; + check_post 'Session readable when save skipped', + "/on/expire/cache?$session&expiry=$max_expiry", $read_session, + undef, 0, 0, 'value'; + check_post 'Dirty overrides SessionExpiryUpdateInterval', + "/on/expire/cache?$session&expiry=$max_expiry", $create_session, + $session, 1, 1; + check_get 'Old session always updates expiry', + "/on/expire/cache?$session&expiry=$threshold_expiry", $session, 0, 1; + check_get 'New empty session with expiry not saved', "/on/expire/cache"; + check_post 'Can create session with SessionExpiryUpdateInterval', + "/on/expire/cache", $create_session, $session, 1, 1; +} +else { + for (1 .. 7 * $checks_per_test) { + skip "SessionExpiryUpdateInterval tests require backporting"; + } +} + +# SessionInclude/Exclude directives +check_post 'Cannot write session when not included', + "/on/include?$session", $create_session; +check_post 'Can read session when included', + "/on/include/yes?$session", $read_session, undef, 0, 0, 'value'; +check_post 'SessionExclude overrides SessionInclude', + "/on/include/yes/no?$session", $create_session; diff --git a/debian/perl-framework/t/modules/session_cookie.t b/debian/perl-framework/t/modules/session_cookie.t new file mode 100644 index 0000000..46f7bf2 --- /dev/null +++ b/debian/perl-framework/t/modules/session_cookie.t @@ -0,0 +1,29 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => have_min_apache_version('2.5.0') ? 4 : 2, + need_module 'session_cookie'; + +my $uri = '/modules/session_cookie/test404'; +my $r = GET($uri); +my @set_cookie_headers = $r->header("Set-Cookie"); +ok t_cmp($r->code, 404); + +# See PR: 60910 +if (have_min_apache_version('2.5.0')) { + ok t_cmp(scalar(@set_cookie_headers), 1, "Set-Cookie header not duplicated in error response (404)."); +} + +$uri = '/modules/session_cookie/test'; +$r = GET($uri); +@set_cookie_headers = $r->header("Set-Cookie"); +ok t_cmp($r->code, 200); + +# See PR: 60910 +if (have_min_apache_version('2.5.0')) { + ok t_cmp(scalar(@set_cookie_headers), 1, "Set-Cookie header not duplicated in successful response (200)."); +}
\ No newline at end of file diff --git a/debian/perl-framework/t/modules/setenvif.t b/debian/perl-framework/t/modules/setenvif.t new file mode 100644 index 0000000..cb561c2 --- /dev/null +++ b/debian/perl-framework/t/modules/setenvif.t @@ -0,0 +1,193 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $vars = Apache::Test::vars(); +my $htdocs = Apache::Test::vars('documentroot'); +my $body; + +## +## mod_setenvif tests +## + +my $good_ua = '^libwww-perl/.*'; +my $bad_ua = 'foo-browser/0.1'; + +my $page = "/modules/setenvif/htaccess/setenvif.shtml"; +my %var_att = + ( + 'Remote_Host' => + { + 'pass' => $vars->{remote_addr}, + 'fail' => 'some.where.else.com' + }, + 'Remote_Addr' => + { + 'pass' => $vars->{remote_addr}, + 'fail' => '63.125.18.195' + }, + 'Request_Method' => + { + 'pass' => 'GET', + 'fail' => 'POST' + }, + 'Request_Protocol' => + { + 'pass' => 'HTTP', + 'fail' => 'FTP' + }, + 'Request_URI' => + { + 'pass' => $page, + 'fail' => 'foo.html' + }, + # Test with a regex. Looking for 'User-Agent' + '^User-Ag' => + { + 'pass' => $good_ua, + 'fail' => $bad_ua + } + ); + +my @var = qw(VAR_ONE VAR_TWO VAR_THREE); + +my $htaccess = "$htdocs/modules/setenvif/htaccess/.htaccess"; + +plan tests => @var * 10 + (keys %var_att) * 6 * @var + 4, + have_module qw(setenvif include); + +sub write_htaccess { + my $string = shift; + open (HT, ">$htaccess") or die "can't open $htaccess: $!"; + print HT $string; + close(HT); +} + +sub test_all_vars { + my $exp_modifier = shift; + my $conf_str = shift; + my $set = 'set'; + + my ($actual, $expected); + foreach my $var (@var) { + $conf_str .= " $var=$set"; + write_htaccess($conf_str); + $expected = set_expect($exp_modifier, $conf_str); + $actual = GET_BODY $page; + $actual =~ s/\r//sg; #win32 + + print "---\n"; + print "conf:\n$conf_str\n"; + print "expecting:\n->$expected<-\n"; + print "got:\n->$actual<-\n"; + + ok ($actual eq $expected); + } +} + +sub set_expect { + my $not = shift; + my $conf_str = shift; + my ($v, $exp_str) = ('',''); + + my %exp = + ( + 1 => 'VAR_ONE', + 2 => 'VAR_TWO', + 3 => 'VAR_THREE' + ); + + foreach (sort keys %exp) { + my $foo = $exp{$_}; + $v = '(none)'; + if ($conf_str =~ /$foo=(\S+)/) { + $v = $1 unless $not; + } + + $exp_str .= "$_:$v\n"; + } + + return $exp_str; +} + +## test simple browser match ## +test_all_vars(0,"BrowserMatch $good_ua"); +test_all_vars(1,"BrowserMatch $bad_ua"); + +## test SetEnvIf with variable attributes ## +foreach my $attribute (sort keys %var_att) { + test_all_vars(0,"SetEnvIf $attribute $var_att{$attribute}{pass}"); + test_all_vars(1,"SetEnvIf $attribute $var_att{$attribute}{fail}"); + + ## some 'relaying' variables ## + test_all_vars(0, + "SetEnvIf $attribute $var_att{$attribute}{pass} RELAY=1\nSetEnvIf RELAY 1"); + test_all_vars(1, + "SetEnvIf $attribute $var_att{$attribute}{pass} RELAY=1\nSetEnvIf RELAY 0"); + + ## SetEnvIfNoCase tests ## + my $uc = uc $var_att{$attribute}{pass}; + test_all_vars(0,"SetEnvIfNoCase $attribute $uc"); + $uc = uc $var_att{$attribute}{fail}; + test_all_vars(1,"SetEnvIfNoCase $attribute $uc"); +} + +## test 'relaying' variables ## +test_all_vars(0,"BrowserMatch $good_ua RELAY=1\nSetEnvIf RELAY 1"); +test_all_vars(0, + "BrowserMatch $good_ua RELAY=1\nSetEnvIf RELAY 1 R2=1\nSetEnvIf R2 1"); +test_all_vars(1, + "BrowserMatch $good_ua RELAY=1\nSetEnvIf RELAY 1 R2=1\nSetEnvIf R2 0"); +test_all_vars(1,"BrowserMatch $good_ua RELAY=0\nSetEnvIf RELAY 1"); +test_all_vars(1,"BrowserMatch $good_ua RELAY=1\nSetEnvIf RELAY 0"); + +## test '!' ## +# We set then unset 'R2' (see a few lines above for the corresponding test, without the 'unset' +test_all_vars(1, + "BrowserMatch $good_ua RELAY=1\nSetEnvIf RELAY 1 R2=1\nSetEnvIf RELAY 1 !R2\nSetEnvIf R2 1"); + +## test SetEnvIfExpr ## +test_all_vars(0, "SetEnvIfExpr \"%{REQUEST_URI} =~ /\.shtml\$/\""); +test_all_vars(1, "SetEnvIfExpr \"%{REQUEST_URI} =~ /\.foo\$/\""); + +## test SetEnvIfExpr with replacement ## +write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} =~ /\.\(sh\)tml\$/\" VAR_ONE=\$0 VAR_TWO=\$1"); +$body = GET_BODY $page; +ok t_cmp($body, "1:.shtml\n2:sh\n3:(none)\n"); + +write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} !~ /\.\(sh\)tml\$/\" VAR_ONE=\$0 VAR_TWO=\$1"); +$body = GET_BODY $page; +ok t_cmp($body, "1:(none)\n2:(none)\n3:(none)\n"); + +## test SetEnvIfExpr with replacement when regex does NOT match ## +write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} =~ /\.\(sh\)tmlXXX\$/\" VAR_ONE=\$0 VAR_TWO=\$1"); +$body = GET_BODY $page; +ok t_cmp($body, "1:(none)\n2:(none)\n3:(none)\n"); + +if (need_min_apache_version("2.4.38")) { + ## test SetEnvIfExpr with replacement when regex is REQUIRED to NOT match ## + write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} !~ /\.\(sh\)tmlXXX\$/\" VAR_ONE=\$0 VAR_TWO=\$1"); + $body = GET_BODY $page; + ok t_cmp($body, "1:\$0\n2:\$1\n3:(none)\n"); +} +else { + # Skip for versions without r1786235 backported + skip "skipping inverted match test with version <2.4.38" +} + +## i think this should work, but it doesnt. +## leaving it commented now pending investigation. +## seems you cant override variables that have been previously set. +## +## test_all_vars(0, +## "SetEnv RELAY 1\nSetEnvIf RELAY 1 RELAY=2\nSetEnvIf RELAY 2"); +## test_all_vars(0, +## "BrowserMatch $good_ua RELAY=1\nSetEnvIf RELAY 1 RELAY=2\nSetEnvIf RELAY 2"); +## +## + +## clean up ## +unlink $htaccess if -e $htaccess; diff --git a/debian/perl-framework/t/modules/speling.t b/debian/perl-framework/t/modules/speling.t new file mode 100644 index 0000000..85af159 --- /dev/null +++ b/debian/perl-framework/t/modules/speling.t @@ -0,0 +1,64 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my @testcasespaths = ( + ['/modules/speling/nocase/'], + ['/modules/speling/caseonly/'], +); + +my @testcases = ( + ## File Test CheckCaseOnly Off On + ['good.html', "normal", 200, 200], + ['god.html', "omission", 301, 404], + ['goood.html', "insertion", 301, 404], + ['godo.html', "transposition", 301, 404], + ['go_d.html', "wrong character", 301, 404], + + ['good.wrong_ext', "wrong extension", 300, 300], + ['GOOD.wrong_ext', "NC wrong extension", 300, 300], + + ['Bad.html', "wrong filename", 404, 404], + ['dogo.html', "double transposition", 404, 404], + ['XooX.html', "double wrong character", 404, 404], + + ['several0.html', "multiple choice", 300, 404], +); + +# macOS HFS is case-insensitive but case-preserving so the below tests +# would cause misleading failures +if ($^O ne "darwin") { + push (@testcases, ['GOOD.html', "case", 301, 301]); +} + +plan tests => scalar @testcasespaths * scalar @testcases * 2, need 'mod_speling'; + +my $r; +my $code = 2; + +# Disable redirect +local $Apache::TestRequest::RedirectOK = 0; + +foreach my $p (@testcasespaths) { + foreach my $t (@testcases) { + ## + #local $Apache::TestRequest::RedirectOK = 0; + $r = GET($p->[0] . $t->[0]); + + # Checking for return code + ok t_cmp($r->code, $t->[$code], "Checking " . $t->[1] . ". Expecting: ". $t->[$code]); + + # Checking that the expected filename is in the answer + if ($t->[$code] != 200 && $t->[$code] != 404) { + ok t_cmp($r->content, qr/good\.html|several1\.html/, "Redirect ok"); + } + else { + skip "Skipping. No redirect with status " . $t->[$code]; + } + } + + $code = $code+1; +} diff --git a/debian/perl-framework/t/modules/status.t b/debian/perl-framework/t/modules/status.t new file mode 100644 index 0000000..6a3dab1 --- /dev/null +++ b/debian/perl-framework/t/modules/status.t @@ -0,0 +1,20 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## +## mod_status quick test +## + +plan tests => 1, need_module 'status'; + +my $uri = '/server-status'; +my $servername = Apache::Test::vars()->{servername}; + +my $title = "Apache Server Status for $servername"; + +my $status = GET_BODY $uri; +print "$status\n"; +ok ($status =~ /$title/i); diff --git a/debian/perl-framework/t/modules/substitute.t b/debian/perl-framework/t/modules/substitute.t new file mode 100644 index 0000000..0f111c0 --- /dev/null +++ b/debian/perl-framework/t/modules/substitute.t @@ -0,0 +1,125 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw(t_write_file); + +Apache::TestRequest::user_agent(keep_alive => 1); + +my $debug = 0; +my $url = '/modules/substitue/test.txt'; + +# mod_bucketeer control chars +my $B = chr(0x02); +my $F = chr(0x06); +my $P = chr(0x10); + +my @simple_cases = (); + +my @test_cases = ( + [ "f${B}o${P}ofoo" => 's/foo/bar/' ], + [ "f${B}o${P}ofoo" => 's/fo/fa/', 's/fao/bar/' ], + [ "foofoo" => 's/Foo/bar/' ], + [ "fo${F}ofoo" => 's/Foo/bar/i' ], + [ "foOFoo" => 's/OF/of/', 's/foo/bar/' ], + [ "fofooo" => 's/(.)fo/$1of/', 's/foo/bar/' ], + [ "foof\noo" => 's/f.oo/bar/' ], + [ "xfooo" => 's/foo/fo/' ], + [ "xfoo" x 4000 => 's/foo/bar/', 's/FOO/BAR/' ], + [ "foox\n" x 4000 => 's/foo/bar/', 's/FOO/BAR/' ], + [ "a.baxb(" => 's/a.b/a$1/n' ], + [ "a.baxb(" => 's/a.b/a$1/n', 's/1axb(/XX/n' ], + [ "xfoo" x 4000 => 's/foo/bar/n', 's/FOO/BAR/n' ], +); + +if (have_min_apache_version("2.3.5")) { + # tests for r1307067 + push @test_cases, [ "x<body>x" => 's/<body>/&/' ], + [ "x<body>x" => 's/<body>/$0/' ], + [ "foobar" => 's/(oo)b/c$1/' ], + [ "foobar" => 's/(oo)b/c\$1/' ], + [ "foobar" => 's/(oo)b/\d$1/' ]; +} + +if (have_min_apache_version("2.4.42")) { + push @simple_cases, [ "foo\nbar" => 's/foo.*/XXX$0XXX', "XXXfooXXX\nbar" ], +} +plan tests => scalar @test_cases + scalar @simple_cases, + need need_lwp, + need_module('mod_substitute'), + need_module('mod_bucketeer'); + +foreach my $t (@test_cases) { + my ($content, @rules) = @{$t}; + + write_testfile($content); + write_htaccess(@rules); + + # We assume that perl does the right thing (TM) and compare that with + # mod_substitute's result. + my $expect = $content; + $expect =~ s/[$B$F$P]+//g; + foreach my $rule (@rules) { + if ($rule =~ s/n$//) { + # non-regex match, escape specials for perl + my @parts = split('/', $rule); + $parts[1] = quotemeta($parts[1]); + $parts[2] = quotemeta($parts[2]); + $rule = join('/', @parts); + $rule .= '/' if (scalar @parts == 3); + } + else { + # special case: HTTPD uses $0 for the whole match, perl uses $& + $rule =~ s/\$0/\$&/g; + } + $rule .= "g"; # mod_substitute always does global search & replace + + # "no warnings" because the '\d' in one of the rules causes a warning, + # which we have set to be fatal. + eval "{\n no warnings ; \$expect =~ $rule\n}"; + } + + my $response = GET('/modules/substitute/test.txt'); + my $rc = $response->code; + my $got = $response->content; + my $ok = ($rc == 200) && ($got eq $expect); + print "got $rc '$got'", ($ok ? ": OK\n" : ", expected '$expect'\n"); + + ok($ok); +} + +foreach my $t (@simple_cases) { + my ($content, $rule, $expect) = @{$t}; + write_testfile($content); + write_htaccess($rule); + my $response = GET('/modules/substitute/test.txt'); + my $rc = $response->code; + my $got = $response->content; + my $ok = ($rc == 200) && ($got eq $expect); + print "got $rc '$got'", ($ok ? ": OK\n" : ", expected '$expect'\n"); + + ok($ok); +} +exit 0; + +### sub routines +sub write_htaccess +{ + my @rules = @_; + my $file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'htdocs', + 'modules', 'substitute', '.htaccess'); + my $content = "SetOutputFilter BUCKETEER;SUBSTITUTE\n"; + $content .= "Substitute $_\n" for @rules; + t_write_file($file, $content); + print "$content<===\n" if $debug; +} + +sub write_testfile +{ + my $content = shift; + my $file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'htdocs', + 'modules', 'substitute', 'test.txt'); + t_write_file($file, $content); + print "$content<===\n" if $debug; +} diff --git a/debian/perl-framework/t/modules/unique_id.t b/debian/perl-framework/t/modules/unique_id.t new file mode 100644 index 0000000..a3f206b --- /dev/null +++ b/debian/perl-framework/t/modules/unique_id.t @@ -0,0 +1,27 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## +## mod_unique_id tests +## + +my $iters = 100; +my $url = "/modules/cgi/unique-id.pl"; +my %idx = (); + +plan tests => 3 * $iters, need need_cgi, need_module('unique_id'); + +foreach (1..$iters) { + my $r = GET $url; + ok t_cmp($r->code, 200, "fetch unique ID"); + my $v = $r->content; + print "# unique id: $v\n"; + chomp $v; + ok length($v) >= 20; + ok !exists($idx{$v}); + $idx{$v} = 1; +} diff --git a/debian/perl-framework/t/modules/usertrack.t b/debian/perl-framework/t/modules/usertrack.t new file mode 100644 index 0000000..d9f62da --- /dev/null +++ b/debian/perl-framework/t/modules/usertrack.t @@ -0,0 +1,74 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @testcases = ( + ['/modules/usertrack/foo.html'], + ['/modules/usertrack/bar.html'], + ['/modules/usertrack/foo.html'], + ['/modules/usertrack/bar.html'], +); + +my $iters = 100; +my %cookiex = (); + +plan tests => (scalar (@testcases) * 2 + 2) * $iters + 1 + 3, need 'mod_usertrack'; + +foreach (1..$iters) { + my $nb_req = 1; + my $cookie = ""; + + foreach my $t (@testcases) { + ## + my $r = GET($t->[0], "Cookie" => $cookie); + + # Checking for return code + ok t_cmp($r->code, 200, "Checking return code is '200'"); + + # Checking for content + my $setcookie = $r->header('Set-Cookie'); + + # Only the first and third requests of an iteration must have a Set-Cookie + if ((($nb_req == 1) || ($nb_req == 3)) && (defined $setcookie)) { + ok defined $setcookie; + + print "Set-Cookie: " . $setcookie . "\n"; + # Copy the cookie in order to send it back in the next requests + $cookie = substr($setcookie, 0, index($setcookie, ";") ); + print "Cookie: " . $cookie . "\n"; + + # This cookie must not have been already seen + ok !exists($cookiex{$cookie}); + $cookiex{$cookie} = 1; + } + else { + ok !(defined $setcookie); + } + + # After the 2nd request, we lie and send a modified cookie. + # So the 3rd request whould receive a new cookie + if ($nb_req == 2) { + $cookie = "X" . $cookie; + } + + $nb_req++; + } +} + +# Check the overall number of cookies generated +ok ((scalar (keys %cookiex)) == ($iters * 2)); + +# Check that opt-in flags aren't set +my $r = GET("/modules/usertrack/foo.html"); +ok t_cmp($r->code, 200, "Checking return code is '200'"); +# Checking for content +my $setcookie = $r->header('Set-Cookie'); +t_debug("$setcookie"); +ok defined $setcookie; +$setcookie =~ m/(Secure|HTTPonly|SameSite)/i; +ok t_cmp($1, undef); + + diff --git a/debian/perl-framework/t/modules/vhost_alias.t b/debian/perl-framework/t/modules/vhost_alias.t new file mode 100644 index 0000000..a89a97b --- /dev/null +++ b/debian/perl-framework/t/modules/vhost_alias.t @@ -0,0 +1,101 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $htdocs = Apache::Test::vars('documentroot'); +my $url = '/index.html'; +my $cgi_name = "test-cgi"; +my $cgi_string = "test cgi for"; +my $root = "$htdocs/modules/vhost_alias"; +my $ext; + +my @vh = qw(www.vha-test.com big.server.name.from.heck.org ab.com w-t-f.net); + +plan tests => @vh * 2, need need_module('vhost_alias'), need_cgi, need_lwp; + +Apache::TestRequest::scheme('http'); #ssl not listening on this vhost +Apache::TestRequest::module('mod_vhost_alias'); #use this module's port + +## test environment setup ## +t_mkdir($root); + +foreach (@vh) { + my @part = split /\./, $_; + my $d = "$root/"; + + ## create VirtualDocumentRoot htdocs/modules/vhost_alias/%2/%1.4/%-2/%2+ + ## %2 ## + if ($part[1]) { + $d .= $part[1]; + } else { + $d .= "_"; + } + t_mkdir($d); + + $d .= "/"; + ## %1.4 ## + if (length($part[0]) < 4) { + $d .= "_"; + } else { + $d .= substr($part[0], 3, 1); + } + t_mkdir($d); + + $d .= "/"; + ## %-2 ## + if ($part[@part-2]) { + $d .= $part[@part-2]; + } else { + $d .= "_"; + } + t_mkdir($d); + + $d .= "/"; + ## %2+ ## + for (my $i = 1;$i < @part;$i++) { + $d .= $part[$i]; + $d .= "." if $part[$i+1]; + } + t_mkdir($d); + + ## write index.html for the VirtualDocumentRoot ## + t_write_file("$d$url",$_); + + ## create directories for VirtualScriptAlias tests ## + $d = "$root/$_"; + t_mkdir($d); + $d .= "/"; + + ## write cgi ## + my $cgi_content = <<SCRIPT; +echo Content-type: text/html +echo +echo $cgi_string $_ +SCRIPT + + $ext = Apache::TestUtil::t_write_shell_script("$d$cgi_name", $cgi_content); + chmod 0755, "$d$cgi_name.$ext"; +} + +## run tests ## +foreach (@vh) { + ## test VirtalDocumentRoot ## + ok t_cmp(GET_BODY($url, Host => $_), + $_, + "VirtalDocumentRoot test" + ); + + ## test VirtualScriptAlias ## + my $cgi_uri = "/cgi-bin/$cgi_name.$ext"; + my $actual = GET_BODY $cgi_uri, Host => $_; + $actual =~ s/[\r\n]+$//; + ok t_cmp($actual, + "$cgi_string $_", + "VirtualScriptAlias test" + ); +} + + diff --git a/debian/perl-framework/t/php-fpm/etc/php-fpm.conf b/debian/perl-framework/t/php-fpm/etc/php-fpm.conf new file mode 100644 index 0000000..1a2def0 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/etc/php-fpm.conf @@ -0,0 +1,19 @@ +;;;;;;;;;;;;;;;;;;;;; +; FPM Configuration ; +;;;;;;;;;;;;;;;;;;;;; + +; All relative paths in this configuration file are relative to PHP's install +; prefix (/usr/local). This prefix can be dynamically changed by using the +; '-p' argument from the command line. + +;;;;;;;;;;;;;;;;;; +; Global Options ; +;;;;;;;;;;;;;;;;;; + +[global] + +error_log = log/php-fpm.log +syslog.ident = php-fpm +log_level = notice +daemonize = no +include=etc/php-fpm.d/*.conf diff --git a/debian/perl-framework/t/php-fpm/etc/php-fpm.d/www.conf b/debian/perl-framework/t/php-fpm/etc/php-fpm.d/www.conf new file mode 100644 index 0000000..1952525 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/etc/php-fpm.d/www.conf @@ -0,0 +1,7 @@ +; Start a new pool named 'www'. +; the variable $pool can be used in any directive and will be replaced by the +; pool name ('www' here) +[www] +listen = 127.0.0.1:9001 +pm = static +pm.max_children = 1 diff --git a/debian/perl-framework/t/php-fpm/fcgi.pl b/debian/perl-framework/t/php-fpm/fcgi.pl new file mode 100755 index 0000000..930b030 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/fcgi.pl @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +use FCGI; +use Socket; +use FCGI::ProcManager; +use Data::Dumper; + +$num_args = $#ARGV + 1; +if ($num_args != 1) { + print "\nUsage: fcgi.pl <socket>\n"; + exit 1; +} + +$proc_manager = FCGI::ProcManager->new( {n_processes => 1} ); +$socket = FCGI::OpenSocket( $ARGV[0], 10 ); +$request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, +$socket, &FCGI::FAIL_ACCEPT_ON_INTR ); +$proc_manager->pm_manage(); +if ($request) { + while ( $request->Accept() >= 0 ) { + $proc_manager->pm_pre_dispatch(); + print("Content-type: text/plain\r\n\r\n"); + print Dumper(\%req_params); + } +} +FCGI::CloseSocket($socket); diff --git a/debian/perl-framework/t/php-fpm/log/.empty b/debian/perl-framework/t/php-fpm/log/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/log/.empty diff --git a/debian/perl-framework/t/php-fpm/pools/www/.empty b/debian/perl-framework/t/php-fpm/pools/www/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/pools/www/.empty diff --git a/debian/perl-framework/t/php-fpm/run/.empty b/debian/perl-framework/t/php-fpm/run/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/run/.empty diff --git a/debian/perl-framework/t/php-fpm/var/log/.empty b/debian/perl-framework/t/php-fpm/var/log/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/var/log/.empty diff --git a/debian/perl-framework/t/php/README b/debian/perl-framework/t/php/README new file mode 100644 index 0000000..506ed74 --- /dev/null +++ b/debian/perl-framework/t/php/README @@ -0,0 +1,3 @@ +These tests were taken from the .phpt files in the 'tests' directory of the PHP source tarball. Some have been changed a bit, but most have been taken straight from the php test files. Credit is due to the author(s) of these tests. +http://www.php.net/ +jsachs@covalent.net diff --git a/debian/perl-framework/t/php/add.t b/debian/perl-framework/t/php/add.t new file mode 100644 index 0000000..646159f --- /dev/null +++ b/debian/perl-framework/t/php/add.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## add.php source: +## <?php $a=1; $b=2; $c=3; $d=$a+$b+$c; echo $d?> +## +## result should be '6' (1+2+3=6) + +my $result = GET_BODY "/php/add.php"; +ok $result eq '6'; diff --git a/debian/perl-framework/t/php/all.t b/debian/perl-framework/t/php/all.t new file mode 100644 index 0000000..13171f6 --- /dev/null +++ b/debian/perl-framework/t/php/all.t @@ -0,0 +1,9 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; + +#skip all tests in this directory unless php4 module is enabled +plan tests => 1, need_php; + +ok 1; diff --git a/debian/perl-framework/t/php/arg.t b/debian/perl-framework/t/php/arg.t new file mode 100644 index 0000000..48bca23 --- /dev/null +++ b/debian/perl-framework/t/php/arg.t @@ -0,0 +1,34 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, need_php; + +## arg.php source: +## <?php +## for($i=0;$i<$argc;$i++) { +## echo "$i: ".$argv[$i]."\n"; +## } +## ?> +## +## result should be '<arg number>: <arg>' for each arg sent. + +my @testargs = ('foo', 'b@r', 'testarg123-456-fu', 'ARGV', 'hello%20world'); +my ($expected, $testargs) = ('',''); +my $count = 0; + +foreach (@testargs) { + $testargs .= "$_+"; + $expected .= "$count: $_\n"; + $count++; +} +chop($testargs); ## get rid of trailing '+' + +my $result = GET_BODY "/php/arg.php?$testargs"; +ok t_cmp($result, + $expected, + "GET request for /php/arg.php?$testargs" + ); diff --git a/debian/perl-framework/t/php/cfunctions.t b/debian/perl-framework/t/php/cfunctions.t new file mode 100644 index 0000000..3873a8e --- /dev/null +++ b/debian/perl-framework/t/php/cfunctions.t @@ -0,0 +1,1015 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +0 +Dafna! +I'm still alive +Hey there!! +0 +1 +Dafna! +I'm still alive +Hey there!! +1 +2 +Dafna! +I'm still alive +Hey there!! +2 +3 +Dafna! +I'm still alive +Hey there!! +3 +4 +Dafna! +I'm still alive +Hey there!! +4 +5 +Dafna! +I'm still alive +Hey there!! +5 +6 +Dafna! +I'm still alive +Hey there!! +6 +7 +Dafna! +I'm still alive +Hey there!! +7 +8 +Dafna! +I'm still alive +Hey there!! +8 +9 +Dafna! +I'm still alive +Hey there!! +9 +10 +Dafna! +I'm still alive +Hey there!! +10 +11 +Dafna! +I'm still alive +Hey there!! +11 +12 +Dafna! +I'm still alive +Hey there!! +12 +13 +Dafna! +I'm still alive +Hey there!! +13 +14 +Dafna! +I'm still alive +Hey there!! +14 +15 +Dafna! +I'm still alive +Hey there!! +15 +16 +Dafna! +I'm still alive +Hey there!! +16 +17 +Dafna! +I'm still alive +Hey there!! +17 +18 +Dafna! +I'm still alive +Hey there!! +18 +19 +Dafna! +I'm still alive +Hey there!! +19 +20 +Dafna! +I'm still alive +Hey there!! +20 +21 +Dafna! +I'm still alive +Hey there!! +21 +22 +Dafna! +I'm still alive +Hey there!! +22 +23 +Dafna! +I'm still alive +Hey there!! +23 +24 +Dafna! +I'm still alive +Hey there!! +24 +25 +Dafna! +I'm still alive +Hey there!! +25 +26 +Dafna! +I'm still alive +Hey there!! +26 +27 +Dafna! +I'm still alive +Hey there!! +27 +28 +Dafna! +I'm still alive +Hey there!! +28 +29 +Dafna! +I'm still alive +Hey there!! +29 +30 +Dafna! +I'm still alive +Hey there!! +30 +31 +Dafna! +I'm still alive +Hey there!! +31 +32 +Dafna! +I'm still alive +Hey there!! +32 +33 +Dafna! +I'm still alive +Hey there!! +33 +34 +Dafna! +I'm still alive +Hey there!! +34 +35 +Dafna! +I'm still alive +Hey there!! +35 +36 +Dafna! +I'm still alive +Hey there!! +36 +37 +Dafna! +I'm still alive +Hey there!! +37 +38 +Dafna! +I'm still alive +Hey there!! +38 +39 +Dafna! +I'm still alive +Hey there!! +39 +40 +Dafna! +I'm still alive +Hey there!! +40 +41 +Dafna! +I'm still alive +Hey there!! +41 +42 +Dafna! +I'm still alive +Hey there!! +42 +43 +Dafna! +I'm still alive +Hey there!! +43 +44 +Dafna! +I'm still alive +Hey there!! +44 +45 +Dafna! +I'm still alive +Hey there!! +45 +46 +Dafna! +I'm still alive +Hey there!! +46 +47 +Dafna! +I'm still alive +Hey there!! +47 +48 +Dafna! +I'm still alive +Hey there!! +48 +49 +Dafna! +I'm still alive +Hey there!! +49 +50 +Dafna! +I'm still alive +Hey there!! +50 +51 +Dafna! +I'm still alive +Hey there!! +51 +52 +Dafna! +I'm still alive +Hey there!! +52 +53 +Dafna! +I'm still alive +Hey there!! +53 +54 +Dafna! +I'm still alive +Hey there!! +54 +55 +Dafna! +I'm still alive +Hey there!! +55 +56 +Dafna! +I'm still alive +Hey there!! +56 +57 +Dafna! +I'm still alive +Hey there!! +57 +58 +Dafna! +I'm still alive +Hey there!! +58 +59 +Dafna! +I'm still alive +Hey there!! +59 +60 +Dafna! +I'm still alive +Hey there!! +60 +61 +Dafna! +I'm still alive +Hey there!! +61 +62 +Dafna! +I'm still alive +Hey there!! +62 +63 +Dafna! +I'm still alive +Hey there!! +63 +64 +Dafna! +I'm still alive +Hey there!! +64 +65 +Dafna! +I'm still alive +Hey there!! +65 +66 +Dafna! +I'm still alive +Hey there!! +66 +67 +Dafna! +I'm still alive +Hey there!! +67 +68 +Dafna! +I'm still alive +Hey there!! +68 +69 +Dafna! +I'm still alive +Hey there!! +69 +70 +Dafna! +I'm still alive +Hey there!! +70 +71 +Dafna! +I'm still alive +Hey there!! +71 +72 +Dafna! +I'm still alive +Hey there!! +72 +73 +Dafna! +I'm still alive +Hey there!! +73 +74 +Dafna! +I'm still alive +Hey there!! +74 +75 +Dafna! +I'm still alive +Hey there!! +75 +76 +Dafna! +I'm still alive +Hey there!! +76 +77 +Dafna! +I'm still alive +Hey there!! +77 +78 +Dafna! +I'm still alive +Hey there!! +78 +79 +Dafna! +I'm still alive +Hey there!! +79 +80 +Dafna! +I'm still alive +Hey there!! +80 +81 +Dafna! +I'm still alive +Hey there!! +81 +82 +Dafna! +I'm still alive +Hey there!! +82 +83 +Dafna! +I'm still alive +Hey there!! +83 +84 +Dafna! +I'm still alive +Hey there!! +84 +85 +Dafna! +I'm still alive +Hey there!! +85 +86 +Dafna! +I'm still alive +Hey there!! +86 +87 +Dafna! +I'm still alive +Hey there!! +87 +88 +Dafna! +I'm still alive +Hey there!! +88 +89 +Dafna! +I'm still alive +Hey there!! +89 +90 +Dafna! +I'm still alive +Hey there!! +90 +91 +Dafna! +I'm still alive +Hey there!! +91 +92 +Dafna! +I'm still alive +Hey there!! +92 +93 +Dafna! +I'm still alive +Hey there!! +93 +94 +Dafna! +I'm still alive +Hey there!! +94 +95 +Dafna! +I'm still alive +Hey there!! +95 +96 +Dafna! +I'm still alive +Hey there!! +96 +97 +Dafna! +I'm still alive +Hey there!! +97 +98 +Dafna! +I'm still alive +Hey there!! +98 +99 +Dafna! +I'm still alive +Hey there!! +99 +100 +Dafna! +I'm still alive +Hey there!! +100 +101 +Dafna! +I'm still alive +Hey there!! +101 +102 +Dafna! +I'm still alive +Hey there!! +102 +103 +Dafna! +I'm still alive +Hey there!! +103 +104 +Dafna! +I'm still alive +Hey there!! +104 +105 +Dafna! +I'm still alive +Hey there!! +105 +106 +Dafna! +I'm still alive +Hey there!! +106 +107 +Dafna! +I'm still alive +Hey there!! +107 +108 +Dafna! +I'm still alive +Hey there!! +108 +109 +Dafna! +I'm still alive +Hey there!! +109 +110 +Dafna! +I'm still alive +Hey there!! +110 +111 +Dafna! +I'm still alive +Hey there!! +111 +112 +Dafna! +I'm still alive +Hey there!! +112 +113 +Dafna! +I'm still alive +Hey there!! +113 +114 +Dafna! +I'm still alive +Hey there!! +114 +115 +Dafna! +I'm still alive +Hey there!! +115 +116 +Dafna! +I'm still alive +Hey there!! +116 +117 +Dafna! +I'm still alive +Hey there!! +117 +118 +Dafna! +I'm still alive +Hey there!! +118 +119 +Dafna! +I'm still alive +Hey there!! +119 +120 +Dafna! +I'm still alive +Hey there!! +120 +121 +Dafna! +I'm still alive +Hey there!! +121 +122 +Dafna! +I'm still alive +Hey there!! +122 +123 +Dafna! +I'm still alive +Hey there!! +123 +124 +Dafna! +I'm still alive +Hey there!! +124 +125 +Dafna! +I'm still alive +Hey there!! +125 +126 +Dafna! +I'm still alive +Hey there!! +126 +127 +Dafna! +I'm still alive +Hey there!! +127 +128 +Dafna! +I'm still alive +Hey there!! +128 +129 +Dafna! +I'm still alive +Hey there!! +129 +130 +Dafna! +I'm still alive +Hey there!! +130 +131 +Dafna! +I'm still alive +Hey there!! +131 +132 +Dafna! +I'm still alive +Hey there!! +132 +133 +Dafna! +I'm still alive +Hey there!! +133 +134 +Dafna! +I'm still alive +Hey there!! +134 +135 +Dafna! +I'm still alive +Hey there!! +135 +136 +Dafna! +I'm still alive +Hey there!! +136 +137 +Dafna! +I'm still alive +Hey there!! +137 +138 +Dafna! +I'm still alive +Hey there!! +138 +139 +Dafna! +I'm still alive +Hey there!! +139 +140 +Dafna! +I'm still alive +Hey there!! +140 +141 +Dafna! +I'm still alive +Hey there!! +141 +142 +Dafna! +I'm still alive +Hey there!! +142 +143 +Dafna! +I'm still alive +Hey there!! +143 +144 +Dafna! +I'm still alive +Hey there!! +144 +145 +Dafna! +I'm still alive +Hey there!! +145 +146 +Dafna! +I'm still alive +Hey there!! +146 +147 +Dafna! +I'm still alive +Hey there!! +147 +148 +Dafna! +I'm still alive +Hey there!! +148 +149 +Dafna! +I'm still alive +Hey there!! +149 +150 +Dafna! +I'm still alive +Hey there!! +150 +151 +Dafna! +I'm still alive +Hey there!! +151 +152 +Dafna! +I'm still alive +Hey there!! +152 +153 +Dafna! +I'm still alive +Hey there!! +153 +154 +Dafna! +I'm still alive +Hey there!! +154 +155 +Dafna! +I'm still alive +Hey there!! +155 +156 +Dafna! +I'm still alive +Hey there!! +156 +157 +Dafna! +I'm still alive +Hey there!! +157 +158 +Dafna! +I'm still alive +Hey there!! +158 +159 +Dafna! +I'm still alive +Hey there!! +159 +160 +Dafna! +I'm still alive +Hey there!! +160 +161 +Dafna! +I'm still alive +Hey there!! +161 +162 +Dafna! +I'm still alive +Hey there!! +162 +163 +Dafna! +I'm still alive +Hey there!! +163 +164 +Dafna! +I'm still alive +Hey there!! +164 +165 +Dafna! +I'm still alive +Hey there!! +165 +166 +Dafna! +I'm still alive +Hey there!! +166 +167 +Dafna! +I'm still alive +Hey there!! +167 +168 +Dafna! +I'm still alive +Hey there!! +168 +169 +Dafna! +I'm still alive +Hey there!! +169 +170 +Dafna! +I'm still alive +Hey there!! +170 +171 +Dafna! +I'm still alive +Hey there!! +171 +172 +Dafna! +I'm still alive +Hey there!! +172 +173 +Dafna! +I'm still alive +Hey there!! +173 +174 +Dafna! +I'm still alive +Hey there!! +174 +175 +Dafna! +I'm still alive +Hey there!! +175 +176 +Dafna! +I'm still alive +Hey there!! +176 +177 +Dafna! +I'm still alive +Hey there!! +177 +178 +Dafna! +I'm still alive +Hey there!! +178 +179 +Dafna! +I'm still alive +Hey there!! +179 +180 +Dafna! +I'm still alive +Hey there!! +180 +181 +Dafna! +I'm still alive +Hey there!! +181 +182 +Dafna! +I'm still alive +Hey there!! +182 +183 +Dafna! +I'm still alive +Hey there!! +183 +184 +Dafna! +I'm still alive +Hey there!! +184 +185 +Dafna! +I'm still alive +Hey there!! +185 +186 +Dafna! +I'm still alive +Hey there!! +186 +187 +Dafna! +I'm still alive +Hey there!! +187 +188 +Dafna! +I'm still alive +Hey there!! +188 +189 +Dafna! +I'm still alive +Hey there!! +189 +190 +Dafna! +I'm still alive +Hey there!! +190 +191 +Dafna! +I'm still alive +Hey there!! +191 +192 +Dafna! +I'm still alive +Hey there!! +192 +193 +Dafna! +I'm still alive +Hey there!! +193 +194 +Dafna! +I'm still alive +Hey there!! +194 +195 +Dafna! +I'm still alive +Hey there!! +195 +196 +Dafna! +I'm still alive +Hey there!! +196 +197 +Dafna! +I'm still alive +Hey there!! +197 +198 +Dafna! +I'm still alive +Hey there!! +198 +199 +Dafna! +I'm still alive +Hey there!! +199 +Dafna +EXPECT + +my $result = GET_BODY "/php/cfunctions.php"; + +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/classes.t b/debian/perl-framework/t/php/classes.t new file mode 100644 index 0000000..2e2d2c5 --- /dev/null +++ b/debian/perl-framework/t/php/classes.t @@ -0,0 +1,54 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +User information +---------------- + +First name: Zeev +Family name: Suraski +Address: Ben Gourion 3, Kiryat Bialik, Israel +Phone: +972-4-8713139 + + +User information +---------------- + +First name: Andi +Family name: Gutmans +Address: Haifa, Israel +Phone: +972-4-8231621 + + +User information +---------------- + +First name: Andi +Family name: Gutmans +Address: Haifa, Israel +Phone: +972-4-8231621 + + +User information +---------------- + +First name: Andi +Family name: Gutmans +Address: New address... +Phone: +972-4-8231621 + + +EXPECT + +my $result = GET_BODY "/php/classes.php"; + +## get rid of whitespace so that does not cause failure in the comparison. +$expected =~ s/\s//g; +$result =~ s/\s//g; + +ok $result eq $expected diff --git a/debian/perl-framework/t/php/construct.t b/debian/perl-framework/t/php/construct.t new file mode 100644 index 0000000..b047315 --- /dev/null +++ b/debian/perl-framework/t/php/construct.t @@ -0,0 +1,66 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 2, need_php4; + +## testing PHP OO bug (#7515) +## php src: +## <?php +## class obj { +## function method() {} +## } +## +## function test($o_copy) { +## $o_copy->root->set_in_copied_o=TRUE; +## var_dump($o_copy);?><BR><?php } +## +## $o->root=new obj(); +## +## ob_start(); +## var_dump($o); +## $x=ob_get_contents(); +## ob_end_clean(); +## +## $o->root->method(); +## +## ob_start(); +## var_dump($o); +## $y=ob_get_contents(); +## ob_end_clean(); +## +## // $o->root->method() makes ob_get_contents() have a '&' in front of object +## // so this does not work. +## // echo ($x==$y) ? 'success':'failure'; +## +## echo "x = $x"; +## echo "y = $y"; +## ?> +## +## output should be: +## x = object(stdClass)(1) { +## ["root"]=> +## object(obj)(0) { +## } +## } +## y = object(stdClass)(1) { +## ["root"]=> +## &object(obj)(0) { +## } +## } + +my $result = GET_BODY "/php/construct.php"; + +## get rid of newlines to make compairon easier. +$result =~ s/\n//g; + +my ($x, $y); +if ($result =~ /x = (.*)y = (.*)/) { + $x = $1; + $y = $2; +} + +ok $x eq "object(stdClass)(1) { [\"root\"]=> object(obj)(0) { }}"; +ok $y eq "object(stdClass)(1) { [\"root\"]=> &object(obj)(0) { }}"; diff --git a/debian/perl-framework/t/php/dirname.t b/debian/perl-framework/t/php/dirname.t new file mode 100644 index 0000000..f1f1a9f --- /dev/null +++ b/debian/perl-framework/t/php/dirname.t @@ -0,0 +1,43 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## dirname.php source: +## <?php +## +## function check_dirname($path) +## { +## print "dirname($path) == " . dirname($path) . "\n"; +## } +## +## check_dirname("/foo/"); +## check_dirname("/foo"); +## check_dirname("/foo/bar"); +## check_dirname("d:\\foo\\bar.inc"); +## check_dirname("/"); +## check_dirname(".../foo"); +## check_dirname("./foo"); +## check_dirname("foobar///"); +## check_dirname("c:\\foo"); +## ?> +## +## result should be: +## dirname(/foo/) == / +## dirname(/foo) == / +## dirname(/foo/bar) == /foo +## dirname(d:\foo\bar.inc) == . +## dirname(/) == / +## dirname(.../foo) == ... +## dirname(./foo) == . +## dirname(foobar///) == . +## dirname(c:\foo) == . + + +my $expected = "dirname(/foo/) == /\ndirname(/foo) == /\ndirname(/foo/bar) == /foo\ndirname(d\:\\foo\\bar.inc) == .\ndirname(/) == /\ndirname(.../foo) == ...\ndirname(./foo) == .\ndirname(foobar///) == .\ndirname(c\:\\foo) == .\n"; + +my $result = GET_BODY "/php/dirname.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/divide.t b/debian/perl-framework/t/php/divide.t new file mode 100644 index 0000000..d547cc3 --- /dev/null +++ b/debian/perl-framework/t/php/divide.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## divide.php source: +## <?php $a=27; $b=3; $c=3; $d=$a/$b/$c; echo $d?> +## +## result should be '3' (27/3/3=3) + +my $result = GET_BODY "/php/divide.php"; +ok $result eq '3'; diff --git a/debian/perl-framework/t/php/do-while.t b/debian/perl-framework/t/php/do-while.t new file mode 100644 index 0000000..6fcb16c --- /dev/null +++ b/debian/perl-framework/t/php/do-while.t @@ -0,0 +1,12 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = "321"; + +my $result = GET_BODY "/php/do-while.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/else.t b/debian/perl-framework/t/php/else.t new file mode 100644 index 0000000..3ae2ba0 --- /dev/null +++ b/debian/perl-framework/t/php/else.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/else.php"; +ok $result eq "good\n"; diff --git a/debian/perl-framework/t/php/elseif.t b/debian/perl-framework/t/php/elseif.t new file mode 100644 index 0000000..e125884 --- /dev/null +++ b/debian/perl-framework/t/php/elseif.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/elseif.php"; +ok $result eq "good\n"; diff --git a/debian/perl-framework/t/php/eval.t b/debian/perl-framework/t/php/eval.t new file mode 100644 index 0000000..62fe096 --- /dev/null +++ b/debian/perl-framework/t/php/eval.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing eval function + +plan tests => 1, need_php; + +my $expected = "Hello"; + +my $result = GET_BODY "/php/eval.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/eval2.t b/debian/perl-framework/t/php/eval2.t new file mode 100644 index 0000000..09a96f6 --- /dev/null +++ b/debian/perl-framework/t/php/eval2.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing eval function inside user function + +plan tests => 1, need_php4; + +my $expected = "Hello"; + +my $result = GET_BODY "/php/eval2.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/eval3.t b/debian/perl-framework/t/php/eval3.t new file mode 100644 index 0000000..5edab01 --- /dev/null +++ b/debian/perl-framework/t/php/eval3.t @@ -0,0 +1,35 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing eval function + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +hey +0 +hey +1 +hey +2 +hey +3 +hey +4 +hey +5 +hey +6 +hey +7 +hey +8 +hey +9 +EXPECT + +my $result = GET_BODY "/php/eval3.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/eval4.t b/debian/perl-framework/t/php/eval4.t new file mode 100644 index 0000000..9c676e6 --- /dev/null +++ b/debian/perl-framework/t/php/eval4.t @@ -0,0 +1,35 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing eval function + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +hey, this is a regular echo'd eval() +hey, this is a function inside an eval()! +EXPECT + +my $result = GET_BODY "/php/eval4.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/func1.t b/debian/perl-framework/t/php/func1.t new file mode 100644 index 0000000..a57611a --- /dev/null +++ b/debian/perl-framework/t/php/func1.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## func1.php source: +## <?php echo strlen("abcdef")?> +## +## result should be '6' + +my $result = GET_BODY "/php/func1.php"; +ok $result eq '6'; diff --git a/debian/perl-framework/t/php/func2.t b/debian/perl-framework/t/php/func2.t new file mode 100644 index 0000000..2dedb59 --- /dev/null +++ b/debian/perl-framework/t/php/func2.t @@ -0,0 +1,16 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php4; + +my $expected = <<EXPECT; +hey=0, 0 +hey=1, -1 +hey=2, -2 +EXPECT + +my $result = GET_BODY "/php/func2.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/func3.t b/debian/perl-framework/t/php/func3.t new file mode 100644 index 0000000..e5e347b --- /dev/null +++ b/debian/perl-framework/t/php/func3.t @@ -0,0 +1,204 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php4; + +my $expected = <<EXPECT; +hey +blah +hey +blah +Counting from 7 to 14 +7 +8 +9 +10 +11 +12 +13 +14 +hey +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +factorial(5) = 120 +factorial(6) = 720 +factorial(7) = 5040 +factorial(8) = 40320 +factorial(9) = 362880 +factorial(10) = 3628800 +and now, from a function... +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +(it should break at 5...) +factorial(0) = 1 +factorial(1) = 1 +factorial(2) = 2 +factorial(3) = 6 +factorial(4) = 24 +------ +720 +840 +3 +4 +5 +EXPECT + +my $result = GET_BODY "/php/func3.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/func4.t b/debian/perl-framework/t/php/func4.t new file mode 100644 index 0000000..83fe94c --- /dev/null +++ b/debian/perl-framework/t/php/func4.t @@ -0,0 +1,42 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php4; + +my $expected = <<EXPECT; +Before function declaration... +After function declaration... +Calling function for the first time... +---- +In function, printing the string "This works!" 10 times +0) This works! +1) This works! +2) This works! +3) This works! +4) This works! +5) This works! +6) This works! +7) This works! +8) This works! +9) This works! +Done with function... +----- +Returned from function call... +Calling the function for the second time... +---- +In function, printing the string "This like, really works and stuff..." 3 times +0) This like, really works and stuff... +1) This like, really works and stuff... +2) This like, really works and stuff... +Done with function... +----- +Returned from function call... +This is some other function, to ensure more than just one function works fine... + +EXPECT + +my $result = GET_BODY "/php/func4.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/func5.t b/debian/perl-framework/t/php/func5.t new file mode 100644 index 0000000..9208659 --- /dev/null +++ b/debian/perl-framework/t/php/func5.t @@ -0,0 +1,33 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, need_php; + +my $path = Apache::Test::vars()->{t_logs}; +my $file = "$path/func5.php.ran"; +unlink $file if -e $file; + +my $expected = <<EXPECT; +foo() will be called on shutdown... +EXPECT + +my $result = GET_BODY "/php/func5.php?$file"; +ok t_cmp($result, + $expected, + "GET request for /php/func5.php?$file" + ); + +sleep 1; +ok t_cmp(-e $file, + 1, + "$file exists" + ); + +# Clean up +unlink $file if -e $file; + + diff --git a/debian/perl-framework/t/php/func6.t b/debian/perl-framework/t/php/func6.t new file mode 100644 index 0000000..6422a97 --- /dev/null +++ b/debian/perl-framework/t/php/func6.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## nested functions test. + +plan tests => 1, need_php; + +my $expected = "4 Hello 4"; + +my $result = GET_BODY "/php/func6.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/getenv.t b/debian/perl-framework/t/php/getenv.t new file mode 100644 index 0000000..9d54878 --- /dev/null +++ b/debian/perl-framework/t/php/getenv.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, need_php; + +# Regression test for http://bugs.php.net/bug.php?id=19840 + +ok t_cmp((GET_BODY "/php/getenv.php"), + "GET", + "getenv(REQUEST_METHOD)" +); diff --git a/debian/perl-framework/t/php/getlastmod.t b/debian/perl-framework/t/php/getlastmod.t new file mode 100644 index 0000000..4e1b7b1 --- /dev/null +++ b/debian/perl-framework/t/php/getlastmod.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest qw(GET_BODY); +use Apache::TestUtil; +use File::Spec::Functions qw(catfile); + +use POSIX qw(strftime); + +plan tests => 1, need_php; + +my $vars = Apache::Test::vars(); +my $fname = catfile $vars->{documentroot}, "php", "getlastmod.php"; +my $mtime = (stat($fname))[9] || die "could not find file"; +my $month = strftime "%B", gmtime($mtime); + +ok t_cmp( + GET_BODY("/php/getlastmod.php"), + $month, + "getlastmod()" +); diff --git a/debian/perl-framework/t/php/globals.t b/debian/perl-framework/t/php/globals.t new file mode 100644 index 0000000..ce4e631 --- /dev/null +++ b/debian/perl-framework/t/php/globals.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/globals.php"; +ok $result eq "1 5 2 2 10 5 2 5 3 2 10 5 3 5 4 2 \n"; diff --git a/debian/perl-framework/t/php/hello.t b/debian/perl-framework/t/php/hello.t new file mode 100644 index 0000000..028bd3f --- /dev/null +++ b/debian/perl-framework/t/php/hello.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## hello.php source: +## <?php echo "Hello World"?> +## +## result should be 'Hello World' + +my $result = GET_BODY "/php/hello.php"; +ok $result eq 'Hello World'; diff --git a/debian/perl-framework/t/php/if.t b/debian/perl-framework/t/php/if.t new file mode 100644 index 0000000..319549d --- /dev/null +++ b/debian/perl-framework/t/php/if.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/if.php"; +ok $result eq 'Yes'; diff --git a/debian/perl-framework/t/php/if2.t b/debian/perl-framework/t/php/if2.t new file mode 100644 index 0000000..113fb35 --- /dev/null +++ b/debian/perl-framework/t/php/if2.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## Testing user-defined function falling out of an If into another + +plan tests => 1, need_php4; + +my $expected = "1\n"; + +my $result = GET_BODY "/php/if2.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/ifmodsince.t b/debian/perl-framework/t/php/ifmodsince.t new file mode 100644 index 0000000..47859e6 --- /dev/null +++ b/debian/perl-framework/t/php/ifmodsince.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest qw(GET_RC); + +use POSIX qw(strftime); + +plan tests => 1, need_php; + +# Test for bug where Apache serves a 304 if the PHP file (on disk) has +# not been modified since the date given in an If-Modified-Since +# header; http://bugs.php.net/bug.php?id=17098 + +ok t_cmp( + GET_RC("/php/hello.php", + "If-Modified-Since" => strftime("%a, %d %b %Y %T GMT", gmtime)), + 200, + "not 304 if the php file has not been modified since If-Modified-Since" +); + diff --git a/debian/perl-framework/t/php/include.t b/debian/perl-framework/t/php/include.t new file mode 100644 index 0000000..74cbe36 --- /dev/null +++ b/debian/perl-framework/t/php/include.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing include + +plan tests => 1, need_php; + +my $expected = "Hello"; + +my $result = GET_BODY "/php/include.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/include2.t b/debian/perl-framework/t/php/include2.t new file mode 100644 index 0000000..6608630 --- /dev/null +++ b/debian/perl-framework/t/php/include2.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing user function in an nclude + +plan tests => 1, need_php4; + +my $expected = "Hello"; + +my $result = GET_BODY "/php/include2.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/inheritance.t b/debian/perl-framework/t/php/inheritance.t new file mode 100644 index 0000000..a5bd7d3 --- /dev/null +++ b/debian/perl-framework/t/php/inheritance.t @@ -0,0 +1,23 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +This is class foo +a = 2 +b = 5 +10 +----- +This is class bar +a = 4 +b = 3 +c = 12 +12 +EXPECT + +my $result = GET_BODY "/php/inheritance.php"; +ok $result eq $expected diff --git a/debian/perl-framework/t/php/lookup.t b/debian/perl-framework/t/php/lookup.t new file mode 100644 index 0000000..66ae95d --- /dev/null +++ b/debian/perl-framework/t/php/lookup.t @@ -0,0 +1,29 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 4, need_php; + +my $expect = "status=200:method=GET:uri=/php/target.php"; + +my $r = GET_BODY "/php/lookup.php"; + +chomp $r; + +ok t_cmp($r, $expect, "apache_lookup_uri results OK"); + +# regression test for http://bugs.php.net/bug.php?id=31645 +$r = GET("/php/lookup2.php"); + +ok t_cmp($r->header("X-Before"), "foobar", "header set before apache_lookup_uri"); +ok t_cmp($r->header("X-After"), "foobar", "header set after apache_lookup_uri"); + +my $c = $r->content; + +chomp $c; + +ok t_cmp($c, $expect, "second apache_lookup_uri results"); + diff --git a/debian/perl-framework/t/php/multiply.t b/debian/perl-framework/t/php/multiply.t new file mode 100644 index 0000000..35ec85a --- /dev/null +++ b/debian/perl-framework/t/php/multiply.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## multiply.php source: +## <?php $a=2; $b=4; $c=8; $d=$a*$b*$c; echo $d?> +## +## result should be '64' (2*4*8=64) + +my $result = GET_BODY "/php/multiply.php"; +ok $result eq '64'; diff --git a/debian/perl-framework/t/php/nestif.t b/debian/perl-framework/t/php/nestif.t new file mode 100644 index 0000000..0ddac24 --- /dev/null +++ b/debian/perl-framework/t/php/nestif.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/nestif.php"; +ok $result eq "good\n"; diff --git a/debian/perl-framework/t/php/ops.t b/debian/perl-framework/t/php/ops.t new file mode 100644 index 0000000..dad7542 --- /dev/null +++ b/debian/perl-framework/t/php/ops.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## ops.php source: +## <?php $a=8; $b=4; $c=8; echo $a|$b&$c?> +## +## result should be '8' + +my $result = GET_BODY "/php/ops.php"; +ok $result eq '8'; diff --git a/debian/perl-framework/t/php/param.t b/debian/perl-framework/t/php/param.t new file mode 100644 index 0000000..d7bee96 --- /dev/null +++ b/debian/perl-framework/t/php/param.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php4; + +my $result = GET_BODY "/php/param.php"; +ok $result eq "3\n"; diff --git a/debian/perl-framework/t/php/param2.t b/debian/perl-framework/t/php/param2.t new file mode 100644 index 0000000..4235a97 --- /dev/null +++ b/debian/perl-framework/t/php/param2.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php4; + +my $result = GET_BODY "/php/param2.php"; +ok $result eq "2\n"; diff --git a/debian/perl-framework/t/php/pathinfo.t b/debian/perl-framework/t/php/pathinfo.t new file mode 100644 index 0000000..76bd479 --- /dev/null +++ b/debian/perl-framework/t/php/pathinfo.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 5, sub { need_php() && need_min_apache_version('2.0.0'); }; + +my $r; + +$r = GET("/apache/acceptpathinfo/on/info.php/fish/food"); +ok t_cmp($r->code, 200, "PATH_INFO accepted by default"); +ok t_cmp($r->content, "_/fish/food_", "PATH_INFO parsed OK"); + +$r = GET("/apache/acceptpathinfo/off/info.php/fish/food"); +ok t_cmp($r->code, 404, "PATH_INFO rejected if disabled"); + +$r = GET("/apache/acceptpathinfo/on/info.php/fish/food"); +ok t_cmp($r->code, 200, "PATH_INFO accepted if enabled"); +ok t_cmp($r->content, "_/fish/food_", "PATH_INFO parsed OK"); + diff --git a/debian/perl-framework/t/php/recurse.t b/debian/perl-framework/t/php/recurse.t new file mode 100644 index 0000000..1dba5b3 --- /dev/null +++ b/debian/perl-framework/t/php/recurse.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/recurse.php"; +ok $result eq "1 2 3 4 5 6 7 8 9 \n"; diff --git a/debian/perl-framework/t/php/regression.t b/debian/perl-framework/t/php/regression.t new file mode 100644 index 0000000..35e1f3e --- /dev/null +++ b/debian/perl-framework/t/php/regression.t @@ -0,0 +1,244 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +PHP Regression Test + +<html> +<head> + +*** Testing assignments and variable aliasing: ***<br> +This should read "blah": blah<br> +This should read "this is nifty": this is nifty<br> +*************************************************<br> + +*** Testing integer operators ***<br> +Correct result - 8: 8<br> +Correct result - 8: 8<br> +Correct result - 2: 2<br> +Correct result - -2: -2<br> +Correct result - 15: 15<br> +Correct result - 15: 15<br> +Correct result - 2: 2<br> +Correct result - 3: 3<br> +*********************************<br> + +*** Testing real operators ***<br> +Correct result - 8: 8<br> +Correct result - 8: 8<br> +Correct result - 2: 2<br> +Correct result - -2: -2<br> +Correct result - 15: 15<br> +Correct result - 15: 15<br> +Correct result - 2: 2<br> +Correct result - 3: 3<br> +*********************************<br> + +*** Testing if/elseif/else control ***<br> + +This works<br> +this_still_works<br> +should_print<br> + + +*** Seriously nested if's test ***<br> +** spelling correction by kluzz ** +Only two lines of text should follow:<br> +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0<br> +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4<br> +3 loop iterations should follow:<br> +2 4<br> +3 4<br> +4 4<br> +**********************************<br> + +*** C-style else-if's ***<br> +This should be displayed<br> +*************************<br> + +*** WHILE tests ***<br> +0 is smaller than 20<br> +1 is smaller than 20<br> +2 is smaller than 20<br> +3 is smaller than 20<br> +4 is smaller than 20<br> +5 is smaller than 20<br> +6 is smaller than 20<br> +7 is smaller than 20<br> +8 is smaller than 20<br> +9 is smaller than 20<br> +10 is smaller than 20<br> +11 is smaller than 20<br> +12 is smaller than 20<br> +13 is smaller than 20<br> +14 is smaller than 20<br> +15 is smaller than 20<br> +16 is smaller than 20<br> +17 is smaller than 20<br> +18 is smaller than 20<br> +19 is smaller than 20<br> +20 equals 20<br> +21 is greater than 20<br> +22 is greater than 20<br> +23 is greater than 20<br> +24 is greater than 20<br> +25 is greater than 20<br> +26 is greater than 20<br> +27 is greater than 20<br> +28 is greater than 20<br> +29 is greater than 20<br> +30 is greater than 20<br> +31 is greater than 20<br> +32 is greater than 20<br> +33 is greater than 20<br> +34 is greater than 20<br> +35 is greater than 20<br> +36 is greater than 20<br> +37 is greater than 20<br> +38 is greater than 20<br> +39 is greater than 20<br> +*******************<br> + + +*** Nested WHILEs ***<br> +Each array variable should be equal to the sum of its indices:<br> +\${test00}[0] = 0<br> +\${test00}[1] = 1<br> +\${test00}[2] = 2<br> +\${test01}[0] = 1<br> +\${test01}[1] = 2<br> +\${test01}[2] = 3<br> +\${test02}[0] = 2<br> +\${test02}[1] = 3<br> +\${test02}[2] = 4<br> +\${test10}[0] = 1<br> +\${test10}[1] = 2<br> +\${test10}[2] = 3<br> +\${test11}[0] = 2<br> +\${test11}[1] = 3<br> +\${test11}[2] = 4<br> +\${test12}[0] = 3<br> +\${test12}[1] = 4<br> +\${test12}[2] = 5<br> +\${test20}[0] = 2<br> +\${test20}[1] = 3<br> +\${test20}[2] = 4<br> +\${test21}[0] = 3<br> +\${test21}[1] = 4<br> +\${test21}[2] = 5<br> +\${test22}[0] = 4<br> +\${test22}[1] = 5<br> +\${test22}[2] = 6<br> +*********************<br> + +*** hash test... ***<br> +commented out... +**************************<br> + +*** Hash resizing test ***<br> +ba<br> +baa<br> +baaa<br> +baaaa<br> +baaaaa<br> +baaaaaa<br> +baaaaaaa<br> +baaaaaaaa<br> +baaaaaaaaa<br> +baaaaaaaaaa<br> +ba<br> +10<br> +baa<br> +9<br> +baaa<br> +8<br> +baaaa<br> +7<br> +baaaaa<br> +6<br> +baaaaaa<br> +5<br> +baaaaaaa<br> +4<br> +baaaaaaaa<br> +3<br> +baaaaaaaaa<br> +2<br> +baaaaaaaaaa<br> +1<br> +**************************<br> + + +*** break/continue test ***<br> +\$i should go from 0 to 2<br> +\$j should go from 3 to 4, and \$q should go from 3 to 4<br> + \$j=3<br> + \$q=3<br> + \$q=4<br> + \$j=4<br> + \$q=3<br> + \$q=4<br> +\$j should go from 0 to 2<br> + \$j=0<br> + \$j=1<br> + \$j=2<br> +\$k should go from 0 to 2<br> + \$k=0<br> + \$k=1<br> + \$k=2<br> +\$i=0<br> +\$j should go from 3 to 4, and \$q should go from 3 to 4<br> + \$j=3<br> + \$q=3<br> + \$q=4<br> + \$j=4<br> + \$q=3<br> + \$q=4<br> +\$j should go from 0 to 2<br> + \$j=0<br> + \$j=1<br> + \$j=2<br> +\$k should go from 0 to 2<br> + \$k=0<br> + \$k=1<br> + \$k=2<br> +\$i=1<br> +\$j should go from 3 to 4, and \$q should go from 3 to 4<br> + \$j=3<br> + \$q=3<br> + \$q=4<br> + \$j=4<br> + \$q=3<br> + \$q=4<br> +\$j should go from 0 to 2<br> + \$j=0<br> + \$j=1<br> + \$j=2<br> +\$k should go from 0 to 2<br> + \$k=0<br> + \$k=1<br> + \$k=2<br> +\$i=2<br> +***********************<br> + +*** Nested file include test ***<br> +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +********************************<br> + +Tests completed.<br> +Limor Ullmann is now Limor Baruch :I + +EXPECT + +my $result = GET_BODY "/php/regression.php"; + +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/regression2.t b/debian/perl-framework/t/php/regression2.t new file mode 100644 index 0000000..b7d3ce3 --- /dev/null +++ b/debian/perl-framework/t/php/regression2.t @@ -0,0 +1,11264 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +<html> +<head> +*** Testing assignments and variable aliasing: *** +This should read "blah": blah +This should read "this is nifty": this is nifty +************************************************* + +*** Testing integer operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing real operators *** +Correct result - 8: 8 +Correct result - 8: 8 +Correct result - 2: 2 +Correct result - -2: -2 +Correct result - 15: 15 +Correct result - 15: 15 +Correct result - 2: 2 +Correct result - 3: 3 +********************************* + +*** Testing if/elseif/else control *** + +This works +this_still_works +should_print + + +*** Seriously nested if's test *** +** spelling correction by kluzz ** +Only two lines of text should follow: +this should be displayed. should be: \$i=1, \$j=0. is: \$i=1, \$j=0 +this is supposed to be displayed. should be: \$i=2, \$j=4. is: \$i=2, \$j=4 +3 loop iterations should follow: +2 4 +3 4 +4 4 +********************************** + +*** C-style else-if's *** +This should be displayed +************************* + +*** WHILE tests *** +0 is smaller than 20 +1 is smaller than 20 +2 is smaller than 20 +3 is smaller than 20 +4 is smaller than 20 +5 is smaller than 20 +6 is smaller than 20 +7 is smaller than 20 +8 is smaller than 20 +9 is smaller than 20 +10 is smaller than 20 +11 is smaller than 20 +12 is smaller than 20 +13 is smaller than 20 +14 is smaller than 20 +15 is smaller than 20 +16 is smaller than 20 +17 is smaller than 20 +18 is smaller than 20 +19 is smaller than 20 +20 equals 20 +21 is greater than 20 +22 is greater than 20 +23 is greater than 20 +24 is greater than 20 +25 is greater than 20 +26 is greater than 20 +27 is greater than 20 +28 is greater than 20 +29 is greater than 20 +30 is greater than 20 +31 is greater than 20 +32 is greater than 20 +33 is greater than 20 +34 is greater than 20 +35 is greater than 20 +36 is greater than 20 +37 is greater than 20 +38 is greater than 20 +39 is greater than 20 +******************* + + +*** Nested WHILEs *** +Each array variable should be equal to the sum of its indices: +\${test00}[0] = 0 +\${test00}[1] = 1 +\${test00}[2] = 2 +\${test01}[0] = 1 +\${test01}[1] = 2 +\${test01}[2] = 3 +\${test02}[0] = 2 +\${test02}[1] = 3 +\${test02}[2] = 4 +\${test10}[0] = 1 +\${test10}[1] = 2 +\${test10}[2] = 3 +\${test11}[0] = 2 +\${test11}[1] = 3 +\${test11}[2] = 4 +\${test12}[0] = 3 +\${test12}[1] = 4 +\${test12}[2] = 5 +\${test20}[0] = 2 +\${test20}[1] = 3 +\${test20}[2] = 4 +\${test21}[0] = 3 +\${test21}[1] = 4 +\${test21}[2] = 5 +\${test22}[0] = 4 +\${test22}[1] = 5 +\${test22}[2] = 6 +********************* + +*** hash test... *** +commented out... +************************** + +*** Hash resizing test *** +ba +baa +baaa +baaaa +baaaaa +baaaaaa +baaaaaaa +baaaaaaaa +baaaaaaaaa +baaaaaaaaaa +ba +10 +baa +9 +baaa +8 +baaaa +7 +baaaaa +6 +baaaaaa +5 +baaaaaaa +4 +baaaaaaaa +3 +baaaaaaaaa +2 +baaaaaaaaaa +1 +************************** + + +*** break/continue test *** +\$i should go from 0 to 2 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=0 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=1 +\$j should go from 3 to 4, and \$q should go from 3 to 4 + \$j=3 + \$q=3 + \$q=4 + \$j=4 + \$q=3 + \$q=4 +\$j should go from 0 to 2 + \$j=0 + \$j=1 + \$j=2 +\$k should go from 0 to 2 + \$k=0 + \$k=1 + \$k=2 +\$i=2 +*********************** + +*** Nested file include test *** +<html> +This is Finish.phtml. This file is supposed to be included +from regression_test.phtml. This is normal HTML. +and this is PHP code, 2+2=4 +</html> +******************************** + +Tests completed. +EXPECT + +my $result = GET_BODY "/php/regression2.php"; + +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/regression3.t b/debian/perl-framework/t/php/regression3.t new file mode 100644 index 0000000..bbd5111 --- /dev/null +++ b/debian/perl-framework/t/php/regression3.t @@ -0,0 +1,526 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php4; + +my $expected = <<EXPECT; + 0 a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 4 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 3 a 3 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 4 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 2 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 4 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 3 a 3 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 4 a 4 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 5 a 5 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 6 a 6 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 7 a 7 a 8 a 9 + b 10 + b 9 a 9 + b 10 + b 8 a 8 a 9 + b 10 + b 9 a 9 + b 10 +EXPECT + +my $result = GET_BODY "/php/regression3.php"; + +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/stack.t b/debian/perl-framework/t/php/stack.t new file mode 100644 index 0000000..92bec94 --- /dev/null +++ b/debian/perl-framework/t/php/stack.t @@ -0,0 +1,14 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +## testing stack after early function return + +plan tests => 1, need_php4; + +my $expected = "HelloHello"; + +my $result = GET_BODY "/php/stack.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/status.t b/debian/perl-framework/t/php/status.t new file mode 100644 index 0000000..cc783ae --- /dev/null +++ b/debian/perl-framework/t/php/status.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my @codes = (404, 599); + +plan tests => @codes + 0, need_php; + +foreach my $code (@codes) { + ok t_cmp(GET_RC("/php/status.php?code=$code"), $code, + "regression test for http://bugs.php.net/bug.php?id=31519"); +} diff --git a/debian/perl-framework/t/php/strings.t b/debian/perl-framework/t/php/strings.t new file mode 100644 index 0000000..6effcc9 --- /dev/null +++ b/debian/perl-framework/t/php/strings.t @@ -0,0 +1,12 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = "\" \\'\\n\\'a\\\\b\\"; + +my $result = GET_BODY "/php/strings.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/strings2.t b/debian/perl-framework/t/php/strings2.t new file mode 100644 index 0000000..c6fd801 --- /dev/null +++ b/debian/perl-framework/t/php/strings2.t @@ -0,0 +1,30 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +Testing strtok: passed +Testing strstr: passed +Testing strrchr: passed +Testing strtoupper: passed +Testing strtolower: passed +Testing substr: passed +Testing rawurlencode: passed +Testing rawurldecode: passed +Testing urlencode: passed +Testing urldecode: passed +Testing quotemeta: passed +Testing ufirst: passed +Testing strtr: passed +Testing addslashes: passed +Testing stripslashes: passed +Testing uniqid: passed +EXPECT + +my $result = GET_BODY "/php/strings2.php"; + +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/strings3.t b/debian/perl-framework/t/php/strings3.t new file mode 100644 index 0000000..e53519f --- /dev/null +++ b/debian/perl-framework/t/php/strings3.t @@ -0,0 +1,55 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $result = GET_BODY "/php/strings3.php"; +my @res = split /\n/, $result; +my $count = @res; + +plan tests => $count + 1, need_php; + +my $expected = <<EXPECT; +printf test 1:simple string +printf test 2:42 +printf test 3:3.333333 +printf test 4:3.3333333333 +printf test 5:2.50 +printf test 6:2.50000000 +printf test 7:0000002.50 +printf test 8:< foo> +printf test 9:<bar > +printf test 10: 123456789012345 +printf test 10:<høyesterettsjustitiarius> +printf test 11: 123456789012345678901234567890 +printf test 11:< høyesterettsjustitiarius> +printf test 12:-12.34 +printf test 13: -12 +printf test 14:@ +printf test 15:10101010 +printf test 16:aa +printf test 17:AA +printf test 18: 10101010 +printf test 19: aa +printf test 20: AA +printf test 21:0000000010101010 +printf test 22:00000000000000aa +printf test 23:00000000000000AA +printf test 24:abcde +printf test 25:gazonk +printf test 26:2 1 +printf test 27:3 1 2 +printf test 28:02 1 +printf test 29:2 1 +EXPECT + +my @exp = split /\n/, $expected; +my $count2 = @exp; + +ok $count eq $count2; + +foreach (my $i = 0 ; $i < $count ; $i++) { + ok t_cmp("[".$res[$i]."]", "[".$exp[$i]."]", "test $i"); +} diff --git a/debian/perl-framework/t/php/strings4.t b/debian/perl-framework/t/php/strings4.t new file mode 100644 index 0000000..f39b98d --- /dev/null +++ b/debian/perl-framework/t/php/strings4.t @@ -0,0 +1,16 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +<>"&åÄ +<>"&åÄ +EXPECT + +my $result = GET_BODY "/php/strings4.php"; + +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/subtract.t b/debian/perl-framework/t/php/subtract.t new file mode 100644 index 0000000..8a579ee --- /dev/null +++ b/debian/perl-framework/t/php/subtract.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +## subtract.php source: +## <?php $a=27; $b=7; $c=10; $d=$a-$b-$c; echo $d?> +## +## result should be '10' (27-7-10=10) + +my $result = GET_BODY "/php/subtract.php"; +ok $result eq '10'; diff --git a/debian/perl-framework/t/php/switch.t b/debian/perl-framework/t/php/switch.t new file mode 100644 index 0000000..5a922b2 --- /dev/null +++ b/debian/perl-framework/t/php/switch.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/switch.php"; +ok $result eq "good\n"; diff --git a/debian/perl-framework/t/php/switch2.t b/debian/perl-framework/t/php/switch2.t new file mode 100644 index 0000000..b09fc45 --- /dev/null +++ b/debian/perl-framework/t/php/switch2.t @@ -0,0 +1,43 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +In branch 1 +Inner default... +blah=100 +EXPECT + +my $result = GET_BODY "/php/switch2.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/switch3.t b/debian/perl-framework/t/php/switch3.t new file mode 100644 index 0000000..767b0d9 --- /dev/null +++ b/debian/perl-framework/t/php/switch3.t @@ -0,0 +1,22 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +i=0 +In branch 0 +i=1 +In branch 1 +i=2 +In branch 2 +i=3 +In branch 3 +hi +EXPECT + +my $result = GET_BODY "/php/switch3.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/switch4.t b/debian/perl-framework/t/php/switch4.t new file mode 100644 index 0000000..2d5b4f5 --- /dev/null +++ b/debian/perl-framework/t/php/switch4.t @@ -0,0 +1,43 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $expected = <<EXPECT; +zero +one +2 +3 +4 +5 +6 +7 +8 +9 +zero +one +2 +3 +4 +5 +6 +7 +8 +9 +zero +one +2 +3 +4 +5 +6 +7 +8 +9 +EXPECT + +my $result = GET_BODY "/php/switch4.php"; +ok $result eq $expected; diff --git a/debian/perl-framework/t/php/umask.t b/debian/perl-framework/t/php/umask.t new file mode 100644 index 0000000..769ffab --- /dev/null +++ b/debian/perl-framework/t/php/umask.t @@ -0,0 +1,19 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## test that umask() is reset after script execution + +plan tests => 4, need_php4; + +my $first = GET_BODY "/php/umask.php"; + +foreach my $n (1..4) { + my $try = GET_BODY "/php/umask.php"; + + ok t_cmp($try, $first, "umask was $try not $first for request $n"); +} + diff --git a/debian/perl-framework/t/php/var1.t b/debian/perl-framework/t/php/var1.t new file mode 100644 index 0000000..22a9f3d --- /dev/null +++ b/debian/perl-framework/t/php/var1.t @@ -0,0 +1,36 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, need_php; + +## var1.php source: +## <?php echo $variable?> +## +## result should be variable echoed back. + +my $page = '/php/var1.php'; +my $data = "blah1+blah2+FOO"; +#my @data = (variable => $data); +my $expected = $data; +$expected =~ s/\+/ /g; + +## POST +#my $return = POST_BODY $page, \@data; +#print STDERR "\n\n$return\n\n"; +#ok $return eq $expected; +my $return = POST_BODY $page, content => "variable=$data"; +ok t_cmp($return, + $expected, + "POST request for $page, content=\"variable=$data\"" + ); + +## GET +$return = GET_BODY "$page?variable=$data"; +ok t_cmp($return, + $expected, + "GET request for $page?variable=$data" + ); diff --git a/debian/perl-framework/t/php/var2.t b/debian/perl-framework/t/php/var2.t new file mode 100644 index 0000000..2080b7e --- /dev/null +++ b/debian/perl-framework/t/php/var2.t @@ -0,0 +1,34 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, need_php; + +## var2.php source: +## <?php echo "$v1 $v2"?> +## +## result should be variables v1 and v2. + +my $page = '/php/var2.php'; +my $v1 = "blah1+blah2+FOO"; +my $v2 = "this+is+v2"; +my $data = "v1=$v1\&v2=$v2"; +my $expected = "$v1 $v2"; +$expected =~ s/\+/ /g; + +## POST +my $return = POST_BODY $page, content => $data; +ok t_cmp($return, + $expected, + "POST request for $page, content=\"$data\"" + ); + +## GET +$return = GET_BODY "$page?$data"; +ok t_cmp($return, + $expected, + "GET request for $page?$data" + ); diff --git a/debian/perl-framework/t/php/var3.t b/debian/perl-framework/t/php/var3.t new file mode 100644 index 0000000..efa19fe --- /dev/null +++ b/debian/perl-framework/t/php/var3.t @@ -0,0 +1,35 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 2, need_php; + +## var3.php source: +## <?php echo "$v1 $v2 $v3"?> +## +## result should be variables v1, v2 and v3. + +my $page = '/php/var3.php'; +my $v1 = "blah1+blah2+FOO"; +my $v2 = "this+is+v2"; +my $v3 = "DOOM-GL00m"; +my $data = "v1=$v1\&v2=$v2\&v3=$v3"; +my $expected = "$v1 $v2 $v3"; +$expected =~ s/\+/ /g; + +## POST +my $return = POST_BODY $page, content => $data; +ok t_cmp($return, + $expected, + "POST request for $page, content=\"$data\"" + ); + +## GET +$return = GET_BODY "$page?$data"; +ok t_cmp($return, + $expected, + "GET request for $page?$data" + ); diff --git a/debian/perl-framework/t/php/virtual.t b/debian/perl-framework/t/php/virtual.t new file mode 100644 index 0000000..f0dd67e --- /dev/null +++ b/debian/perl-framework/t/php/virtual.t @@ -0,0 +1,13 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 1, sub { need_php() && need_module('negotiation') }; + +my $result = GET_BODY "/php/virtual.php"; +chomp $result; +ok t_cmp($result, "before file.html after", + "regression test for http://bugs.php.net/bug.php?id=30446"); diff --git a/debian/perl-framework/t/php/while.t b/debian/perl-framework/t/php/while.t new file mode 100644 index 0000000..74453c7 --- /dev/null +++ b/debian/perl-framework/t/php/while.t @@ -0,0 +1,10 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need_php; + +my $result = GET_BODY "/php/while.php"; +ok $result eq '123456789'; diff --git a/debian/perl-framework/t/protocol/echo.t b/debian/perl-framework/t/protocol/echo.t new file mode 100644 index 0000000..b225866 --- /dev/null +++ b/debian/perl-framework/t/protocol/echo.t @@ -0,0 +1,40 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest (); + +my @test_strings = ( + $0, + $^X, + $$ x 5, +); + +my $tests = 1 + @test_strings; +my $vars = Apache::Test::vars(); +my @modules = qw(mod_echo); + +if (have_ssl) { + $tests *= 2; + unshift @modules, 'mod_echo_ssl'; + Apache::TestRequest::set_ca_cert(); +} + +plan tests => $tests, ['mod_echo']; + +for my $module (@modules) { + print "testing $module\n"; + + my $sock = Apache::TestRequest::vhost_socket($module); + ok $sock; + + Apache::TestRequest::socket_trace($sock); + + for my $data (@test_strings) { + $sock->print("$data\n"); + + chomp(my $response = Apache::TestRequest::getline($sock)); + ok t_cmp($response, $data, 'echo'); + } +} diff --git a/debian/perl-framework/t/protocol/nntp-like.t b/debian/perl-framework/t/protocol/nntp-like.t new file mode 100644 index 0000000..9e5bb1f --- /dev/null +++ b/debian/perl-framework/t/protocol/nntp-like.t @@ -0,0 +1,47 @@ +#testing that the server can respond right after client connects, +#before client sends any request data + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $tests = 5; +my $vars = Apache::Test::vars(); +my @modules = qw(mod_nntp_like); + +if (have_ssl && ! have_module('http2')) { + $tests *= 2; + unshift @modules, 'mod_nntp_like_ssl'; + Apache::TestRequest::set_ca_cert(); +} + +plan tests => $tests, need('mod_nntp_like', + { "deferred accept() prohibits testing with >=2.1.0 and OS $^O" => + sub { !have_min_apache_version('2.1.0') + || ($^O ne "linux" && $^O ne "darwin")} } ); + +for my $module (@modules) { + print "testing $module\n"; + + my $sock = Apache::TestRequest::vhost_socket($module); + ok $sock; + + Apache::TestRequest::socket_trace($sock); + + my $response = Apache::TestRequest::getline($sock); + + $response =~ s/[\r\n]+$//; + ok t_cmp($response, '200 localhost - ready', + 'welcome response'); + + for my $data ('LIST', 'GROUP dev.httpd.apache.org', 'ARTICLE 401') { + $sock->print("$data\n"); + + $response = Apache::TestRequest::getline($sock); + chomp($response) if (defined($response)); + ok t_cmp($response, $data, 'echo'); + } +} diff --git a/debian/perl-framework/t/security/CVE-2003-0542.t b/debian/perl-framework/t/security/CVE-2003-0542.t new file mode 100644 index 0000000..20497d8 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2003-0542.t @@ -0,0 +1,15 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1, need 'rewrite'; + +my $rc; + +$rc = GET_RC "/security/CAN-2003-0542/nonesuch"; + +ok t_cmp($rc, 404, "CAN-2003-0542 test case"); + diff --git a/debian/perl-framework/t/security/CVE-2004-0747.t b/debian/perl-framework/t/security/CVE-2004-0747.t new file mode 100644 index 0000000..414a844 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2004-0747.t @@ -0,0 +1,34 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1, need_apache(2); + +my $rc; + +$rc = GET_RC "/security/CAN-2004-0747/"; + +# This test used to check for SegFaults when expanding variables +# inside a .htaccess file. +# Only, the code trying to parse the generated AuthName will +# fail with a 500 when the string exceeds a certain length (at least on OS X) +# +# So, in case of a 500 return, we check for a proper body and assume +# that the failure was graceful and not a crash. +# +# The alternative would be to expand a env var under our control in .htacess +# for this test, so that the outcome is not depending on the env of the person +# starting the test. +# +if ($rc == 500) { + my $body = GET_BODY "/security/CAN-2004-0747/"; + if (length $body > 0) { + $rc = 200; + } +} + +ok t_cmp($rc, 200, "CAN-2004-0747 ap_resolve_env test case"); + diff --git a/debian/perl-framework/t/security/CVE-2004-0811.t b/debian/perl-framework/t/security/CVE-2004-0811.t new file mode 100644 index 0000000..c0c7661 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2004-0811.t @@ -0,0 +1,21 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 8, need_apache(2); + +my $rc; + +foreach my $y (1..4) { + $rc = GET_RC("/security/CAN-2004-0811/sub/"); + ok t_cmp($rc, 200, "subdir access allowed"); +} + +foreach my $z (1..4) { + $rc = GET_RC("/security/CAN-2004-0811/"); + ok t_cmp($rc, 401, "topdir access denied"); +} + diff --git a/debian/perl-framework/t/security/CVE-2004-0940.t b/debian/perl-framework/t/security/CVE-2004-0940.t new file mode 100644 index 0000000..740b3f3 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2004-0940.t @@ -0,0 +1,12 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 1, need_module 'include'; + +# 1.3.32 and earlier will segfault +ok t_cmp(GET_RC("/security/CAN-2004-0940.shtml"), + 200, 'response was 200'); diff --git a/debian/perl-framework/t/security/CVE-2004-0942.t b/debian/perl-framework/t/security/CVE-2004-0942.t new file mode 100644 index 0000000..9810480 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2004-0942.t @@ -0,0 +1,36 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +$SIG{PIPE} = 'IGNORE'; + +plan tests => 2, need_min_apache_version('2.0'); + +my $sock = Apache::TestRequest::vhost_socket('default'); +ok $sock; + +# This is a test for CAN-2004-0942 albeit a pretty bad one: +# CAN-2004-0942 is a memory leak in the <=2.0.52 logic for handling +# whitespace in folded headers. This test tests that a folded header +# which, including whitespace, exceeds the field length limit, gets a +# 400 response. A better httpd implementation could handle such +# headers without the memory leak, yet would fail this test. + +Apache::TestRequest::socket_trace($sock); + +$sock->print("GET /index.html HTTP/1.0\r\n"); + +my $n = $sock->print("Hello:\r\n"); +foreach (1..100) { + $n = $sock->print(" "x500 . "\r\n") if $sock->connected; +} + +$sock->print("\r\n") if $sock->connected; + +my $line = Apache::TestRequest::getline($sock) || ''; + +ok t_cmp($line, qr{^HTTP/1\.. 400}, "request was refused"); + diff --git a/debian/perl-framework/t/security/CVE-2004-0958.t b/debian/perl-framework/t/security/CVE-2004-0958.t new file mode 100644 index 0000000..87e8d39 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2004-0958.t @@ -0,0 +1,37 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my %queries = +( + + "foo[bar=1" => qr/\[foo_bar\] => 1\n/, + "foo bar=2" => qr/\[foo_bar\] => 2\n/, + "foo. .bar=3" => qr/\[foo___bar\] => 3\n/, + "foobar[=3" => qr/\[foobar_\] => 3\n/, + + "foo[g][=1" => qr/\[g\] => 1\n/, # corruption pre-5.0.2/4.3.9 + "foo[][=2" => qr/\[0\] => 2\n/, # segfault in 5.0.2/4.3.9 + + "foo[][[[[[=3" => qr/\[0\] => 3\n/, + "foo[][][][][]=5" => qr/\[0\] => 5\n/, + + "foo[j]bar=6" => qr/\[j\] => 6\n/, + + +### tests which have dubious results currently: +# "foo[[[[[[[h]=4" => qr/\[0\] => 4\n/, +# "foo[ ]=7" => qr/\[baz\] => 7\n/, +# "foo[ ]=7" => qr/\[baz\] => 7\n/, + + ); + +plan tests => (keys %queries) * 1, need_php; + +foreach (keys %queries) { + my $actual = GET_BODY "/security/CAN-2004-0958.php?".$_; + ok t_cmp($actual, $queries{$_}, "query for $_"); +} diff --git a/debian/perl-framework/t/security/CVE-2004-0959.t b/debian/perl-framework/t/security/CVE-2004-0959.t new file mode 100644 index 0000000..fb15e80 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2004-0959.t @@ -0,0 +1,56 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 6, need 'LWP', { "PHP not installed", \&need_php }; + +use HTTP::Message; + +my $url = Apache::TestRequest::resolve_url("/security/CAN-2004-0959.php"); + +sub multipart +{ + my $name = shift; + my $filename = shift; + my $ctype = shift; + my $extra = shift; + my $req = HTTP::Request->new(POST => $url); + + $req->header(Content_Type => 'multipart/form-data; boundary=XXXX'); + + $req->content("--XXXX\n". + "Content-Disposition: form-data; name=\"MAX_FILE_SIZE\"\n\n". + "30000\n". + "--XXXX\n". + "Content-Disposition: form-data; name=\"".$name."\"; filename=\"".$filename."\"\n". + "Content-Type: ".$ctype."\n\n". + "fish\n"); + + $req->add_content($extra) if $extra; + + $req->add_content("--XXXX--\n"); + + Apache::TestRequest::user_agent->request($req); +} + +my $resp = multipart("user_file", "fish.php", "text/plain"); +ok t_cmp($resp->code, 200, "POST request success"); +ok t_cmp($resp->content, "fish.php", "filename parsed safely"); + +$resp = multipart("user_file", "../../fish.php", "text/plain"); +ok t_cmp($resp->code, 200, "POST request success"); +ok t_cmp($resp->content, "fish.php", "filename parsed safely"); + +$resp = multipart + ("user[file[name]123", "good.php", "/tmp/passt.php", + "--XXXX\n". + "Content-Disposition: form-data; name=\"user[file[type]123\"; filename=\"vg\"\n". + "Content-Type: text/plain\n\n". + "fishfood\n"); + +ok t_cmp($resp->code, 200, "POST request success"); +ok t_cmp($resp->content, "FAILED", "filename parsed safely"); + diff --git a/debian/perl-framework/t/security/CVE-2005-2491.t b/debian/perl-framework/t/security/CVE-2005-2491.t new file mode 100644 index 0000000..7085fb8 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2005-2491.t @@ -0,0 +1,21 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2 * 2, need 'rewrite'; + +foreach my $dir ("one/", "two/") { + my $r = GET("/security/CAN-2005-2491/" . $dir); + + # LWP will generate the annoying fake-500 response if the server + # segfaults before generating its own 500 response; check + # the response message explicitly to rule that out. + + ok t_cmp($r->message, 'Internal Server Error', + 'check that server did not segfault'); + + ok t_cmp($r->code, 500, "check for 500 response error"); +} diff --git a/debian/perl-framework/t/security/CVE-2005-2700.t b/debian/perl-framework/t/security/CVE-2005-2700.t new file mode 100644 index 0000000..6af7fae --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2005-2700.t @@ -0,0 +1,25 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $vars = Apache::Test::vars(); + +plan tests => 2, need $vars->{ssl_module_name}, need_lwp, + qw(LWP::Protocol::https); + +Apache::TestRequest::user_agent_keepalive(0); +Apache::TestRequest::scheme('https'); +Apache::TestRequest::module('ssl_optional_cc'); + +my $r; + +$r = GET "/require/none/"; + +ok t_cmp($r->code, 200, "access permitted without ccert"); + +$r = GET "/require/any/"; + +ok !t_cmp($r->code, 200, "access *not* permitted without ccert"); diff --git a/debian/perl-framework/t/security/CVE-2005-3352.t b/debian/perl-framework/t/security/CVE-2005-3352.t new file mode 100644 index 0000000..b1881a9 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2005-3352.t @@ -0,0 +1,23 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $vars = Apache::Test::vars(); + +plan tests => 2, need_imagemap; + +my $url = "/security/CVE-2005-3352.map"; + +my $r = GET $url, Referer => '">http://fish/'; + +ok t_cmp($r->code, 200, "response code is OK"); + +if ((!have_min_apache_version('2.3') && have_min_apache_version('2.2.24')) || + have_min_apache_version('2.4.4')) { + ok t_cmp($r->content, qr/%22%3e/, "referer was escaped"); +} else { + ok t_cmp($r->content, qr/\"/, "referer was escaped"); +} diff --git a/debian/perl-framework/t/security/CVE-2005-3357.t b/debian/perl-framework/t/security/CVE-2005-3357.t new file mode 100644 index 0000000..0124796 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2005-3357.t @@ -0,0 +1,51 @@ +use strict; +use warnings FATAL => 'all'; + +# Test case for PR 33791. + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +BEGIN { + # prevent TestRequest from croaking on an HTTP/0.9 response + $ENV{APACHE_TEST_HTTP_09_OK} = 1; +} + +my $vars = Apache::Test::vars(); + +plan tests => 3, need $vars->{ssl_module_name}, need_lwp, + qw(LWP::Protocol::https); + +Apache::TestRequest::user_agent_keepalive(0); + +my $config = Apache::Test::config(); + +Apache::TestRequest::module("ssl_pr33791"); + +my $hostport = Apache::TestRequest::hostport(); + +my $rurl = "http://" . $hostport . "/"; + +t_debug("URL is $rurl"); + +my $r = GET($rurl); + +my $proto = $r->protocol; + +ok $proto; + +if (!$proto) { + skip "server gave no response"; +} else { + if ($proto eq "HTTP/0.9") { + skip "server gave HTTP/0.9 response"; + } elsif ($proto) { + ok t_cmp($r->code, + 400, + "Expected bad request from 'GET $rurl'" + ); + } +} + +ok t_cmp($r->content, qr/welcome to localhost/, "errordoc content was served"); diff --git a/debian/perl-framework/t/security/CVE-2006-5752.t b/debian/perl-framework/t/security/CVE-2006-5752.t new file mode 100644 index 0000000..911f59f --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2006-5752.t @@ -0,0 +1,16 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2, need_module 'status'; + +my $r; + +$r = GET "/server-status"; + +ok t_cmp($r->code, 200, "server-status gave response"); + +ok t_cmp($r->header("Content-Type"), qr/charset=/, "response content-type had charset"); diff --git a/debian/perl-framework/t/security/CVE-2007-5000.t b/debian/perl-framework/t/security/CVE-2007-5000.t new file mode 100644 index 0000000..8502378 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2007-5000.t @@ -0,0 +1,18 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $vars = Apache::Test::vars(); + +plan tests => 2, need_imagemap; + +my $url = '/security/CVE-2005-3352.map/<foo>'; + +my $r = GET $url; + +ok t_cmp($r->code, 200, "response code is OK"); + +ok !t_cmp($r->content, qr/<foo>/, "URI was escaped in response"); diff --git a/debian/perl-framework/t/security/CVE-2007-6388.t b/debian/perl-framework/t/security/CVE-2007-6388.t new file mode 100644 index 0000000..70ebb7d --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2007-6388.t @@ -0,0 +1,18 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $vars = Apache::Test::vars(); + +plan tests => 2, need_module 'status'; + +my $url = '/server-status?refresh=42;fish'; + +my $r = GET $url; + +ok t_cmp($r->code, 200, "response code is OK"); + +ok t_cmp($r->header('Refresh'), 42, "refresh parameter not echoed verbatim"); diff --git a/debian/perl-framework/t/security/CVE-2008-2364.t b/debian/perl-framework/t/security/CVE-2008-2364.t new file mode 100644 index 0000000..46552ad --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2008-2364.t @@ -0,0 +1,36 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +my $tests = 3; +my $server_suppresses_interim = 1; +if (!have_min_apache_version("2.4.10")) { + $tests = 1; + $server_suppresses_interim = 0; +} + +plan tests => $tests, need_module 'proxy'; + +Apache::TestRequest::module("proxy_http_reverse"); +Apache::TestRequest::user_agent(requests_redirectable => 0); + +my $r = GET("/reverse/"); +ok t_cmp($r->code, 200, "reverse proxy to index.html"); +if (have_cgi) { + if ($server_suppresses_interim) { + # XXX: This doesn't work in 2.2.x w/o at least r1588519 because LWP + # sees the unexpected interim response and stops. + $r = GET("/reverse/modules/cgi/nph-interim1.pl"); + ok t_cmp($r->code, 200, "small number of interim responses - CVE-2008-2364"); + + $r = GET("/reverse/modules/cgi/nph-interim2.pl"); + ok t_cmp($r->code, 502, "large number of interim responses - CVE-2008-2364"); + } +} else { + skip "skipping tests without CGI module" foreach (1..2); +} + diff --git a/debian/perl-framework/t/security/CVE-2009-1195.t b/debian/perl-framework/t/security/CVE-2009-1195.t new file mode 100644 index 0000000..70663c4 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2009-1195.t @@ -0,0 +1,1120 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + + +plan tests => 221, need 'include', need_min_apache_version('2.2'); + +Apache::TestRequest::module('mod_include'); #use this module's port + +my $r; +my $body; + +### Test #1, context: Options None : AllowOverride Options=IncludesNoExec : Options +Includes + +$r = GET("/modules/include/ssi-exec/1/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #1; 500 response expected"); + +### Test #2, context: Options None : AllowOverride Options=IncludesNoExec : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/2/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #2; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #2"); + +### Test #3, context: Options None : AllowOverride Options=IncludesNoExec : Options Includes + +$r = GET("/modules/include/ssi-exec/3/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #3; 500 response expected"); + +### Test #4, context: Options None : AllowOverride Options=IncludesNoExec : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/4/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #4; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #4"); + +### Test #5, context: Options None : AllowOverride Options=IncludesNoExec : Options -Includes + +$r = GET("/modules/include/ssi-exec/5/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #5; 500 response expected"); + +### Test #6, context: Options None : AllowOverride Options=IncludesNoExec : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/6/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #6; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #6"); + +### Test #7, context: Options None : AllowOverride Options=IncludesNoExec : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/7/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #7; 500 response expected"); + +### Test #8, context: Options None : AllowOverride Options=IncludesNoExec : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/8/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #8; 500 response expected"); + +### Test #9, context: Options None : AllowOverride Options=IncludesNoExec : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/9/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #9; 500 response expected"); + +### Test #10, context: Options None : AllowOverride Options=IncludesNoExec : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/10/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #10; 500 response expected"); + +### Test #11, context: Options None : AllowOverride Options=Includes : Options +Includes + +$r = GET("/modules/include/ssi-exec/11/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #11; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #11"); + +### Test #12, context: Options None : AllowOverride Options=Includes : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/12/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #12; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #12"); + +### Test #13, context: Options None : AllowOverride Options=Includes : Options Includes + +$r = GET("/modules/include/ssi-exec/13/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #13; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #13"); + +### Test #14, context: Options None : AllowOverride Options=Includes : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/14/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #14; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #14"); + +### Test #15, context: Options None : AllowOverride Options=Includes : Options -Includes + +$r = GET("/modules/include/ssi-exec/15/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #15; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #15"); + +### Test #16, context: Options None : AllowOverride Options=Includes : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/16/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #16; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #16"); + +### Test #17, context: Options None : AllowOverride Options=Includes : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/17/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #17; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #17"); + +### Test #18, context: Options None : AllowOverride Options=Includes : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/18/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #18; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #18"); + +### Test #19, context: Options None : AllowOverride Options=Includes : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/19/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #19; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #19"); + +### Test #20, context: Options None : AllowOverride Options=Includes : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/20/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #20; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #20"); + +### Test #21, context: Options None : AllowOverride All : Options +Includes + +$r = GET("/modules/include/ssi-exec/21/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #21; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #21"); + +### Test #22, context: Options None : AllowOverride All : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/22/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #22; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #22"); + +### Test #23, context: Options None : AllowOverride All : Options Includes + +$r = GET("/modules/include/ssi-exec/23/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #23; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #23"); + +### Test #24, context: Options None : AllowOverride All : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/24/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #24; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #24"); + +### Test #25, context: Options None : AllowOverride All : Options -Includes + +$r = GET("/modules/include/ssi-exec/25/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #25; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #25"); + +### Test #26, context: Options None : AllowOverride All : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/26/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #26; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #26"); + +### Test #27, context: Options None : AllowOverride All : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/27/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #27; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #27"); + +### Test #28, context: Options None : AllowOverride All : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/28/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #28; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #28"); + +### Test #29, context: Options None : AllowOverride All : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/29/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #29; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #29"); + +### Test #30, context: Options None : AllowOverride All : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/30/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #30; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #30"); + +### Test #31, context: Options None : AllowOverride None : Options +Includes + +$r = GET("/modules/include/ssi-exec/31/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #31; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #31"); + +### Test #32, context: Options None : AllowOverride None : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/32/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #32; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #32"); + +### Test #33, context: Options None : AllowOverride None : Options Includes + +$r = GET("/modules/include/ssi-exec/33/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #33; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #33"); + +### Test #34, context: Options None : AllowOverride None : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/34/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #34; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #34"); + +### Test #35, context: Options None : AllowOverride None : Options -Includes + +$r = GET("/modules/include/ssi-exec/35/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #35; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #35"); + +### Test #36, context: Options None : AllowOverride None : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/36/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #36; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #36"); + +### Test #37, context: Options None : AllowOverride None : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/37/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #37; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #37"); + +### Test #38, context: Options None : AllowOverride None : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/38/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #38; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #38"); + +### Test #39, context: Options None : AllowOverride None : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/39/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #39; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #39"); + +### Test #40, context: Options None : AllowOverride None : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/40/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #40; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #40"); + +### Test #41, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options +Includes + +$r = GET("/modules/include/ssi-exec/41/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #41; 500 response expected"); + +### Test #42, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/42/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #42; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #42"); + +### Test #43, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options Includes + +$r = GET("/modules/include/ssi-exec/43/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #43; 500 response expected"); + +### Test #44, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/44/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #44; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #44"); + +### Test #45, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options -Includes + +$r = GET("/modules/include/ssi-exec/45/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #45; 500 response expected"); + +### Test #46, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/46/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #46; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #46"); + +### Test #47, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/47/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #47; 500 response expected"); + +### Test #48, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/48/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #48; 500 response expected"); + +### Test #49, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/49/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #49; 500 response expected"); + +### Test #50, context: Options IncludesNoExec : AllowOverride Options=IncludesNoExec : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/50/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #50; 500 response expected"); + +### Test #51, context: Options IncludesNoExec : AllowOverride Options=Includes : Options +Includes + +$r = GET("/modules/include/ssi-exec/51/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #51; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #51"); + +### Test #52, context: Options IncludesNoExec : AllowOverride Options=Includes : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/52/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #52; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #52"); + +### Test #53, context: Options IncludesNoExec : AllowOverride Options=Includes : Options Includes + +$r = GET("/modules/include/ssi-exec/53/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #53; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #53"); + +### Test #54, context: Options IncludesNoExec : AllowOverride Options=Includes : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/54/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #54; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #54"); + +### Test #55, context: Options IncludesNoExec : AllowOverride Options=Includes : Options -Includes + +$r = GET("/modules/include/ssi-exec/55/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #55; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #55"); + +### Test #56, context: Options IncludesNoExec : AllowOverride Options=Includes : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/56/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #56; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #56"); + +### Test #57, context: Options IncludesNoExec : AllowOverride Options=Includes : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/57/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #57; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #57"); + +### Test #58, context: Options IncludesNoExec : AllowOverride Options=Includes : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/58/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #58; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #58"); + +### Test #59, context: Options IncludesNoExec : AllowOverride Options=Includes : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/59/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #59; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #59"); + +### Test #60, context: Options IncludesNoExec : AllowOverride Options=Includes : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/60/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #60; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #60"); + +### Test #61, context: Options IncludesNoExec : AllowOverride All : Options +Includes + +$r = GET("/modules/include/ssi-exec/61/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #61; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #61"); + +### Test #62, context: Options IncludesNoExec : AllowOverride All : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/62/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #62; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #62"); + +### Test #63, context: Options IncludesNoExec : AllowOverride All : Options Includes + +$r = GET("/modules/include/ssi-exec/63/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #63; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #63"); + +### Test #64, context: Options IncludesNoExec : AllowOverride All : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/64/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #64; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #64"); + +### Test #65, context: Options IncludesNoExec : AllowOverride All : Options -Includes + +$r = GET("/modules/include/ssi-exec/65/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #65; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #65"); + +### Test #66, context: Options IncludesNoExec : AllowOverride All : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/66/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #66; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #66"); + +### Test #67, context: Options IncludesNoExec : AllowOverride All : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/67/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #67; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #67"); + +### Test #68, context: Options IncludesNoExec : AllowOverride All : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/68/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #68; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #68"); + +### Test #69, context: Options IncludesNoExec : AllowOverride All : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/69/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #69; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #69"); + +### Test #70, context: Options IncludesNoExec : AllowOverride All : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/70/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #70; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #70"); + +### Test #71, context: Options IncludesNoExec : AllowOverride None : Options +Includes + +$r = GET("/modules/include/ssi-exec/71/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #71; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #71"); + +### Test #72, context: Options IncludesNoExec : AllowOverride None : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/72/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #72; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #72"); + +### Test #73, context: Options IncludesNoExec : AllowOverride None : Options Includes + +$r = GET("/modules/include/ssi-exec/73/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #73; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #73"); + +### Test #74, context: Options IncludesNoExec : AllowOverride None : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/74/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #74; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #74"); + +### Test #75, context: Options IncludesNoExec : AllowOverride None : Options -Includes + +$r = GET("/modules/include/ssi-exec/75/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #75; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #75"); + +### Test #76, context: Options IncludesNoExec : AllowOverride None : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/76/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #76; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #76"); + +### Test #77, context: Options IncludesNoExec : AllowOverride None : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/77/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #77; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #77"); + +### Test #78, context: Options IncludesNoExec : AllowOverride None : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/78/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #78; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #78"); + +### Test #79, context: Options IncludesNoExec : AllowOverride None : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/79/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #79; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #79"); + +### Test #80, context: Options IncludesNoExec : AllowOverride None : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/80/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #80; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #80"); + +### Test #81, context: Options Includes : AllowOverride Options=IncludesNoExec : Options +Includes + +$r = GET("/modules/include/ssi-exec/81/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #81; 500 response expected"); + +### Test #82, context: Options Includes : AllowOverride Options=IncludesNoExec : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/82/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #82; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #82"); + +### Test #83, context: Options Includes : AllowOverride Options=IncludesNoExec : Options Includes + +$r = GET("/modules/include/ssi-exec/83/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #83; 500 response expected"); + +### Test #84, context: Options Includes : AllowOverride Options=IncludesNoExec : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/84/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #84; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #84"); + +### Test #85, context: Options Includes : AllowOverride Options=IncludesNoExec : Options -Includes + +$r = GET("/modules/include/ssi-exec/85/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #85; 500 response expected"); + +### Test #86, context: Options Includes : AllowOverride Options=IncludesNoExec : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/86/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #86; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #86"); + +### Test #87, context: Options Includes : AllowOverride Options=IncludesNoExec : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/87/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #87; 500 response expected"); + +### Test #88, context: Options Includes : AllowOverride Options=IncludesNoExec : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/88/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #88; 500 response expected"); + +### Test #89, context: Options Includes : AllowOverride Options=IncludesNoExec : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/89/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #89; 500 response expected"); + +### Test #90, context: Options Includes : AllowOverride Options=IncludesNoExec : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/90/exec.shtml"); +ok t_cmp($r->code, 500, "Options should not be allowed for script #90; 500 response expected"); + +### Test #91, context: Options Includes : AllowOverride Options=Includes : Options +Includes + +$r = GET("/modules/include/ssi-exec/91/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #91; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #91"); + +### Test #92, context: Options Includes : AllowOverride Options=Includes : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/92/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #92; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #92"); + +### Test #93, context: Options Includes : AllowOverride Options=Includes : Options Includes + +$r = GET("/modules/include/ssi-exec/93/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #93; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #93"); + +### Test #94, context: Options Includes : AllowOverride Options=Includes : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/94/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #94; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #94"); + +### Test #95, context: Options Includes : AllowOverride Options=Includes : Options -Includes + +$r = GET("/modules/include/ssi-exec/95/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #95; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #95"); + +### Test #96, context: Options Includes : AllowOverride Options=Includes : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/96/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #96; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #96"); + +### Test #97, context: Options Includes : AllowOverride Options=Includes : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/97/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #97; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #97"); + +### Test #98, context: Options Includes : AllowOverride Options=Includes : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/98/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #98; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #98"); + +### Test #99, context: Options Includes : AllowOverride Options=Includes : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/99/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #99; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #99"); + +### Test #100, context: Options Includes : AllowOverride Options=Includes : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/100/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #100; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #100"); + +### Test #101, context: Options Includes : AllowOverride All : Options +Includes + +$r = GET("/modules/include/ssi-exec/101/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #101; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #101"); + +### Test #102, context: Options Includes : AllowOverride All : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/102/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #102; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #102"); + +### Test #103, context: Options Includes : AllowOverride All : Options Includes + +$r = GET("/modules/include/ssi-exec/103/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #103; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #103"); + +### Test #104, context: Options Includes : AllowOverride All : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/104/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #104; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #104"); + +### Test #105, context: Options Includes : AllowOverride All : Options -Includes + +$r = GET("/modules/include/ssi-exec/105/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #105; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #105"); + +### Test #106, context: Options Includes : AllowOverride All : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/106/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #106; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #106"); + +### Test #107, context: Options Includes : AllowOverride All : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/107/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #107; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, '[an error occurred while processing this directive]', "SSI should be evaluated but exec not permitted for script #107"); + +### Test #108, context: Options Includes : AllowOverride All : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/108/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #108; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #108"); + +### Test #109, context: Options Includes : AllowOverride All : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/109/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #109; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #109"); + +### Test #110, context: Options Includes : AllowOverride All : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/110/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #110; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, qr/--\#exec cgi=/, "SSI should not be evaluated for script #110"); + +### Test #111, context: Options Includes : AllowOverride None : Options +Includes + +$r = GET("/modules/include/ssi-exec/111/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #111; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #111"); + +### Test #112, context: Options Includes : AllowOverride None : Options +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/112/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #112; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #112"); + +### Test #113, context: Options Includes : AllowOverride None : Options Includes + +$r = GET("/modules/include/ssi-exec/113/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #113; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #113"); + +### Test #114, context: Options Includes : AllowOverride None : Options IncludesNoExec + +$r = GET("/modules/include/ssi-exec/114/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #114; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #114"); + +### Test #115, context: Options Includes : AllowOverride None : Options -Includes + +$r = GET("/modules/include/ssi-exec/115/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #115; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #115"); + +### Test #116, context: Options Includes : AllowOverride None : Options -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/116/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #116; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #116"); + +### Test #117, context: Options Includes : AllowOverride None : Options -Includes +IncludesNoExec + +$r = GET("/modules/include/ssi-exec/117/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #117; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #117"); + +### Test #118, context: Options Includes : AllowOverride None : Options +Includes -IncludesNoExec + +$r = GET("/modules/include/ssi-exec/118/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #118; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #118"); + +### Test #119, context: Options Includes : AllowOverride None : Options -IncludesNoExec +Includes + +$r = GET("/modules/include/ssi-exec/119/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #119; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #119"); + +### Test #120, context: Options Includes : AllowOverride None : Options +IncludesNoExec -Includes + +$r = GET("/modules/include/ssi-exec/120/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #120; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #120"); + +### Test #121, context: Options Includes : AllowOverride None : No options in subdir, no .htaccess + +$r = GET("/modules/include/ssi-exec/121/subdir/exec.shtml"); +ok t_cmp($r->code, 200, "Options should be allowed for script #121; 200 response expected"); + +$body = $r->content; +chomp $body; + +ok t_cmp($body, 'perl cgi', "SSI should be evaluated with exec allowed for script #121"); + diff --git a/debian/perl-framework/t/security/CVE-2009-1890.t b/debian/perl-framework/t/security/CVE-2009-1890.t new file mode 100644 index 0000000..6ef46b2 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2009-1890.t @@ -0,0 +1,65 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +use IO::Select; + +plan tests => 7, need [qw(mod_proxy proxy_http.c)]; + +my $len = 100000; + +my $sock = Apache::TestRequest::vhost_socket('proxy_http_reverse'); +ok $sock && $sock->connected; + +my $req = + "POST /reverse/modules/cgi/perl_echo.pl HTTP/1.0\r\n". + "Content-Length: 0" . $len . "\r\n". + "\r\n"; + +ok $sock->print($req); + +my $half_body = 'x' x ($len/2); +ok $sock->print($half_body); +sleep(1); +ok $sock->print($half_body); + +my $readable = IO::Select->new($sock)->can_read(10); +ok $readable, 1, "timeout, server hung"; +if (!$readable) { + skip "server hung, not testing further", foreach(1..2); + exit(0); +} + +my $line = Apache::TestRequest::getline($sock) || ''; +ok t_cmp($line, qr{^HTTP/1\.. 200}, "request was parsed"); + +do { + $line = Apache::TestRequest::getline($sock) || ''; + $line = super_chomp($line); + print "# header: $line\n"; +} until ($line eq ""); + +my $buffer; +while ($len > 0 && $sock->read($buffer, $len)) { + print "# got: $buffer\n"; + $len -= length($buffer); + print "# remaining: $len\n"; +} + +ok t_cmp($len, 0, "read entire body"); + +sub super_chomp { + my ($body) = shift; + + ## super chomp - all leading and trailing \n (and \r for win32) + $body =~ s/^[\n\r]*//; + $body =~ s/[\n\r]*$//; + ## and all the rest change to spaces + $body =~ s/\n/ /g; + $body =~ s/\r//g; #rip out all remaining \r's + + $body; +} diff --git a/debian/perl-framework/t/security/CVE-2009-3555.t b/debian/perl-framework/t/security/CVE-2009-3555.t new file mode 100644 index 0000000..bd0c413 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2009-3555.t @@ -0,0 +1,67 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 4, need 'ssl'; + +# This test case attempts only one type of attack which is possible +# due to the TLS renegotiation vulnerability, CVE-2009-3555. A +# specific defense against this attack was added to mod_ssl in +# r891282. For more information, see the dev@httpd thread beginning +# at message ID <4B01BD20.1060300@adnovum.ch>. + +Apache::TestRequest::set_client_cert("client_ok"); + +Apache::TestRequest::module('mod_ssl'); + +my $sock = Apache::TestRequest::vhost_socket('mod_ssl'); + +if ($sock && $sock->connected && $sock->get_sslversion() eq "TLSv1_3") { + skip "Skipping test for TLSv1.3" foreach(1..4); + exit; +} + +ok $sock && $sock->connected; + + +my $req = "GET /require/asf/ HTTP/1.1\r\n". + "Host: " . Apache::TestRequest::hostport() . "\r\n". + "\r\n". + "GET /this/is/a/prefix/injection/attack HTTP/1.0\r\n". + "Host: " . Apache::TestRequest::hostport() . "\r\n". + "\r\n"; + +ok $sock->print($req); + +my $line = Apache::TestRequest::getline($sock) || ''; + +ok t_cmp($line, qr{^HTTP/1\.. 200}, "read first response-line"); + +my $rv = 0; + +do { + $line = Apache::TestRequest::getline($sock) || ''; + $line = super_chomp($line); + print "# line: $line\n"; + if ($line eq "Connection: close") { + $rv = 1; + } +} until ($line eq ""); + +ok $rv, 1, "expected Connection: close header in response"; + +sub super_chomp { + my ($body) = shift; + + ## super chomp - all leading and trailing \n (and \r for win32) + $body =~ s/^[\n\r]*//; + $body =~ s/[\n\r]*$//; + ## and all the rest change to spaces + $body =~ s/\n/ /g; + $body =~ s/\r//g; #rip out all remaining \r's + + $body; +} diff --git a/debian/perl-framework/t/security/CVE-2011-3368-rewrite.t b/debian/perl-framework/t/security/CVE-2011-3368-rewrite.t new file mode 100644 index 0000000..4107be0 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2011-3368-rewrite.t @@ -0,0 +1,23 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 3, need 'rewrite'; + +Apache::TestRequest::module("cve_2011_3368_rewrite"); + +my $sock = Apache::TestRequest::vhost_socket(); +ok $sock && $sock->connected; + +my $req = "GET @"."localhost/foobar.html HTTP/1.1\r\n". + "Host: " . Apache::TestRequest::hostport() . "\r\n". + "\r\n"; + +ok $sock->print($req); + +my $line = Apache::TestRequest::getline($sock) || ''; + +ok t_cmp($line, qr{^HTTP/1\.. 400 Bad Request}, "got 400 error"); diff --git a/debian/perl-framework/t/security/CVE-2011-3368.t b/debian/perl-framework/t/security/CVE-2011-3368.t new file mode 100644 index 0000000..bbedc79 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2011-3368.t @@ -0,0 +1,23 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 3, need 'proxy', need_min_apache_version('2.2.5'); + +Apache::TestRequest::module("cve_2011_3368"); + +my $sock = Apache::TestRequest::vhost_socket(); +ok $sock && $sock->connected; + +my $req = "GET @"."localhost/foobar.html HTTP/1.1\r\n". + "Host: " . Apache::TestRequest::hostport() . "\r\n". + "\r\n"; + +ok $sock->print($req); + +my $line = Apache::TestRequest::getline($sock) || ''; + +ok t_cmp($line, qr{^HTTP/1\.. 400 Bad Request}, "got 400 error"); diff --git a/debian/perl-framework/t/security/CVE-2017-7659.t b/debian/perl-framework/t/security/CVE-2017-7659.t new file mode 100644 index 0000000..690922d --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2017-7659.t @@ -0,0 +1,28 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +plan tests => 2, + need( + need_module('http2') + ); + +my $module = "h2c"; +Apache::TestRequest::module($module); + +my $sock = Apache::TestRequest::vhost_socket($module); +ok $sock; + +# Thanks to Javier Jimenez for this test case. +Apache::TestRequest::socket_trace($sock); +$sock->print("p * HTTP/1.0\r\n" + . "Connection:H/\r\n" + . "Upgrade:h2c\r\n" + . "HTTP2-Settings:\r\n\r\n"); + +# The server should not have crashed -- getc() should return *something*. +ok $sock->getc(); +$sock->close(); diff --git a/debian/perl-framework/t/security/CVE-2019-0215.t b/debian/perl-framework/t/security/CVE-2019-0215.t new file mode 100644 index 0000000..978c1ef --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2019-0215.t @@ -0,0 +1,47 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my $vars = Apache::Test::vars(); + +plan tests => 2, need $vars->{ssl_module_name}, need_lwp, + qw(LWP::Protocol::https); + +my $r; + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); +Apache::TestRequest::module('ssl_optional_cc'); + +$r = GET "/require/none/"; +my $tls13_works = $r->is_success; + +# Forget the above user agent settings, start fresh +Apache::TestRequest::user_agent(reset => 1); + +# If TLS 1.3 worked, run the tests using it and expect 403. +# Older TLS versions seem to show the TLS alert client side as a 500. +my $expected_status; +if ($tls13_works) { + Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); + $expected_status = 403; + t_debug "Using TLSv13, expecting status 403"; +} else { + t_debug "Using TLS before TLSv13, expecting status 500"; + $expected_status = 500; +} + +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); +Apache::TestRequest::module('ssl_optional_cc'); + +$r = GET "/require/any/"; + +ok t_cmp($r->code, $expected_status, "first access denied without client cert"); + +$r = GET "/require/any/"; + +ok t_cmp($r->code, $expected_status, "second access denied without client cert"); diff --git a/debian/perl-framework/t/security/CVE-2020-1927.t b/debian/perl-framework/t/security/CVE-2020-1927.t new file mode 100644 index 0000000..523feb6 --- /dev/null +++ b/debian/perl-framework/t/security/CVE-2020-1927.t @@ -0,0 +1,60 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use MIME::Base64; +use Data::Dumper; +use HTTP::Response; +use Socket; + +plan tests => 1, need_min_apache_version('2.4.42'); + +my $sock = Apache::TestRequest::vhost_socket("core"); +if (!$sock) { + print "# failed to connect\n"; + ok(0); + next; +} + +my $req = sprintf "GET /CVE-2020-1927/%%0D%%0Ahttp://127.0.0.1/ HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n"; +print "# SENDING to " . peer($sock) . "\n# $req\n"; +$sock->print("$req"); +$sock->flush(); +sleep(0.1); +$req = escape($req); +print "# SENDING to " . peer($sock) . "\n# $req\n"; + +my $response_data = ""; +my $buf; +while ($sock->read($buf, 10000) > 0) { + $response_data .= $buf; +} +my $response = HTTP::Response->parse($response_data); +if (! defined $response) { + die "HTTP::Response->parse failed"; +} +ok t_cmp($response->code, 404, "regex didn't match and redirect"); + +sub escape +{ + my $in = shift; + $in =~ s{\\}{\\\\}g; + $in =~ s{\r}{\\r}g; + $in =~ s{\n}{\\n}g; + $in =~ s{\t}{\\t}g; + $in =~ s{([\x00-\x1f])}{sprintf("\\x%02x", ord($1))}ge; + return $in; +} + +sub peer +{ + my $sock = shift; + my $hersockaddr = getpeername($sock); + return "<disconnected>" if !$hersockaddr; + my ($port, $iaddr) = sockaddr_in($hersockaddr); + my $herhostname = gethostbyaddr($iaddr, AF_INET); + my $herstraddr = inet_ntoa($iaddr); + return "$herstraddr:$port"; +} diff --git a/debian/perl-framework/t/ssl/all.t b/debian/perl-framework/t/ssl/all.t new file mode 100644 index 0000000..d3965d8 --- /dev/null +++ b/debian/perl-framework/t/ssl/all.t @@ -0,0 +1,12 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +my $vars = Apache::Test::vars(); + +#skip all tests in this directory unless ssl is enabled +#and LWP has https support +plan tests => 1, [$vars->{ssl_module_name}, qw(LWP::Protocol::https)]; + +ok 1; + diff --git a/debian/perl-framework/t/ssl/basicauth.t b/debian/perl-framework/t/ssl/basicauth.t new file mode 100644 index 0000000..dde2131 --- /dev/null +++ b/debian/perl-framework/t/ssl/basicauth.t @@ -0,0 +1,45 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestConfig (); +use Apache::TestUtil; + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $url = '/ssl-fakebasicauth/index.html'; + +plan tests => 4, need need_auth, need_lwp; + +Apache::TestRequest::scheme('https'); + +# With TLSv1.3 mod_ssl may return a better 403 error here, otherwise +# expect a TLS alert which is represented as a 500 by LWP. +ok t_cmp (GET_RC($url, cert => undef), + qr/^(500|403)$/, + "Getting $url with no cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_snakeoil'), + 200, + "Getting $url with client_snakeoil cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_ok'), + 401, + "Getting $url with client_ok cert" + ); + +if (!have_min_apache_version("2.5.1")) { + skip "Colon in username test skipped."; +} +else { + ok t_cmp (GET_RC($url, cert => 'client_colon'), + 403, + "Getting $url with client_colon cert" + ); +} diff --git a/debian/perl-framework/t/ssl/env.t b/debian/perl-framework/t/ssl/env.t new file mode 100644 index 0000000..912a4dc --- /dev/null +++ b/debian/perl-framework/t/ssl/env.t @@ -0,0 +1,89 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use Apache::TestConfig (); +use Apache::TestSSLCA (); + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. +Apache::TestRequest::user_agent_keepalive(0); + +my $cert = 'client_snakeoil'; + +my $server_expect = + Apache::TestSSLCA::dn_vars('ca', 'SERVER_I'); + +my $client_expect = + Apache::TestSSLCA::dn_vars($cert, 'CLIENT_S'); + +my $url = '/ssl-cgi/env.pl'; + +my $tests = (keys(%$server_expect) + keys(%$client_expect) + 1) * 2; +plan tests => $tests, need need_cgi, need_lwp; + +Apache::TestRequest::scheme('https'); + +my $r = GET($url); + +ok t_cmp($r->code, 200, "response status OK"); + +my $env = getenv($r->as_string); + +verify($env, $server_expect); +verify($env, $client_expect, 1); + +$url = '/require-ssl-cgi/env.pl'; + +$r = GET($url, cert => $cert); + +ok t_cmp($r->code, 200, "second response status OK"); + +$env = getenv($r->as_string); + +verify($env, $server_expect); +verify($env, $client_expect); + +sub verify { + my($env, $expect, $ne) = @_; + + while (my($key, $val) = each %$expect) { + # the emailAddress attribute is still exported using the name + # _DN_Email by mod_ssl, even when using OpenSSL 0.9.7. + if ($key =~ /(.*)_emailAddress/) { + $key = $1 . "_Email"; + } + if (Apache::TestConfig::WIN32) { + #perl uppercases all %ENV keys + #which causes SSL_*_DN_Email lookups to fail + $key = uc $key; + } + unless ($ne || $env->{$key}) { + print "#$key does not exist\n"; + $env->{$key} = ""; #prevent use of unitialized value + } + if ($ne) { + print "#$key should not exist\n"; + ok not exists $env->{$key}; + } + else { + print "#$key: expect '$val', got '$env->{$key}'\n"; + ok $env->{$key} eq $val; + } + } +} + +sub getenv { + my $str = shift; + + my %env; + + for my $line (split /[\r\n]+/, $str) { + my($key, $val) = split /\s*=\s*/, $line, 2; + next unless $key and $val; + $env{$key} = $val; + } + + \%env; +} diff --git a/debian/perl-framework/t/ssl/extlookup.t b/debian/perl-framework/t/ssl/extlookup.t new file mode 100644 index 0000000..d40e76e --- /dev/null +++ b/debian/perl-framework/t/ssl/extlookup.t @@ -0,0 +1,32 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +Apache::TestRequest::scheme("https"); + +my %exts = ( + "2.16.840.1.113730.1.13" => "This Is A Comment" +); + +if (have_min_apache_version("2.4.0")) { + $exts{"1.3.6.1.4.1.18060.12.0"} = "Lemons", +} + +plan tests => 2 * (keys %exts), need 'test_ssl', need_min_apache_version(2.1); + +my ($actual, $expected, $r, $c); + +foreach (sort keys %exts) { + $r = GET("/test_ssl_ext_lookup?$_", cert => 'client_ok'); + + ok t_cmp($r->code, 200, "ssl_ext_lookup works for $_"); + + $c = $r->content; + chomp $c; + + ok t_cmp($c, $exts{$_}, "Extension value match for $_"); +} + diff --git a/debian/perl-framework/t/ssl/fakeauth.t b/debian/perl-framework/t/ssl/fakeauth.t new file mode 100644 index 0000000..9009cf4 --- /dev/null +++ b/debian/perl-framework/t/ssl/fakeauth.t @@ -0,0 +1,35 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestConfig (); +use Apache::TestUtil; + +# check fake authentication using mod_auth_anon +# no cert should fail but the presence of any cert +# should pass. see also t/ssl/basicauth.t + +my $url = '/ssl-fakebasicauth2/index.html'; + +plan tests => 3, need need_auth, + need_module('mod_authn_anon'), + need_min_apache_version(2.1); + +Apache::TestRequest::scheme('https'); + +# With TLSv1.3 mod_ssl may return a better 403 error here, otherwise +# expect a TLS alert which is represented as a 500 by LWP. +ok t_cmp (GET_RC($url, cert => undef), + qr/^(500|403)$/, + "Getting $url with no cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_snakeoil'), + 200, + "Getting $url with client_snakeoil cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_ok'), + 200, + "Getting $url with client_ok cert" + ); diff --git a/debian/perl-framework/t/ssl/headers.t b/debian/perl-framework/t/ssl/headers.t new file mode 100644 index 0000000..825d6a9 --- /dev/null +++ b/debian/perl-framework/t/ssl/headers.t @@ -0,0 +1,28 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $tests = 3; + +plan tests => $tests, need need_lwp, need_module('headers', 'ssl'); + +Apache::TestRequest::scheme('https'); + +my $h = HEAD_STR "/modules/headers/ssl/"; + +# look for 500 when mod_headers doesn't grok the %s tag +if ($h =~ /^HTTP\/1.1 500 Internal Server Error\n/) { + foreach (1..$tests) { + skip "Skipping because mod_headers doesn't grok %s\n"; + } + exit 0; +} + +$h =~ s/Client-Bad-Header-Line:.*$//g; + +ok t_cmp($h, qr/X-SSL-Flag: on/, "SSLFlag header set"); +ok t_cmp($h, qr/X-SSL-Cert:.*END CERTIFICATE-----/, "SSL certificate is unwrapped"); +ok t_cmp($h, qr/X-SSL-None: \(null\)\n/, "unknown SSL variable not given"); diff --git a/debian/perl-framework/t/ssl/http.t b/debian/perl-framework/t/ssl/http.t new file mode 100644 index 0000000..e556224 --- /dev/null +++ b/debian/perl-framework/t/ssl/http.t @@ -0,0 +1,48 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +BEGIN { + # prevent TestRequest from croaking on an HTTP/0.9 response + $ENV{APACHE_TEST_HTTP_09_OK} = 1; +} + +#verify we can send an non-ssl http request to the ssl port +#without dumping core. + +my $url = '/index.html'; + +my @todo; + +if (Apache::TestConfig::WIN32) { + print "\n#ap_core_translate() chokes on ':' here\n", + "#where r->uri = /mod_ssl:error:HTTP-request\n"; + @todo = (todo => [2]); +} + +plan tests => 2, @todo, need_lwp; + +my $config = Apache::Test::config(); +my $ssl_module = $config->{vars}->{ssl_module_name}; +my $hostport = $config->{vhosts}->{$ssl_module}->{hostport}; +my $rurl = "http://$hostport$url"; + +my $res = GET($rurl); +my $proto = $res->protocol; + +if ($proto and $proto eq "HTTP/0.9") { + skip "server gave HTTP/0.9 response"; +} else { + ok t_cmp($res->code, + 400, + "Expected bad request from 'GET $rurl'" + ); +} + +ok t_cmp($res->content, + qr{speaking plain HTTP to an SSL-enabled server port}, + "that error document contains the proper hint" + ); + diff --git a/debian/perl-framework/t/ssl/ocsp.t b/debian/perl-framework/t/ssl/ocsp.t new file mode 100644 index 0000000..8ec8505 --- /dev/null +++ b/debian/perl-framework/t/ssl/ocsp.t @@ -0,0 +1,64 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestSSLCA; +use Apache::TestRequest; +use Apache::TestConfig (); + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $url = '/index.html'; + +Apache::TestRequest::scheme('https'); +Apache::TestRequest::module('ssl_ocsp'); + +my $openssl = Apache::TestSSLCA::openssl(); +if (!have_min_apache_version('2.4.26') + or `$openssl list -commands 2>&1` !~ /ocsp/) { + print "1..0 # skip: No OpenSSL or mod_ssl OCSP support"; + exit 0; +} + +plan tests => 3, need_lwp; + +my $r; + +sok { + $r = GET $url, cert => undef; + my $message = $r->content() || ''; + my $warning = $r->header('Client-Warning') || ''; + print "warning: $warning\n"; + print "message: $message"; + print "response:\n"; + print $r->as_string; + $r->code == 500 && $warning =~ 'Internal response' && + $message =~ /alert handshake failure|read failed|closed connection without sending any data/; +}; + +sok { + $r = GET $url, cert => 'client_ok'; + my $warning = $r->header('Client-Warning') || ''; + my $message = $r->content() || ''; + print "warning: $warning\n"; + print "message: $message"; + print "response:\n"; + print $r->as_string; + $r->code == 200; +}; + +sok { + $r = GET $url, cert => 'client_revoked'; + my $message = $r->content() || ''; + my $warning = $r->header('Client-Warning') || ''; + print "warning: $warning\n"; + print "message: $message"; + print "response:\n"; + print $r->as_string; + $r->code == 500 && $warning =~ 'Internal response' && + $message =~ /alert certificate revoked|read failed|closed connection without sending any data/; +}; diff --git a/debian/perl-framework/t/ssl/pha.t b/debian/perl-framework/t/ssl/pha.t new file mode 100644 index 0000000..2e2a763 --- /dev/null +++ b/debian/perl-framework/t/ssl/pha.t @@ -0,0 +1,47 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use IO::Socket::SSL; + +# This is the equivalent of pr12355.t for TLSv1.3. + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); +Apache::TestRequest::user_agent_keepalive(1); + +my $r = GET "/"; + +if (!$r->is_success) { + print "1..0 # skip: TLSv1.3 not supported"; + exit 0; +} + +if (!defined &IO::Socket::SSL::can_pha || !IO::Socket::SSL::can_pha()) { + print "1..0 # skip: PHA not supported by IO::Socket::SSL < 2.061"; + exit 0; +} + +plan tests => 4, need_min_apache_version("2.4.47"); + +$r = GET("/verify/", cert => undef); +ok t_cmp($r->code, 403, "access must be denied without client certificate"); + +# SSLRenegBufferSize 10 for this location which should mean a 413 +# error. +$r = POST("/require/small/perl_echo.pl", content => 'y'x101, + cert => 'client_ok'); +ok t_cmp($r->code, 413, "PHA reneg body buffer size restriction works"); + +# Reset to use a new connection. +Apache::TestRequest::user_agent(reset => 1); +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); + +$r = POST("/verify/modules/cgi/perl_echo.pl", content => 'x'x10000, + cert => 'client_ok'); + +ok t_cmp($r->code, 200, "PHA works with POST body"); +ok t_cmp($r->content, $r->request->content, "request body matches response"); diff --git a/debian/perl-framework/t/ssl/pr12355.t b/debian/perl-framework/t/ssl/pr12355.t new file mode 100644 index 0000000..8444b3f --- /dev/null +++ b/debian/perl-framework/t/ssl/pr12355.t @@ -0,0 +1,70 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 10, need 'ssl', need_min_apache_version('2.0'); + +my $r; + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); + +$r = GET "/"; +my $tls13_works = $r->is_success; + +# Forget the above user agent settings, start fresh +Apache::TestRequest::user_agent(reset => 1); + +# If TLS 1.3 worked, downgrade to TLS 1.2, otherwise use what works. +if ($tls13_works) { + t_debug "Downgrading to TLSv12"; + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL', SSL_version => 'TLSv12'}); +} else { + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL'}); +} +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); + +# Send a series of POST requests with varying size request bodies. +# Alternate between the location which requires a AES128-SHA ciphersuite +# and one which requires AES256-SHA; mod_ssl will attempt to perform the +# renegotiation between each request, and hence needs to perform the +# buffering of request body data. + +$r = POST "/require-aes256-cgi/perl_echo.pl", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "hello world", "request body matches response"); + +$r = POST "/require-aes128-cgi/perl_echo.pl", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "hello world", "request body matches response"); + +$r = POST "/require-aes256-cgi/perl_echo.pl", content => 'x'x10000; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, $r->request->content, "request body matches response"); + +$r = POST "/require-aes128-cgi/perl_echo.pl", content => 'x'x60000; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, $r->request->content, "request body matches response"); + +# Test that content-level input filters are still run as expected by +# using a request which triggers the mod_case_filter_in: + +my @filter = ('X-AddInputFilter' => 'CaseFilterIn'); #mod_client_add_filter + +if (have_module('case_filter_in')) { + $r = POST "/require-aes256-cgi/perl_echo.pl", @filter, content => "hello"; + + ok t_cmp($r->code, 200, "renegotiation on POST works"); + ok t_cmp($r->content, "HELLO", "request body matches response"); +} else { + skip "mod_case_filter_in not available" foreach (1..2); +} + diff --git a/debian/perl-framework/t/ssl/pr43738.t b/debian/perl-framework/t/ssl/pr43738.t new file mode 100644 index 0000000..6bf9ccf --- /dev/null +++ b/debian/perl-framework/t/ssl/pr43738.t @@ -0,0 +1,43 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 4, + need 'ssl', need_module('actions'), + need_min_apache_version('2.2.7'); + +my $r; + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); + +$r = GET "/"; +my $tls13_works = $r->is_success; + +# Forget the above user agent settings, start fresh +Apache::TestRequest::user_agent(reset => 1); + +# If TLS 1.3 worked, downgrade to TLS 1.2, otherwise use what works. +if ($tls13_works) { + t_debug "Downgrading to TLSv12"; + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL', SSL_version => 'TLSv12'}); +} else { + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL'}); +} +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); + +# Variation of the PR 12355 test which breaks per PR 43738. + +$r = POST "/modules/ssl/aes128/empty.pfa", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "/modules/ssl/aes128/empty.pfa\nhello world", "request body matches response"); + +$r = POST "/modules/ssl/aes256/empty.pfa", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "/modules/ssl/aes256/empty.pfa\nhello world", "request body matches response"); diff --git a/debian/perl-framework/t/ssl/proxy.t b/debian/perl-framework/t/ssl/proxy.t new file mode 100644 index 0000000..bec84b4 --- /dev/null +++ b/debian/perl-framework/t/ssl/proxy.t @@ -0,0 +1,120 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestCommon (); + +my %frontend = ( + proxy_http_https => 'http', + proxy_https_https => 'https', + proxy_https_http => 'https', + proxy_http_https_proxy_section => 'http', + proxy_https_https_proxy_section => 'https', +); +my %backend = ( + proxy_http_https => 'https', + proxy_https_https => 'https', + proxy_https_http => 'http', + proxy_http_https_proxy_section => 'https', + proxy_https_https_proxy_section => 'https', +); + +my $num_modules = scalar keys %frontend; +my $post_module = 'eat_post'; + +my $post_tests = have_module($post_module) ? + Apache::TestCommon::run_post_test_sizes() : 0; + +my $num_http_backends = 0; +for my $module (sort keys %backend) { + if ($backend{$module} eq "http") { + $num_http_backends++; + } +} + +plan tests => (8 + $post_tests) * $num_modules - 5 * $num_http_backends, + need need_lwp, [qw(mod_proxy proxy_http.c)]; + +for my $module (sort keys %frontend) { + + my $scheme = $frontend{$module}; + Apache::TestRequest::module($module); + Apache::TestRequest::scheme($scheme); + + my $hostport = Apache::TestRequest::hostport(); + my $res; + my %vars; + + sok { + t_cmp(GET('/')->code, + 200, + "/ with $module ($scheme)"); + }; + + sok { + t_cmp(GET('/modules/cgi/nph-foldhdr.pl')->code, + 200, + "CGI script with folded headers"); + }; + + if ($backend{$module} eq "https") { + sok { + t_cmp(GET('/verify')->code, + 200, + "using valid proxyssl client cert"); + }; + + sok { + t_cmp(GET('/require/snakeoil')->code, + 403, + "using invalid proxyssl client cert"); + }; + + $res = GET('/require-ssl-cgi/env.pl'); + + sok { + t_cmp($res->code, 200, "protected cgi script"); + }; + + my $body = $res->content || ""; + + for my $line (split /\s*\r?\n/, $body) { + my($key, $val) = split /\s*=\s*/, $line, 2; + next unless $key; + $vars{$key} = $val || ""; + } + + sok { + t_cmp($vars{HTTP_X_FORWARDED_HOST}, + $hostport, + "X-Forwarded-Host header"); + }; + + sok { + t_cmp($vars{SSL_CLIENT_S_DN_CN}, + 'client_ok', + "client subject common name"); + }; + } + + sok { + #test that ProxyPassReverse rewrote the Location header + #to use the frontend server rather than downstream server + my $uri = '/modules'; + my $ruri = Apache::TestRequest::resolve_url($uri) . '/'; + + #tell lwp not to follow redirect so we can see the Location header + local $Apache::TestRequest::RedirectOK = 0; + + $res = GET($uri); + + my $location = $res->header('Location') || 'NONE'; + + t_cmp($location, $ruri, 'ProxyPassReverse Location rewrite'); + }; + + Apache::TestCommon::run_post_test($post_module) if $post_tests; + Apache::TestRequest::user_agent(reset => 1); +} diff --git a/debian/perl-framework/t/ssl/require.t b/debian/perl-framework/t/ssl/require.t new file mode 100644 index 0000000..2a218d4 --- /dev/null +++ b/debian/perl-framework/t/ssl/require.t @@ -0,0 +1,55 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $sslrequire_oid_needed_version = '2.1.7'; +my $have_sslrequire_oid = have_min_apache_version($sslrequire_oid_needed_version); + +plan tests => 10, need_lwp; + +Apache::TestRequest::scheme('https'); + +my $url = '/require/asf/index.html'; + +ok GET_RC($url, cert => undef) != 200; + +ok GET_RC($url, cert => 'client_ok') == 200; + +ok GET_RC($url, cert => 'client_revoked') != 200; + +$url = '/require/snakeoil/index.html'; + +ok GET_RC($url, cert => 'client_ok') != 200; + +ok GET_RC($url, cert => 'client_snakeoil') == 200; + +ok GET_RC('/require/strcmp/index.html', cert => undef) == 200; + +ok GET_RC('/require/intcmp/index.html', cert => undef) == 200; + +if ($have_sslrequire_oid) { + + $url = '/require/certext/index.html'; + + ok GET_RC($url, cert => undef) != 200; + + if (!have_min_apache_version("2.4.0")) { + skip "not backported, see 2.2.19 vote thread for analysis"; + } + else { + ok GET_RC($url, cert => 'client_ok') == 200; + } + + ok GET_RC($url, cert => 'client_snakeoil') != 200; + +} else { + skip "skipping certificate extension test (httpd < $sslrequire_oid_needed_version)" foreach (1..3); +} diff --git a/debian/perl-framework/t/ssl/v2.t b/debian/perl-framework/t/ssl/v2.t new file mode 100644 index 0000000..643c9d7 --- /dev/null +++ b/debian/perl-framework/t/ssl/v2.t @@ -0,0 +1,28 @@ +BEGIN { + $ENV{HTTPS_VERSION} = 2; #use SSLv2 instead of SSLv3 +} + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need need_lwp, + { "SSLv2 test(s) not applicable" => + sub { !need_min_apache_version('2.4.0') } }; + +Apache::TestRequest::scheme('https'); + +#just make sure the basics work for SSLv2 +ok GET_OK('/'); + +#per-dir renegotiation does not work with SSLv2, +#same breakage with apache-1.3.22+mod_ssl-2.8.5 +my $url = '/require/asf/index.html'; + +#ok GET_RC($url, cert => undef) != 200; + +#ok GET_RC($url, cert => 'client_ok') == 200; + +#ok GET_RC($url, cert => 'client_revoked') != 200; diff --git a/debian/perl-framework/t/ssl/varlookup.t b/debian/perl-framework/t/ssl/varlookup.t new file mode 100644 index 0000000..e00a143 --- /dev/null +++ b/debian/perl-framework/t/ssl/varlookup.t @@ -0,0 +1,266 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestSSLCA qw(dn dn_oneline); + +unless (have_lwp) { + # bail out early, since the parser below relies on $LWP::VERSION + plan tests => 0, need_lwp; +} + +use Time::localtime; + +my $config = Apache::Test::config(); +my $vars = Apache::Test::vars(); +my $server = $config->server; +my $time = localtime(); + +(my $mmn = $config->{httpd_info}->{MODULE_MAGIC_NUMBER}) =~ s/:\d+$//; + +#Apache::TestRequest::scheme('https'); +local $vars->{scheme} = 'https'; +my $port = $config->port; +my $rfc2253 = have_min_apache_version('2.3.11'); + +my $url = '/test_ssl_var_lookup'; +my(%lookup, @vars); + +my %client_dn = dn('client_ok'); + +my $client_dn = dn_oneline(\%client_dn, $rfc2253); + +my %client_i_dn = dn('ca'); + +my $client_i_dn = dn_oneline(\%client_i_dn, $rfc2253); + +my %server_dn = dn('server'); + +my $dgst = Apache::TestSSLCA::dgst(); + +my $email_field = Apache::TestSSLCA::email_field(); + +my $san_email = "$client_dn{$email_field}"; + +my $san_dns = "$server_dn{CN}"; + +my $san_msupn = $san_email; + +my $san_dnssrv = "_https.$server_dn{CN}"; + +if (not have_min_apache_version('2.4.13')) { + $san_email = $san_dns = "NULL"; +} + +if (not have_min_apache_version('2.4.17') or + Apache::Test::normalize_vstring(Apache::TestSSLCA::version()) < + Apache::Test::normalize_vstring("0.9.8")) { + $san_msupn = $san_dnssrv = "NULL"; +} + +# YYY will be turned into a pattern match: httpd-test/([-\w]+) +# so we can test with different server keys/certs +$server_dn{OU} = 'httpd-test/YYY'; +$server_dn{CN} = $vars->{servername}; + +my $server_dn = dn_oneline(\%server_dn, $rfc2253); + +$server_dn =~ s{(httpd-test.*?)YYY}{$1([-\\w]+)}; +$server_dn{OU} =~ s{(httpd-test.*?)YYY}{$1([-\\w]+)}; + +my %server_i_dn = %client_i_dn; +my $server_i_dn = $client_i_dn; + +my $cert_datefmt = '^\w{3} {1,2}\d{1,2} \d{2}:\d{2}:\d{2} \d{4} GMT$'; + +while (<DATA>) { + chomp; + s/^\s+//; s/\s+$//; + s/\#.*//; + next unless $_; + my($key, $val) = split /\s+/, $_, 2; + next unless $key and $val; + + if ($val =~ /^\"/) { + $val = eval qq($val); + } + elsif ($val =~ /^\'([^\']+)\'$/) { + $val = $1; + } + else { + $val = eval $val; + } + + die $@ if $@; + + $lookup{$key} = $val; + push @vars, $key; +} + +if (not have_min_apache_version('2.4.32')) { + @vars = grep(!/_RAW/, @vars); +} + +if (not have_min_apache_version('2.5.1')) { + @vars = grep(!/_B64CERT/, @vars); +} + +plan tests => scalar (@vars), need need_lwp, need_module('test_ssl'); + +for my $key (@vars) { + sok { verify($key); }; +} + +sub verify { + my $key = shift; + my @headers; + if ($key eq 'HTTP_REFERER') { + push @headers, Referer => $0; + } + my $str = GET_BODY("$url?$key", cert => 'client_ok', + @headers); + t_cmp($str, $lookup{$key}, "$key"); +} + +__END__ +#http://www.modssl.org/docs/2.8/ssl_reference.html#ToC23 +HTTP_USER_AGENT "libwww-perl/$LWP::VERSION", +HTTP:User-Agent "libwww-perl/$LWP::VERSION", +HTTP_REFERER "$0" +HTTP_COOKIE +HTTP_FORWARDED +HTTP_HOST Apache::TestRequest::hostport() +HTTP_PROXY_CONNECTION +HTTP_ACCEPT + +#standard CGI variables +PATH_INFO +AUTH_TYPE +QUERY_STRING 'QUERY_STRING' +SERVER_SOFTWARE qr(^$server->{version}) +SERVER_ADMIN $vars->{serveradmin} +SERVER_PORT "$port" +SERVER_NAME $vars->{servername} +SERVER_PROTOCOL qr(^HTTP/1\.\d$) +REMOTE_IDENT +REMOTE_ADDR $vars->{remote_addr} +REMOTE_HOST +REMOTE_USER +DOCUMENT_ROOT $vars->{documentroot} +REQUEST_METHOD 'GET' +REQUEST_URI $url + +#mod_ssl specific variables +TIME_YEAR $time->year()+1900 +TIME_MON sprintf "%02d", $time->mon()+1 +TIME_DAY sprintf "%02d", $time->mday() +TIME_WDAY $time->wday() +TIME +TIME_HOUR +TIME_MIN +TIME_SEC + +IS_SUBREQ 'false' +API_VERSION "$mmn" +THE_REQUEST qr(^GET $url\?THE_REQUEST HTTP/1\.\d$) +REQUEST_SCHEME $vars->{scheme} +REQUEST_FILENAME +HTTPS 'on' +ENV:THE_ARGS 'ENV:THE_ARGS' + +#XXX: should use Net::SSLeay to parse the certs +#rather than just pattern match and hardcode + +SSL_CLIENT_M_VERSION qr(^\d+$) +SSL_SERVER_M_VERSION qr(^\d+$) +SSL_CLIENT_M_SERIAL qr(^[0-9A-F]+$) +SSL_SERVER_M_SERIAL qr(^[0-9A-F]+$) +SSL_PROTOCOL qr((TLS|SSL)v([1-3]|1\.[0-3])$) +SSL_CLIENT_V_START qr($cert_datefmt); +SSL_SERVER_V_START qr($cert_datefmt); +SSL_SESSION_ID +SSL_CLIENT_V_END qr($cert_datefmt); +SSL_SERVER_V_END qr($cert_datefmt); +SSL_CIPHER qr(^[A-Z0-9_-]+$) +SSL_CIPHER_EXPORT 'false' +SSL_CIPHER_ALGKEYSIZE qr(^\d+$) +SSL_CIPHER_USEKEYSIZE qr(^\d+$) +SSL_SECURE_RENEG qr(^(false|true)$) + +SSL_CLIENT_S_DN "$client_dn" +SSL_SERVER_S_DN qr(^$server_dn$) +SSL_CLIENT_S_DN_C "$client_dn{C}" +SSL_SERVER_S_DN_C "$server_dn{C}" +SSL_CLIENT_S_DN_ST "$client_dn{ST}" +SSL_SERVER_S_DN_ST "$server_dn{ST}" +SSL_CLIENT_S_DN_L "$client_dn{L}" +SSL_SERVER_S_DN_L "$server_dn{L}" +SSL_CLIENT_S_DN_O "$client_dn{O}" +SSL_SERVER_S_DN_O "$server_dn{O}" +SSL_CLIENT_S_DN_OU "$client_dn{OU}" +SSL_SERVER_S_DN_OU qr(^$server_dn{OU}) +SSL_CLIENT_S_DN_CN "$client_dn{CN}" +SSL_SERVER_S_DN_CN "$server_dn{CN}" +SSL_CLIENT_S_DN_T +SSL_SERVER_S_DN_T +SSL_CLIENT_S_DN_I +SSL_SERVER_S_DN_I +SSL_CLIENT_S_DN_G +SSL_SERVER_S_DN_G +SSL_CLIENT_S_DN_S +SSL_SERVER_S_DN_S +SSL_CLIENT_S_DN_D +SSL_SERVER_S_DN_D +SSL_CLIENT_S_DN_UID +SSL_SERVER_S_DN_UID +SSL_CLIENT_S_DN_Email "$client_dn{$email_field}" +SSL_SERVER_S_DN_Email "$server_dn{$email_field}" +SSL_CLIENT_SAN_Email_0 "$san_email" +SSL_SERVER_SAN_DNS_0 "$san_dns" +SSL_CLIENT_SAN_OTHER_msUPN_0 "$san_msupn" +SSL_SERVER_SAN_OTHER_dnsSRV_0 "$san_dnssrv" + +SSL_CLIENT_I_DN "$client_i_dn" +SSL_SERVER_I_DN "$server_i_dn" +SSL_CLIENT_I_DN_C "$client_i_dn{C}" +SSL_SERVER_I_DN_C "$server_i_dn{C}" +SSL_CLIENT_I_DN_ST "$client_i_dn{ST}" +SSL_SERVER_I_DN_ST "$server_i_dn{ST}" +SSL_CLIENT_I_DN_L "$client_i_dn{L}" +SSL_SERVER_I_DN_L "$server_i_dn{L}" +SSL_CLIENT_I_DN_O "$client_i_dn{O}" +SSL_SERVER_I_DN_O "$server_i_dn{O}" +SSL_CLIENT_I_DN_OU "$client_i_dn{OU}" +SSL_SERVER_I_DN_OU "$server_i_dn{OU}" +SSL_CLIENT_I_DN_CN "$client_i_dn{CN}" +SSL_SERVER_I_DN_CN "$server_i_dn{CN}" +SSL_SERVER_I_DN_CN_RAW "$server_i_dn{CN}" +SSL_SERVER_I_DN_CN_0_RAW "$server_i_dn{CN}" +SSL_CLIENT_I_DN_T +SSL_SERVER_I_DN_T +SSL_CLIENT_I_DN_I +SSL_SERVER_I_DN_I +SSL_CLIENT_I_DN_G +SSL_SERVER_I_DN_G +SSL_CLIENT_I_DN_S +SSL_SERVER_I_DN_S +SSL_CLIENT_I_DN_D +SSL_SERVER_I_DN_D +SSL_CLIENT_I_DN_UID +SSL_SERVER_I_DN_UID +SSL_CLIENT_I_DN_Email "$client_i_dn{$email_field}" +SSL_SERVER_I_DN_Email "$server_i_dn{$email_field}" +SSL_CLIENT_A_SIG "${dgst}WithRSAEncryption" +SSL_SERVER_A_SIG "${dgst}WithRSAEncryption" +SSL_CLIENT_A_KEY 'rsaEncryption' +SSL_SERVER_A_KEY qr(^[rd]saEncryption$) +SSL_CLIENT_CERT qr(^-----BEGIN CERTIFICATE-----) +SSL_SERVER_CERT qr(^-----BEGIN CERTIFICATE-----) +SSL_CLIENT_B64CERT qr(^[a-zA-Z0-9+/]{64,}={0,2}$) +SSL_SERVER_B64CERT qr(^[a-zA-Z0-9+/]{64,}={0,2}$) +SSL_CLIENT_VERIFY 'SUCCESS' +SSL_VERSION_LIBRARY +SSL_VERSION_INTERFACE + diff --git a/debian/perl-framework/t/ssl/verify.t b/debian/perl-framework/t/ssl/verify.t new file mode 100644 index 0000000..7bca845 --- /dev/null +++ b/debian/perl-framework/t/ssl/verify.t @@ -0,0 +1,39 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestConfig (); + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $url = '/verify/index.html'; + +plan tests => 3, need_lwp; + +Apache::TestRequest::scheme('https'); + +my $r; + +sok { + $r = GET $url, cert => undef; + print $r->as_string; + $r->code != 200; +}; + +sok { + $r = GET $url, cert => 'client_ok'; + print $r->as_string; + $r->code == 200; +}; + +sok { + $r = GET $url, cert => 'client_revoked'; + print $r->as_string; + $r->code != 200; +}; + |