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;