Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: ModPerl: Dev

unable to handle range requests with handler

 

 

ModPerl dev RSS feed   Index | Next | Previous | View Threaded


alex at gt

May 24, 2012, 4:16 PM

Post #1 of 4 (457 views)
Permalink
unable to handle range requests with handler

Hi,

I'm running into a problem where range request support does not seem to
work as advertised. Luckily, it's easy to reproduce. =)

I'm using apache 2.2.22 and mod_perl 2.0.6, stock installs with:

PerlRequire /home/alex/modperl.pl
<Location /perl/>
SetHandler perl-script
PerlHandler VideoTest
</Location>
Alias /static/ /tmp/
<Directory /tmp/>
Allow From All
</Directory>

in my httpd.conf, and:

package VideoTest;

use Apache2::RequestIO;
sub handler {
my $r = shift;
$r->sendfile('/tmp/video.mp4');
return Apache2::Const::OK;
}

in my modperl.pl file. Place video.mp4 in /tmp, and the problem can be
seen with:

alex [at] ale ~ $ curl -s -r 0-1000 http://localhost:8001/static/video.mp4 | wc -c
1001
alex [at] ale ~ $ curl -s -r 0-1000 http://localhost:8001/perl/video.mp4 | wc -c
125569
alex [at] ale ~ $

So you can see serving via apache I get the 1001 bytes expected, but if
it goes through mod_perl handler, I get the full video.

Very similar problem described here:

http://www.gossamer-threads.com/lists/modperl/modperl/99880#99880

I dug into byterange_filter.c, and sure enough, under mod_perl we are
aborting the range request here:

/*
* Don't attempt to do byte range work if this brigade doesn't
* contain an EOS, or if any of the buckets has an unknown length;
* this avoids the cases where it is expensive to perform
* byteranging (i.e. may require arbitrary amounts of memory).
*/

if (!APR_BUCKET_IS_EOS(e) || clength <= 0) {
ap_remove_output_filter(f);
return ap_pass_brigade(f->next, bb);
}

added debug to confirm under mod_perl, clength was 125569 as expected,
and e was not EOS, so we abort. Removing the !APR_BUCKET_IS_EOS(e) test,
everything "works".

I don't understand the implications of not having an EOS bucket, or how
to set one in mod_perl (Apache::Filter has something on this, but
doesn't sound like the right direction).

Can anyone offer any insight or direction on this?

Thanks!

Alex

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


alex at gt

May 24, 2012, 6:35 PM

Post #2 of 4 (423 views)
Permalink
Re: unable to handle range requests with handler [In reply to]

Hi,

After some more digging, it looks like sendfile calls ap_send_fd, and in
Apache 2.2.22 at least, ap_send_fd doesn't set an eos bucket, so range
requests won't work.

Posted this:

http://www.gossamer-threads.com/lists/apache/dev/414631

to Apache list as if I change ap_send_fd to also send an eos bucket (as
mod_asis does), then it "works" (although just for sendfile, if you do
r->print, it doesn't work).

Just not sure if this is a proper fix, or if it's a mod_perl problem
or apache problem.

Cheers,

Alex

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


joe_schaefer at yahoo

May 24, 2012, 6:41 PM

Post #3 of 4 (423 views)
Permalink
Re: unable to handle range requests with handler [In reply to]

Largely depends on how httpd implements SSI I think- if they
use sendfile then the bucket isn't there for good reason.
Have you considered driving the output filter chain yourself,
that way *you* can put an EOS bucket on the first brigade you
build and pass to ap_pass_brigade.  That'd be the way I'd
go rather than hoping httpd includes your patch (essentially
implement ap_send_fd in perl).



----- Original Message -----
> From: Alex Krohn <alex [at] gt>
> To: dev [at] perl
> Cc:
> Sent: Thursday, May 24, 2012 9:35 PM
> Subject: Re: unable to handle range requests with handler
>
> Hi,
>
> After some more digging, it looks like sendfile calls ap_send_fd, and in
> Apache 2.2.22 at least, ap_send_fd doesn't set an eos bucket, so range
> requests won't work.
>
> Posted this:
>
>     http://www.gossamer-threads.com/lists/apache/dev/414631
>
> to Apache list as if I change ap_send_fd to also send an eos bucket (as
> mod_asis does), then it "works" (although just for sendfile, if you do
> r->print, it doesn't work).
>
> Just not sure if this is a proper fix, or if it's a mod_perl problem
> or apache problem.
>
> Cheers,
>
> Alex
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe [at] perl
> For additional commands, e-mail: dev-help [at] perl
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


alex at gt

May 25, 2012, 8:27 AM

Post #4 of 4 (421 views)
Permalink
Re: unable to handle range requests with handler [In reply to]

Hi Joe,

> Largely depends on how httpd implements SSI I think- if they
> use sendfile then the bucket isn't there for good reason.
> Have you considered driving the output filter chain yourself,
> that way *you* can put an EOS bucket on the first brigade you
> build and pass to ap_pass_brigade.  That'd be the way I'd
> go rather than hoping httpd includes your patch (essentially
> implement ap_send_fd in perl).

I don't think Apache uses ap_send_fd at all (verified by a grep), and
mentioned here:

http://www.gossamer-threads.com/lists/apache/dev/64653#64653

Also, I was certainly thrown off by docs that suggested with apache 2,
it "just worked", i.e.:

http://perl.apache.org/docs/2.0/user/porting/compat.html#C____r_E_gt_set_byterange___

and a few mailing lists posts. Once I sort this out, will put a doc
patch back to make it clear. =)

Would it be worth implementing the ap_send_fd code in xs/Apache2/RequestIO/Apache2__RequestIO.h
with the eos bucket there? I think it would be really nice if range
requests "just worked" out of the box. =)

If patching mod_perl/apache doesn't make sense (and it may not, still
not 100% about implications of having the eos bucket in ap_send_fd /
requestio sendfile, or the reason for the check for it in range requests),
can you provide a pointer on how to do this with filters?

i.e. can I do something like:

sub handler {
my $r = shift;
$r->sendfile('/tmp/video.mp4');
$r->add_output_filter(\&add_eos);
return Apache2::Const::OK;
}

sub add_eos {
my ($f, $bb) = @_;
my $ba = $bb->bucket_alloc;
my $b = APR::Bucket::eos_create($ba);
$bb->insert_tail($b);
my $rv = $f->next->pass_brigade($bb);
return $rv unless $rv == APR::Const::SUCCESS;
return Apache2::Const::OK;
}

Well, I can't as it doesn't work, but am I on the right track? =)

Cheers,

Alex


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl

ModPerl dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.