blob: 45941e7c39fa9220c2bf6ac958507ecbaa9112c9 [file] [log] [blame]
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 $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;
} 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'
);
}