Hi all,
I am having issues with the sendfile command in mod_per2. I am getting the following errors in the error_log:
[Thu Mar 24 11:38:50 2011] [info] [client 10.199.122.122] (32)Broken pipe: core_output_filter: writing data to the network
[Thu Mar 24 11:38:50 2011] [error] [client 10.199.122.122] Apache2::RequestIO::sendfile: (130) Software caused connection abort.
Here is code for my perl module:
package Ranges;
use strict;
use warnings;
use Apache2::Const qw(OK NOT_FOUND HTTP_PARTIAL_CONTENT);
use File::Basename;
use Data::Dumper;
sub send_pkgitem {
my ($r) = @_;
my $fh = "/tmp/test.pdf"
my $attach_name = basename($fh);
my $content_size = -s $fh;
my $start_range = 0;
my $end_range = $content_size - 1;
my $range = "$start_range"."-"."$end_range".'/'."$content_size";
$r->headers_out->set('Accept-Ranges' => 'bytes'); #causes a server 500 response error when set..
$r->set_content_length(-s $pkgitem->{real_path});
$r->headers_out->set('Content-Range' => "$range");
$r->headers_out->set('Content-Disposition' => "inline; filename=\"$attach_name\"");
$r->set_last_modified;
$r->content_type($pkgitem->{mimetype});
warn "HEADERS_OUT Dumper:\n";
warn Dumper($r->headers_out);
unless ((my $status = $r->meets_conditions) == OK) {
return $status;
}
return OK if $r->header_only;
warn "HEADERS_IN dumper:\n";
warn Dumper($r->headers_in);
warn "range request = $range\n";
warn "content_size = $content_size, end_range = $end_range\n";
my $bytes_total = $end_range;
my $buff_size = 65536;
my $buff_len = $buff_size;
warn "bytes_total = $bytes_total\n";
if ($content_size < $buff_len)
{ $r->sendfile($fh); }
else #process range request
{
warn "RANGE BLOCK:\n";
my $offset = 0;
my $totalbytes_sent = 0;
while ($totalbytes_sent <= $end_range)
{
warn "sendfile -> $fh,$offset,$buff_len\n";
$r->sendfile($fh,$offset,$buff_len);
last if ($bytes_total <= 0);
$bytes_total -= $buff_len;
$buff_len = $bytes_total,$bytes_total = 0 if $buff_len > $bytes_total;
$totalbytes_sent += $buff_len;
if ($bytes_total == 0)
{ $offset += $buff_size; }
else
{ $offset = $totalbytes_sent; }
warn "bytes_total = $bytes_total, totalbytes_sent = $totalbytes_sent\n";
}
}
return OK;
}
1;
***** OUTPUT FROM error_log file *****
content_type = application/pdf
HEADERS_OUT Dumper:
$VAR1 = bless( {
'Accept-Ranges' => 'bytes',
'Content-Length' => '751711',
'Content-Range' => '0-751710/751711',
'Content-Disposition' => 'inline; filename="test.pdf"',
'Last-Modified' => 'Sun, 25 Jan 2009 19:56:38 GMT'
}, 'APR::Table' );
HEADERS_IN dumper:
$VAR1 = bless( {
'Host' => '10.199.122.122',
'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language' => 'en-us,en;q=0.5',
'Accept-Encoding' => 'gzip,deflate',
'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Keep-Alive' => '115',
'Connection' => 'keep-alive',
'Referer' => ''
}, 'APR::Table' );
range request = 0-751710/751711
content_size = 751711, end_range = 751710
bytes_total = 751710
sendfile -> /tmp/test.pdf,0,65536
bytes_total = 686174, totalbytes_sent = 65536
sendfile -> /tmp/test.pdf,65536,65536
[Thu Mar 24 11:38:50 2011] [info] [client 10.199.122.122] (32)Broken pipe: core_output_filter: writing data to the network
[Thu Mar 24 11:38:50 2011] [error] [client 10.199.122.122] Apache2::RequestIO::sendfile: (130) Software caused connection abort.
content_type = application/pdf
HEADERS_OUT Dumper:
$VAR1 = bless( {
'Accept-Ranges' => 'bytes',
'Content-Length' => '751711',
'Content-Range' => '0-751710/751711',
'Content-Disposition' => 'inline; filename="test.pdf"',
'Last-Modified' => 'Sun, 25 Jan 2009 19:56:38 GMT'
}, 'APR::Table' );
HEADERS_IN dumper:
$VAR1 = bless( {
'Host' => '10.199.122.122',
'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language' => 'en-us,en;q=0.5',
'Accept-Encoding' => 'gzip,deflate',
'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Keep-Alive' => '115',
'Connection' => 'keep-alive',
'Range' => 'bytes=1-1,750984-751710'
}, 'APR::Table' );
range request = 0-751710/751711
content_size = 751711, end_range = 751710
bytes_total = 751710
sendfile -> /tmp/test.pdf,0,65536
bytes_total = 686174, totalbytes_sent = 65536
sendfile -> /tmp/test.pdf,65536,65536
bytes_total = 620638, totalbytes_sent = 131072
sendfile -> /tmp/test.pdf,131072,65536
bytes_total = 555102, totalbytes_sent = 196608
sendfile -> /tmp/test.pdf,196608,65536
bytes_total = 489566, totalbytes_sent = 262144
sendfile -> /tmp/test.pdf,262144,65536
bytes_total = 424030, totalbytes_sent = 327680
sendfile -> /tmp/test.pdf,327680,65536
bytes_total = 358494, totalbytes_sent = 393216
sendfile -> /tmp/test.pdf,393216,65536
bytes_total = 292958, totalbytes_sent = 458752
sendfile -> /tmp/test.pdf,458752,65536
bytes_total = 227422, totalbytes_sent = 524288
sendfile -> /tmp/test.pdf,524288,65536
bytes_total = 161886, totalbytes_sent = 589824
sendfile -> /tmp/test.pdf,589824,65536
bytes_total = 96350, totalbytes_sent = 655360
sendfile -> /tmp/test.pdf,655360,65536
bytes_total = 0, totalbytes_sent = 686174
sendfile -> /tmp/test.pdf,720896,30814
In the access_log, the 1st attempt returned a 500 response then the next response was a 200 response.
I am able to view the PDF file just fine but I have to wait until it's fully downloaded before I can view it. My objective is to return a
206 response rather than a 200 response. I am not sure whether it's a mistake in the headers or the way I am calling sendfile.
Thanks for any replies!!