That's a helpful link - thanks! Although, that code uses an HTTP::Response object to pass back to the daemon. Any advice on printing out the response object when not using a daemon? The CPAN docs are entirely clear on this (HTTP::Response and HTTP::Message), and when I implement the print $response->decoded_content in the following code, I get an error of Can't decode ref content at /usr/local/lib/perl5/site_perl/5.8.9/HTTP/Message.pm line 294.
use HTTP::Response;
use IO::File;
my $response = new HTTP::Response( 404,undef,undef,"404 - Not foun
+d." );
$|=1;
my $file = new IO::File "< $path";
if (defined $file) {
$response->code( 200 );
binmode $file;
my $size = -s $file;
my ($startrange, $endrange) = (0,$size-1);
if (defined $ENV{HTTP_RANGE} and $ENV{HTTP_RANGE} =~ /bytes\s*
+=\s*(\d+)-(\d+)?/) {
$response->code( 206 );
($startrange,$endrange) = ($1,$2 || $endrange);
};
$file->seek($startrange,0);
$response->header(Content_Length => $endrange-$startrange);
$response->header(Content_Range => "bytes $startrange-$endrang
+e/$size");
$response->content( sub {
sysread($file, my ($buf), 16*1024); # No error checking ??
+?
return $buf;
});
};
print $response->decoded_content;
Another option I tried, just printing the HTTP headers and content to STDOUT, follows below. This prints the requested ranges using a Transfer-Encoding method of chunked, as described here: w3.org and here: Wiki. There are no server-side errors using this script, but the iPhone Safari client still shows a broken file.
my @ranges;
if($ENV{HTTP_RANGE} =~ s/^bytes=//i) {
@ranges = split /,/, $ENV{HTTP_RANGE};
print "Transfer-Encoding: chunked\n";
warn "printing ranges @ranges\n";
} else {
print "Content-length: $filesize\n\n";
}
if(@ranges) {
open my $fh, '<', $path;
foreach $range (@ranges) {
my($begin, $end) = split /-/, $range;
print "Content_Range: bytes $begin-$end/$filesize\
+n\n";
my $whence = ($begin)? 0 : 2;
my $position = ($begin)? $begin : 0 - $end;
seek $fh, $position, $whence;
if($end) {
$range = ($begin)? $end - $begin : $end;
my $chunk_header = sprintf("%x", $range);
print "$chunk_header\r\n";
sysread $fh, $_ , $range;
print "$_\r\n";
warn "printed range of $range bytes from $begi
+n to $end\n";
} else {
while(<$fh>) { print }
}
}
close $fh;
print "0\r\n";
} else {
open(FILE, $path) or die;
while(<FILE>) { print }
close(FILE);
}
|