You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Adriano Caloiaro <ac...@gmail.com> on 2009/06/18 16:22:46 UTC

mp2 / Apache byterange filter

Hello,

Could someone point me in the correct direction to support byte range
responses in mod_perl2?  From what I've read, Apache should understand that
it needs to apply the byterange filter whenever $r->sendfile is used on a
large file and the Range: header is present in the incoming request.
However what I'm seeing is that the entire file is returned for each byte
range requested by the client.

Access log serving off disk in Apache2:

*.*.*.* - - [17/Jun/2009:19:50:30 -0400] "GET /mygcx/test/flvplayernew17.flv
HTTP/1.1" 206 1 "-" "-"
*.*.*.* - - [17/Jun/2009:19:50:31 -0400] "GET /mygcx/test/flvplayernew17.flv
HTTP/1.1" 206 435996 "-" "-"
*.*.*.* - - [17/Jun/2009:19:50:30 -0400] "GET /mygcx/test/flvplayernew17.flv
HTTP/1.1" 206 2097152 "-" "-"

Serving from perl handler:

*.*.*.* - - [18/Jun/2009:10:11:43 -0400] "GET /mygcx/test/flvplayernew17.flv
HTTP/1.1" 200 2533148 "-" "-"
*.*.*.* - - [18/Jun/2009:10:11:45 -0400] "GET /mygcx/test/flvplayernew17.flv
HTTP/1.1" 200 2533148 "-" "-"
*.*.*.* - - [18/Jun/2009:10:11:45 -0400] "GET /mygcx/test/flvplayernew17.flv
HTTP/1.1" 200 2533148 "-" "-"


It would seem like re-invited in the wheel if I were to implement RFC 2616
in perl when there is a byterange filter already present in apache.  Thank
you for any help!

-Adrian

Re: mp2 / Apache byterange filter

Posted by Adriano Caloiaro <ac...@gmail.com>.
Hello mod_perlers,

According to the code supplied by Jeff, It appears that the only way the
byte range filter can be bypassed is when the content length is <= 0 or the
EOS is not in the brigade.  I know that my content length is not zero, as it
specifically set in my test code.  Is there a way to ensure that the EOS is
set on the brigade?  This is the test handler that is not properly
acknowledging the Range: header:

sub handler {
      my $r = shift;
      $r->content_type('video/x-flv');
      $r->set_content_length('2533148');
      $r->sendfile('/var/www/perl/tmpfiles/mygcx/flvplayernew17.flv');
      return Apache2::Const::OK;
  }

Can anyone point me in the right direction here?  Thanks.

On Thu, Jun 18, 2009 at 10:56 AM, Jeff Trawick <tr...@gmail.com> wrote:

