307 lines
8.9 KiB
Perl
307 lines
8.9 KiB
Perl
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'
|
|
);
|
|
}
|