Hi
All,
I'm writing a
connection filter handler and have started with the example underrun
filter from the mp2 doc's.
I basically want to
read all the data from the bucket brigades until I receive the EOS and then
process an entire request
(POST'ed XML Data in
my case). The Problem is that I never seem to receive the EOS
bucket! and if this never occurs
then I don't know if
the request is complete and I can't send an EOS through to the next filter so
the server blocks!
Has anyone had a
similar problem? or is there a mistake in the example? I'm too new to this to be
able to spot it if there is!
I have included the
filter I'm working with below.
Many thanks in
advance,
Greg.
P.s BTW: I'm runing apache 2.0.49 (MPM
worker), latest stable MP2, perl 5.8.3 (with threads) on solaris
8
use strict;
use warnings;
use warnings;
use base qw(Apache::Filter);
use APR::Brigade ();
use APR::Bucket ();
use APR::Brigade ();
use APR::Bucket ();
use Apache::Const -compile => qw(MODE_READBYTES
OK M_POST);
use APR::Const -compile => qw(SUCCESS BLOCK_READ);
use APR::Const -compile => qw(SUCCESS BLOCK_READ);
use Apache::Const -compile => qw(OK
M_POST);
use Apache::Connection ();
use constant TOKEN_SIZE => 300; # 300bytes
use Apache::Connection ();
use constant TOKEN_SIZE => 300; # 300bytes
sub handler : FilterConnectionHandler {
my($f, $bb, $mode, $block, $readbytes) = @_;
my $ba = $f->c->bucket_alloc;
my $ctx = $f->ctx;
my $buffer = defined $ctx ? $ctx : '';
$ctx = ''; # reset
my $seen_eos = 0;
my $data;
warn "\nfilter called\n";
my($f, $bb, $mode, $block, $readbytes) = @_;
my $ba = $f->c->bucket_alloc;
my $ctx = $f->ctx;
my $buffer = defined $ctx ? $ctx : '';
$ctx = ''; # reset
my $seen_eos = 0;
my $data;
warn "\nfilter called\n";
# fetch and consume bucket brigades untill
we have at least TOKEN_SIZE
# bytes to work with
do {
my $tbb = APR::Brigade->new($f->c->pool, $ba);
my $rv = $f->next->get_brigade($tbb, $mode, $block, $readbytes);
warn "asking for a bb\n";
($data, $seen_eos) = flatten_bb($tbb);
$tbb->destroy;
$buffer .= $data;
} while (!$seen_eos && length($buffer) < TOKEN_SIZE);
# bytes to work with
do {
my $tbb = APR::Brigade->new($f->c->pool, $ba);
my $rv = $f->next->get_brigade($tbb, $mode, $block, $readbytes);
warn "asking for a bb\n";
($data, $seen_eos) = flatten_bb($tbb);
$tbb->destroy;
$buffer .= $data;
} while (!$seen_eos && length($buffer) < TOKEN_SIZE);
# now create a bucket per chunk of
TOKEN_SIZE size and put the remainder
# in ctx
for (split_buffer($buffer)) {
if (length($_) == TOKEN_SIZE) {
$bb->insert_tail(APR::Bucket->new($_));
}
else {
$ctx .= $_;
}
}
# in ctx
for (split_buffer($buffer)) {
if (length($_) == TOKEN_SIZE) {
$bb->insert_tail(APR::Bucket->new($_));
}
else {
$ctx .= $_;
}
}
my $len = length($ctx);
if ($seen_eos) {
# flush the remainder
$bb->insert_tail(APR::Bucket->new($ctx));
$bb->insert_tail(APR::Bucket::eos_create($ba));
warn "seen eos, flushing the remaining: $len bytes\n";
}
else {
# will re-use the remainder on the next invocation
$f->ctx($ctx);
warn "storing the remainder: $len bytes\n";
}
if ($seen_eos) {
# flush the remainder
$bb->insert_tail(APR::Bucket->new($ctx));
$bb->insert_tail(APR::Bucket::eos_create($ba));
warn "seen eos, flushing the remaining: $len bytes\n";
}
else {
# will re-use the remainder on the next invocation
$f->ctx($ctx);
warn "storing the remainder: $len bytes\n";
}
return Apache::OK;
}
}
# split a string into tokens of TOKEN_SIZE bytes
and a remainder
sub split_buffer {
my $buffer = shift;
if ($] < 5.007) {
my @tokens = $buffer =~ /([EMAIL PROTECTED]|.+)/g;
return @tokens;
}
else {
# available only since 5.7.x+
return unpack "(A" . TOKEN_SIZE . ")*", $buffer;
}
}
sub split_buffer {
my $buffer = shift;
if ($] < 5.007) {
my @tokens = $buffer =~ /([EMAIL PROTECTED]|.+)/g;
return @tokens;
}
else {
# available only since 5.7.x+
return unpack "(A" . TOKEN_SIZE . ")*", $buffer;
}
}
sub flatten_bb {
my ($bb) = shift;
my ($bb) = shift;
my $seen_eos = 0;
my @data;
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
if ($b->is_eos){
$seen_eos++;
last;
warn "\n ************ SEEN EOS GB";
}
$b->read(my $bdata);
$bdata = '' unless defined $bdata;
push @data, $bdata;
}
return (join('', @data), $seen_eos);
}
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
if ($b->is_eos){
$seen_eos++;
last;
warn "\n ************ SEEN EOS GB";
}
$b->read(my $bdata);
$bdata = '' unless defined $bdata;
push @data, $bdata;
}
return (join('', @data), $seen_eos);
}
1;
Greg Balmer
Mapflow
4 Merrion
Square
Dublin 2
IRELAND
Tel: +353-1-6341430
Fax:
+353-1-6760504
E-mail: [EMAIL PROTECTED]
Check out the most recent developments on our web-site:
http://www.mapflow.com
"The information in this email is confidential and may be legally
privileged. It is intended solely for the addressee. Access to this email by
anyone else is unauthorised. If you are not the intended recipient, any
disclosure, copyright, distribution or any action taken or omitted to be taken
in reliance on it, is prohibited and may be unlawful"