119 lines
3.3 KiB
Perl
119 lines
3.3 KiB
Perl
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";
|
|
}
|