Apache2-CondProxy
view release on metacpan or search on metacpan
lib/Apache2/CondProxy.pm view on Meta::CPAN
use APR::Const -compile => qw(:common ENOTIMPL OVERLAP_TABLES_SET);
use Path::Class ();
use File::Spec ();
use File::Temp ();
use URI ();
use URI::Escape ();
# constants for pnotes
use constant BRIGADE => __PACKAGE__ . '::BRIGADE';
use constant INPUT => __PACKAGE__ . '::INPUT';
use constant CACHE => __PACKAGE__ . '::CACHE';
my $TRUE = qr/^\s*(1|true|on|yes)\s*$/i;
BEGIN {
# Stopgap implementation of ap_save_brigade. This is almost
# exactly what the C version looks like in server/util_filter.c.
unless (Apache2::Filter->can('save_brigade')) {
*Apache2::Filter::save_brigade = sub {
my ($f, $saveto, $bb, $pool) = @_;
lib/Apache2/CondProxy.pm view on Meta::CPAN
This is the prefix of the location where requests go when they can't
be served by the site where the request was originated. Note the path
of the original request is appended I<relative> to the path of this
URI, as if its initial C</> was pruned off, so craft this URI
accordingly.
=head2 RequestBodyCache
RequestBodyCache /tmp/cond-proxy
In order to work with request content (e.g. C<POST>, C<PUT>), we have
to stash it somewhere so we can replay it into the pipe. This means
the contents of this directory are potentially sensitive. So if you're
going to put it in C</tmp>, make sure to at least make it only
readable to the server. Or you can have this module do that
automatically, just make sure it can write to the parent.
=head2 MatchScheme
MatchScheme on
lib/Apache2/CondProxy.pm view on Meta::CPAN
}
sub _response_handler {
my $r = shift;
#$r->log->debug('lol response handler');
Apache2::Const::OK;
}
sub _cleanup_handler {
my $r = shift;
if (my $xx = $r->pnotes(INPUT)) {
$r->log->debug
('Unlinking temporary file in case it is still sticking around');
unlink($xx->[0]);
}
Apache2::Const::OK;
}
sub _input_filter_tee {
my ($f, $bb, $mode, $block, $readbytes) = @_;
my $c = $f->c;
lib/Apache2/CondProxy.pm view on Meta::CPAN
my $in = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $rv = $f->next->get_brigade($in, $mode, $block, $readbytes);
return $rv unless $rv == APR::Const::SUCCESS;
# only open the tempfile if there is something to put in it
unless ($in->is_empty) {
# deal with tempfile
my $fh;
my $xx = $mainr->pnotes(INPUT);
if ($xx) {
$fh = $xx->[1];
}
else {
# unfortunately something does not like the preemptive unlink
my $dir = $mainr->pnotes(CACHE);
my $fn;
eval { ($fh, $fn) = $dir->tempfile(OPEN => 1, UNLINK => 0) };
if ($@) {
$r->log->crit("Could not create temporary file in $dir: $@");
return Apache2::Const::SERVER_ERROR;
}
$fh->binmode;
# also yes I know this is the reverse of what File::Temp returns
$mainr->pnotes(INPUT, [$fn, $fh]);
}
for (my $b = $in->first; $b; $b = $in->next($b)) {
if ($b->is_eos) {
# flush the temp file and seek it to zero
$fh->flush;
$fh->seek(0, 0);
}
elsif (my $len = $b->read(my $data)) {
$fh->write($data);
lib/Apache2/CondProxy.pm view on Meta::CPAN
}
# it kinda sucks there's no way to make file buckets in mod_perl
# because this would probably be way more efficient to stick the fd in
# a bucket than read the file out in perl.
sub _input_filter_replay {
my ($f, $bb, $mode, $block, $readbytes) = @_;
my $c = $f->c;
my $r = $f->r;
my $xx = $r->pnotes(INPUT) or return Apache2::Const::DECLINED;
my ($fn, $fh) = @$xx;
$r->log->debug('Replaying input into proxy request');
# XXX do i even have to do this?
my $in = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $rv = $f->next->get_brigade($in, $mode, $block, $readbytes);
return $rv unless $rv == APR::Const::SUCCESS;
# whatever is in it, empty it
( run in 0.478 second using v1.01-cache-2.11-cpan-c6e0e5ac2a7 )