Has anyone had experience of using mod_perl OutputFilters with
mod_deflate, I've been banging my head against a brick wall today....
I've learnt a lot about bucket brigades - but for every two steps
forward it's one step back...
Scenario:
static page - being wrapped with an output filter - works with or
without mod_deflate
dynamic page - either Perl or PHP, without mod_deflate the output of
the page gets re-processed and the correct HTML is produced, but with
mod_deflate the content returned is the unwrapped output (i.e. the
output before the output filter has been actioned?)
any ideas or ways to resolve this...
below is my code....
package Sanger::Web::DecoratePage;
use strict;
use warnings;
no warnings qw(uninitialized);
use base qw(Apache2::Filter);
use Apache2::RequestRec ();
use APR::Table ();
use APR::Bucket ();
use APR::Brigade ();
use Apache2::Connection ();
use Apache2::Const -compile => qw(OK DECLINED CONN_KEEPALIVE);
use APR::Const -compile => ':common';
use constant LENGTH => 2048;
sub decorate_page {
my $content = shift;
my $title = $content =~ /<title>(.*)<\/title>/s ? $1 : "untitled
document";
my $body = $content =~ /<body>(.*)<\/body>/s ? $1 : $content;
return qq(<html>
<head>
<title>Wellcome Trust Sanger Institute: $title</title></head>
<body>
<h1>Wellcome Trust Sanger Institute:</h1>
<hr />
$body
<hr />
Footer content....
</body>
</html>
);
}
sub handler : FilterRequestHandler {
my ($filter, $bb) = @_;
my $bb_ctx = APR::Brigade->new($filter->c->pool,
$filter->c->bucket_alloc);
my $t = $filter->r->headers_in();
return Apache2::Const::DECLINED unless $filter->r->status == 200;
warn "\n";
warn "\n";
warn ".. handler [[\n";
foreach my $key (keys %$t) {
warn sprintf " %40s = %s\n", $key, $t->{$key};
}
warn "]]\n";
my $ctx = context( $filter );
# pass through unmodified
return Apache2::Const::DECLINED if $ctx->{state};
my $data = exists $ctx->{data} ? $ctx->{data} : '';
$ctx->{invoked}++;
my( $bdata, $seen_eos, $beos ) = flatten_bb($bb);
$data .= $bdata if $bdata;
if ($seen_eos) {
$data = decorate_page( $data );
my $len = length $data;
$filter->r->headers_out->set('Content-Length', $len);
$filter->r->headers_out->set('Filter-Actioned',
'Sanger::Web::DecoratePage' );
$filter->r->content_type( "text/html" );
if( $data ) {
while( $data ) {
my $x = substr($data,0,LENGTH);
substr($data,0,LENGTH) = '';
warn sprintf "inserting bucket .... %4d :
%10s...%10s",length($x),substr( $x,0,10),substr($x,-10,10);
my $b = APR::Bucket->new( $bb->bucket_alloc, " $x" );
$bb_ctx->insert_tail($b);
}
}
$bb_ctx->insert_tail( $beos );
warn "
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (length $len)
\n" if 0;
$ctx->{state}++
} else {
warn "... store ...";
# store context for all but the last invocation
$ctx->{data} = $data;
$filter->ctx($ctx);
}
$t = $filter->r->headers_out();
warn "\n\n.. [[\n";
foreach my $key (keys %$t) {
warn sprintf " %40s = %s\n", $key, $t->{$key};
}
warn "]]\n";
warn "\n";
warn "end of handler....\n";
warn "\n";
my $rv = $filter->next->pass_brigade($bb_ctx);
return $rv unless $rv == APR::Const::SUCCESS;
return Apache2::Const::OK;
}
sub flatten_bb {
my $bb = shift;
my $seen_eos = 0;
my @data;
my $b = $bb->first;
while( $b ) {
$b->remove;
if($b->is_eos) {
$seen_eos++;
last
}
$b->read(my $bdata);
push @data, $bdata;
$b = $bb->next( $b );
}
return (join('', @data), $seen_eos, $b );
}
sub context {
my ($f) = shift;
my $ctx = $f->ctx;
warn "... $ctx ...";
warn $f->c->keepalive,"; ",Apache2::Const::CONN_KEEPALIVE,";
",$f->c->keepalives;
unless ($ctx) {
$ctx = {
state => 0,
keepalives => $f->c->keepalives,
};
use Data::Dumper;
warn Data::Dumper::Dumper( $ctx );
$f->ctx($ctx);
return $ctx;
}
my $c = $f->c;
if(
$c->keepalive == Apache2::Const::CONN_KEEPALIVE &&
$ctx->{state} &&
$c->keepalives > $ctx->{keepalives}
) {
$ctx->{state} = 0;
$ctx->{keepalives} = $c->keepalives;
}
return $ctx;
}
1;
--
The Wellcome Trust Sanger Institute is operated by Genome Research
Limited, a charity registered in England with number 1021457 and a
company registered in England with number 2742969, whose registered
office is 215 Euston Road, London, NW1 2BE.