view release on metacpan or search on metacpan
Apache::RequestIO: print(), printf(), puts(), write(), rflush() throw
an exception on failure [Stas]
Apache::SubRequest: run() throw an exception on failure [Stas]
Apache::Filter: [Stas]
- remove unneeded methods: remove_input_filter() and
remove_output_filter(), fputs()
- frec() accessor is made read-only
- fflush(), get_brigade() and pass_brigade() now throw exceptions if
called in the void context
- read, print() and puts() throw an exception on failure
Apache::FilterRec: [Stas]
- remove the next() accessor since it's not used by Apache at the
moment
- name() is made read-only
APR::URI: [Stas]
- removed accessors
docs/api/Apache2/Const.pod view on Meta::CPAN
=head2 C<:input_mode>
use Apache2::Const -compile => qw(:input_mode);
The C<:input_mode> group is used by
C<L<get_brigade|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head3 C<Apache2::Const::MODE_EATCRLF>
=over
=item since: 2.0.00
=back
See
C<L<Apache2::Filter::get_brigade()|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head3 C<Apache2::Const::MODE_EXHAUSTIVE>
=over
=item since: 2.0.00
=back
See
C<L<Apache2::Filter::get_brigade()|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head3 C<Apache2::Const::MODE_GETLINE>
=over
=item since: 2.0.00
=back
See
C<L<Apache2::Filter::get_brigade()|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head3 C<Apache2::Const::MODE_INIT>
=over
=item since: 2.0.00
=back
See
C<L<Apache2::Filter::get_brigade()|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head3 C<Apache2::Const::MODE_READBYTES>
=over
=item since: 2.0.00
=back
See
C<L<Apache2::Filter::get_brigade()|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head3 C<Apache2::Const::MODE_SPECULATIVE>
=over
=item since: 2.0.00
=back
See
C<L<Apache2::Filter::get_brigade()|docs::2.0::api::Apache2::Filter/C_get_brigade_>>.
=head2 C<:log>
docs/api/Apache2/Filter.pod view on Meta::CPAN
# filter attributes
my $c = $f->c;
my $r = $f->r;
my $frec = $f->frec();
my $next_f = $f->next;
my $ctx = $f->ctx;
$f->ctx($ctx);
# bucket brigade filtering API
$rc = $f->next->get_brigade($bb, $mode, $block, $readbytes);
$rc = $f->next->pass_brigade($bb);
$rc = $f->fflush($bb);
# streaming filtering API
while ($filter->read(my $buffer, $wanted)) {
# transform $buffer here
$filter->print($buffer);
}
if ($f->seen_eos) {
$filter->print("filter signature");
docs/user/handlers/filters.pod view on Meta::CPAN
package MyApache2::FilterTransparent;
use Apache2::Filter ();
use Apache2::Const -compile => qw(OK);
use APR::Const -compile => ':common';
sub in {
my ($f, $bb, $mode, $block, $readbytes) = @_;
my $rv = $f->next->get_brigade($bb, $mode, $block, $readbytes);
return $rv unless $rv == APR::Const::SUCCESS;
return Apache2::Const::OK;
}
When the input filter I<in()> is invoked, it first asks the upstream
filter for the next bucket brigade (using the C<get_brigade()>
call). That upstream filter is in turn going to ask for the bucket
brigade from the next upstream filter and so on up the chain, until
the last filter (called C<core_in>), the one that reads from the
network, is reached. The C<core_in> filter reads, using a socket, a
portion of the incoming data from the network, processes it, and sends
it to its downstream filter. That filter processes the data and send
it to its downstream filter, etc., until it reaches the first filter
that requested the data. (In reality some other handler triggers the
request for the bucket brigade, such as an HTTP response handler or a
protocol module, but for this discussion it's sufficient to assume
that it's the first filter that issues the C<get_brigade()> call.)
The following diagram depicts a typical input filter data flow
in addition to the program control flow.
=for html
<img src="in_filter_stream.gif" width="659" height="275"
align="middle" alt="input filter data flow"><br><br>
The black- and white-headed arrows show when the control is passed
from one filter to another. In addition, the black-headed arrows show
the actual data flow. The diagram includes some pseudo-code, in Perl
for the mod_perl filters and in C for the internal Apache filters. You
don't have to understand C to understand this diagram. What's
important to understand is that when input filters are invoked, they
first call each other via the C<get_brigade()> call and then block
(notice the brick wall on the diagram), waiting for the call to
return. When this call returns, all upstream filters have already
completed their filtering task on the bucket brigade.
As mentioned earlier, the streaming interface hides the details,
but the first C<$f-E<gt>read()> call will block as the layer under it
performs the C<get_brigade()> call.
The diagram shows only part of the actual input filter chain for an
HTTP request. The C<...> indicates that there are more filters in
between the mod_perl filter and C<http_in>.
Now let's look at what happens in the output filters chain. Here the
first filter acquires the bucket brigades containing the response data
from the content handler (or another protocol handler if we aren't
talking HTTP). It may then make some modification and pass the data to
the next filter (using the C<pass_brigade()> call), which in turn
docs/user/handlers/protocols.pod view on Meta::CPAN
sub handler {
my $c = shift;
$c->client_socket->opt_set(APR::Const::SO_NONBLOCK => 0);
my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $last = 0;
while (1) {
my $rc = $c->input_filters->get_brigade($bb_in,
Apache2::Const::MODE_GETLINE);
last if APR::Status::is_EOF($rc);
die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
while (!$bb_in->is_empty) {
my $b = $bb_in->first;
$b->remove;
if ($b->is_eos) {
lib/Apache2/compat.pm view on Meta::CPAN
sub content {
my $r = shift;
my $bb = APR::Brigade->new($r->pool,
$r->connection->bucket_alloc);
my $data = '';
my $seen_eos = 0;
do {
$r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
APR::Const::BLOCK_READ, IOBUFSIZE);
while (!$bb->is_empty) {
my $b = $bb->first;
if ($b->is_eos) {
$seen_eos++;
last;
}
if ($b->read(my $buf)) {
lib/ModPerl/MethodLookup.pm view on Meta::CPAN
'APR::Table',
undef
]
],
'get_basic_auth_pw' => [
[
'Apache2::Access',
undef
]
],
'get_brigade' => [
[
'Apache2::Filter',
'Apache2::Filter'
]
],
'get_client_block' => [
[
'Apache2::RequestIO',
'Apache2::RequestRec'
]
src/modules/perl/modperl_filter.c view on Meta::CPAN
apr_size_t len = 0;
if (!filter->bb_in) {
/* This should be read only once per handler invocation! */
filter->bb_in = apr_brigade_create(filter->pool,
filter->f->c->bucket_alloc);
MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
"retrieving bb: 0x%lx",
MP_FILTER_NAME(filter->f),
(unsigned long)(filter->bb_in));
MP_RUN_CROAK(ap_get_brigade(filter->f->next, filter->bb_in,
filter->input_mode, filter->block,
filter->readbytes),
"Apache2::Filter::read");
}
len = modperl_filter_read(aTHX_ filter, buffer, wanted);
if (filter->flush && len == 0) {
/* if len > 0 then $filter->write will flush */
apr_status_t rc = modperl_input_filter_flush(filter);
t/filter/TestFilter/both_str_con_add.pm view on Meta::CPAN
sub handler {
my Apache2::Connection $c = shift;
# starting from Apache 2.0.49 several platforms require you to set
# the socket to a blocking IO mode
$c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
for (;;) {
$c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE);
last if $bb->is_empty;
my $b = APR::Bucket::flush_create($c->bucket_alloc);
$bb->insert_tail($b);
$c->output_filters->pass_brigade($bb);
# fflush is the equivalent of the previous 3 lines of code:
# but it's tested elsewhere, here testing flush_create
# $c->output_filters->fflush($bb);
}
t/filter/TestFilter/in_bbs_body.pm view on Meta::CPAN
use APR::Bucket ();
use TestCommon::Utils ();
use Apache2::Const -compile => qw(OK M_POST);
use APR::Const -compile => ':common';
sub handler : FilterRequestHandler {
my ($filter, $bb, $mode, $block, $readbytes) = @_;
$filter->next->get_brigade($bb, $mode, $block, $readbytes);
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
last if $b->is_eos;
if ($b->read(my $data)) {
#warn"[$data]\n";
my $nb = APR::Bucket->new($bb->bucket_alloc, scalar reverse $data);
$b->insert_before($nb);
$b->delete;
t/filter/TestFilter/in_bbs_consume.pm view on Meta::CPAN
sub handler {
my ($filter, $bb, $mode, $block, $readbytes) = @_;
my $ba = $filter->r->connection->bucket_alloc;
my $seen_eos = 0;
my $satisfied = 0;
my $buffer = '';
debug_sub "filter called";
until ($satisfied) {
my $tbb = APR::Brigade->new($filter->r->pool, $ba);
$filter->next->get_brigade($tbb, $mode, $block, READ_SIZE);
debug "asking for a bb of " . READ_SIZE . " bytes\n";
my $data;
($data, $seen_eos) = bb_data_n_eos($tbb);
$tbb->destroy;
$buffer .= $data;
length($buffer) < READ_SIZE ? redo : $satisfied++;
}
# consume all the remaining input
do {
my $tbb = APR::Brigade->new($filter->r->pool, $ba);
$filter->next->get_brigade($tbb, $mode, $block, $readbytes);
debug "discarding the next bb";
$seen_eos = bb_data_n_eos($tbb, 1); # only scan
$tbb->destroy;
} while (!$seen_eos);
if ($seen_eos) {
# flush the remainder
$bb->insert_tail(APR::Bucket->new($ba, $buffer));
$bb->insert_tail(APR::Bucket::eos_create($ba));
debug "seen eos, sending: " . length($buffer) . " bytes";
t/filter/TestFilter/in_bbs_inject_header.pm view on Meta::CPAN
# the brigade unmodified
debug "passing the body through unmodified";
return Apache2::Const::DECLINED;
}
# any custom HTTP header buckets to inject?
return Apache2::Const::OK if inject_header_bucket($bb, $ctx);
# normal HTTP headers processing
my $ctx_bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $rv = $filter->next->get_brigade($ctx_bb, $mode, $block, $readbytes);
return $rv unless $rv == APR::Const::SUCCESS;
while (!$ctx_bb->is_empty) {
my $b = $ctx_bb->first;
if ($b->is_eos) {
debug "EOS!!!";
$b->remove;
$bb->insert_tail($b);
last;
t/filter/TestFilter/in_bbs_underrun.pm view on Meta::CPAN
my $buffer = defined $ctx ? $ctx : '';
$ctx = ''; # reset
my $seen_eos = 0;
my $data;
debug_sub "filter called";
# fetch and consume bucket brigades untill we have at least SIZE
# bytes to work with
do {
my $tbb = APR::Brigade->new($filter->r->pool, $ba);
$filter->next->get_brigade($tbb, $mode, $block, $readbytes);
debug "asking for a bb";
($data, $seen_eos) = flatten_bb($tbb);
$tbb->destroy;
$buffer .= $data;
} while (!$seen_eos && length($buffer) < SIZE);
# now create a bucket per chunk of SIZE size and put the remainder
# in ctx
for (split_buffer($buffer)) {
if (length($_) == SIZE) {
t/filter/TestFilter/in_init_basic.pm view on Meta::CPAN
sub transparent : FilterRequestHandler
FilterHasInitHandler(\&transparent_init)
{
my ($filter, $bb, $mode, $block, $readbytes) = @_;
my $ctx = $filter->ctx;
$ctx->{run}++;
$filter->r->notes->set(run => $ctx->{run});
$filter->ctx($ctx);
$filter->next->get_brigade($bb, $mode, $block, $readbytes);
return Apache2::Const::OK;
}
# this filter is not supposed to get a chance to run, since its init
# handler immediately removes it
sub suicide_init : FilterInitHandler { shift->remove(); Apache2::Const::OK }
sub suicide : FilterHasInitHandler(\&suicide_init) {
t/lib/TestCommon/FilterDebug.pm view on Meta::CPAN
sub snoop {
my $type = shift;
my ($filter, $bb, $mode, $block, $readbytes) = @_; # filter args
# $mode, $block, $readbytes are passed only for input filters
my $stream = defined $mode ? "input" : "output";
# read the data and pass-through the bucket brigades unchanged
if (defined $mode) {
# input filter
my $rv = $filter->next->get_brigade($bb, $mode, $block, $readbytes);
return $rv unless $rv == APR::Const::SUCCESS;
bb_dump($type, $stream, $bb);
}
else {
# output filter
bb_dump($type, $stream, $bb);
my $rv = $filter->next->pass_brigade($bb);
return $rv unless $rv == APR::Const::SUCCESS;
}
#if ($bb->is_empty) {
t/lib/TestCommon/Utils.pm view on Meta::CPAN
my $r = shift;
my $debug = shift || 0;
my $bb = APR::Brigade->new($r->pool,
$r->connection->bucket_alloc);
my $data = '';
my $seen_eos = 0;
my $count = 0;
do {
$r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
APR::Const::BLOCK_READ, IOBUFSIZE);
$count++;
warn "read_post: bb $count\n" if $debug;
while (!$bb->is_empty) {
my $b = $bb->first;
if ($b->is_eos) {
t/protocol/TestProtocol/echo_bbs.pm view on Meta::CPAN
my $c = shift;
# starting from Apache 2.0.49 several platforms require you to set
# the socket to a blocking IO mode
$c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
while (1) {
debug "asking new line";
my $rc = $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE);
last if APR::Status::is_EOF($rc);
die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
last if $b->is_eos;
debug "processing new line";
if ($b->read(my $data)) {
t/protocol/TestProtocol/echo_bbs2.pm view on Meta::CPAN
# starting from Apache 2.0.49 several platforms require you to set
# the socket to a blocking IO mode
$c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $last = 0;
while (1) {
my $rc = $c->input_filters->get_brigade($bb_in,
Apache2::Const::MODE_GETLINE);
last if APR::Status::is_EOF($rc);
die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
next unless $bb_in->flatten(my $data);
#warn "read: [$data]\n";
last if $data =~ /^[\r\n]+$/;
# transform data here
my $bucket = APR::Bucket->new($bb_in->bucket_alloc, uc $data);
t/protocol/TestProtocol/echo_filter.pm view on Meta::CPAN
sub handler {
my $c = shift;
# starting from Apache 2.0.49 several platforms require you to set
# the socket to a blocking IO mode
$c->client_socket->opt_set(APR::Const::SO_NONBLOCK, 0);
my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
while (1) {
my $rc = $c->input_filters->get_brigade($bb, Apache2::Const::MODE_GETLINE);
last if APR::Status::is_EOF($rc);
die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS;
# fflush is the equivalent of the following 3 lines of code:
#
# my $b = APR::Bucket::flush_create($c->bucket_alloc);
# $bb->insert_tail($b);
# $c->output_filters->pass_brigade($bb);
$c->output_filters->fflush($bb);
}
t/response/TestAPI/in_out_filters.pm view on Meta::CPAN
sub read_request_body {
my $r = shift;
my $bb = APR::Brigade->new($r->pool,
$r->connection->bucket_alloc);
my $data = '';
my $seen_eos = 0;
my $count = 0;
do {
$r->input_filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
APR::Const::BLOCK_READ, IOBUFSIZE);
$count++;
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
if ($b->is_eos) {
$seen_eos++;
last;
}
t/response/TestApache/discard_rbody.pm view on Meta::CPAN
if ($test eq 'none') {
# don't read the request body
}
elsif ($test eq 'partial') {
# read some of request POSTed data (IOBUFSIZE bytes),
# but not all of it
my $filters = $r->input_filters();
my $ba = $r->connection->bucket_alloc;
my $bb = APR::Brigade->new($r->pool, $ba);
$filters->get_brigade($bb, Apache2::Const::MODE_READBYTES,
APR::Const::BLOCK_READ, IOBUFSIZE);
}
elsif ($test eq 'all') {
# consume all of the request body
my $data = TestCommon::Utils::read_post($r);
die "failed to consume all the data" unless length($data) == 100000;
}
# now get rid of the rest of the input data should work, no matter
# how little or how much of the body was read
xs/APR/Brigade/APR__Brigade.h view on Meta::CPAN
SV *mpxs_apr_brigade_create(pTHX_ SV *CLASS, SV *p_sv,
apr_bucket_alloc_t *ba)
{
apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
apr_bucket_brigade *bb = apr_brigade_create(p, ba);
SV *bb_sv = sv_setref_pv(newSV(0), "APR::Brigade", (void*)bb);
mpxs_add_pool_magic(bb_sv, p_sv);
return bb_sv;
}
#define get_brigade(brigade, fetch) \
(fetch(brigade) == APR_BRIGADE_SENTINEL(brigade) ? \
NULL : fetch(brigade))
static MP_INLINE
apr_bucket *mpxs_APR__Brigade_first(apr_bucket_brigade *brigade)
{
return get_brigade(brigade, APR_BRIGADE_FIRST);
}
static MP_INLINE
apr_bucket *mpxs_APR__Brigade_last(apr_bucket_brigade *brigade)
{
return get_brigade(brigade, APR_BRIGADE_LAST);
}
#define get_bucket(brigade, bucket, fetch) \
(fetch(bucket) == APR_BRIGADE_SENTINEL(brigade) ? \
NULL : fetch(bucket))
static MP_INLINE
apr_bucket *mpxs_APR__Brigade_next(apr_bucket_brigade *brigade,
apr_bucket *bucket)
{
xs/Apache2/Filter/Apache2__Filter.h view on Meta::CPAN
/* if users don't bother to check the success, do it on their
* behalf */
if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
modperl_croak(aTHX_ rc, "Apache2::Filter::fflush");
}
return rc;
}
static MP_INLINE
apr_status_t mpxs_Apache2__Filter_get_brigade(pTHX_
ap_filter_t *f,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t readbytes)
{
apr_status_t rc = ap_get_brigade(f, bb, mode, block, readbytes);
/* if users don't bother to check the success, do it on their
* behalf */
if (GIMME_V == G_VOID && rc != APR_SUCCESS) {
modperl_croak(aTHX_ rc, "Apache2::Filter::get_brigade");
}
return rc;
}
static MP_INLINE
apr_status_t mpxs_Apache2__Filter_pass_brigade(pTHX_ ap_filter_t *f,
apr_bucket_brigade *bb)
{
apr_status_t rc = ap_pass_brigade(f, bb);
xs/maps/apache2_functions.map view on Meta::CPAN
>ap_process_config_tree
MODULE=Apache2::Filter PACKAGE=guess
~ap_add_output_filter
~ap_add_input_filter
-ap_add_input_filter_handle
-ap_get_input_filter_handle
-ap_add_output_filter_handle
-ap_get_output_filter_handle
>ap_add_ouput_filters_by_type
~ap_get_brigade
mpxs_Apache2__Filter_get_brigade | | \
f, bb, mode=AP_MODE_READBYTES, \
block=APR_BLOCK_READ, \
readbytes=8192
~ap_pass_brigade
mpxs_Apache2__Filter_pass_brigade
!ap_register_input_filter
!ap_register_output_filter
-ap_remove_output_filter
-ap_remove_input_filter
!ap_save_brigade
xs/tables/current/Apache2/FunctionTable.pm view on Meta::CPAN
'name' => 'r'
},
{
'type' => 'const char **',
'name' => 'pw'
}
]
},
{
'return_type' => 'apr_status_t',
'name' => 'ap_get_brigade',
'args' => [
{
'type' => 'ap_filter_t *',
'name' => 'filter'
},
{
'type' => 'apr_bucket_brigade *',
'name' => 'bucket'
},
{
view all matches for this distributionview release on metacpan - search on metacpan