> On Thu, Jun 18, 2009 at 10:22 AM, Adriano Caloiaro <ac...@gmail.com>wrote:
>
>> Hello,
>>
>> Could someone point me in the correct direction to support byte range
>> responses in mod_perl2?  From what I've read, Apache should understand that
>> it needs to apply the byterange filter whenever $r->sendfile is used on a
>> large file and the Range: header is present in the incoming request.
>> However what I'm seeing is that the entire file is returned for each byte
>> range requested by the client.
>>
>> Access log serving off disk in Apache2:
>>
>> *.*.*.* - - [17/Jun/2009:19:50:30 -0400] "GET
>> /mygcx/test/flvplayernew17.flv HTTP/1.1" 206 1 "-" "-"
>> *.*.*.* - - [17/Jun/2009:19:50:31 -0400] "GET
>> /mygcx/test/flvplayernew17.flv HTTP/1.1" 206 435996 "-" "-"
>> *.*.*.* - - [17/Jun/2009:19:50:30 -0400] "GET
>> /mygcx/test/flvplayernew17.flv HTTP/1.1" 206 2097152 "-" "-"
>>
>> Serving from perl handler:
>>
>> *.*.*.* - - [18/Jun/2009:10:11:43 -0400] "GET
>> /mygcx/test/flvplayernew17.flv HTTP/1.1" 200 2533148 "-" "-"
>> *.*.*.* - - [18/Jun/2009:10:11:45 -0400] "GET
>> /mygcx/test/flvplayernew17.flv HTTP/1.1" 200 2533148 "-" "-"
>> *.*.*.* - - [18/Jun/2009:10:11:45 -0400] "GET
>> /mygcx/test/flvplayernew17.flv HTTP/1.1" 200 2533148 "-" "-"
>>
>
> Maybe these checks are bypassing range processing?  (httpd 2.2.x,
> byterange_filter.c)
>
>     /* Iterate through the brigade until reaching EOS or a bucket with
>      * unknown length. */
>     for (e = APR_BRIGADE_FIRST(bb);
>          (e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e)
>           && e->length != (apr_size_t)-1);
>          e = APR_BUCKET_NEXT(e)) {
>         clength += e->length;
>     }
>
>     /* 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);
>     }
>
>
>>
>>
>> It would seem like re-invited in the wheel if I were to implement RFC 2616
>> in perl when there is a byterange filter already present in apache.  Thank
>> you for any help!
>
>
> See if these byterange requirements can be met.  (Somebody that knows more
> about mod_perl may have to check for you.  It depends on how data is passed
> to httpd.)
>
>

Re: mp2 / Apache byterange filter

Posted by Jeff Trawick <tr...@gmail.com>.
On Thu, Jun 18, 2009 at 10:22 AM, Adriano Caloiaro <ac...@gmail.com>wrote:

> Hello,
>
> Could someone point me in the correct direction to support byte range
> responses in mod_perl2?  From what I've read, Apache should understand that
> it needs to apply the byterange filter whenever $r->sendfile is used on a
> large file and the Range: header is present in the incoming request.
> However what I'm seeing is that the entire file is returned for each byte
> range requested by the client.
>
> Access log serving off disk in Apache2:
>
> *.*.*.* - - [17/Jun/2009:19:50:30 -0400] "GET
> /mygcx/test/flvplayernew17.flv HTTP/1.1" 206 1 "-" "-"
> *.*.*.* - - [17/Jun/2009:19:50:31 -0400] "GET
> /mygcx/test/flvplayernew17.flv HTTP/1.1" 206 435996 "-" "-"
> *.*.*.* - - [17/Jun/2009:19:50:30 -0400] "GET
> /mygcx/test/flvplayernew17.flv HTTP/1.1" 206 2097152 "-" "-"
>
> Serving from perl handler:
>
> *.*.*.* - - [18/Jun/2009:10:11:43 -0400] "GET
> /mygcx/test/flvplayernew17.flv HTTP/1.1" 200 2533148 "-" "-"
> *.*.*.* - - [18/Jun/2009:10:11:45 -0400] "GET
> /mygcx/test/flvplayernew17.flv HTTP/1.1" 200 2533148 "-" "-"
> *.*.*.* - - [18/Jun/2009:10:11:45 -0400] "GET
> /mygcx/test/flvplayernew17.flv HTTP/1.1" 200 2533148 "-" "-"
>

Maybe these checks are bypassing range processing?  (httpd 2.2.x,
byterange_filter.c)

    /* Iterate through the brigade until reaching EOS or a bucket with
     * unknown length. */
    for (e = APR_BRIGADE_FIRST(bb);
         (e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e)
          && e->length != (apr_size_t)-1);
         e = APR_BUCKET_NEXT(e)) {
        clength += e->length;
    }

    /* 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);
    }


>
>
> It would seem like re-invited in the wheel if I were to implement RFC 2616
> in perl when there is a byterange filter already present in apache.  Thank
> you for any help!


See if these byterange requirements can be met.  (Somebody that knows more
about mod_perl may have to check for you.  It depends on how data is passed
to httpd.)