GoferTransport-http
view release on metacpan or search on metacpan
lib/DBI/Gofer/Transport/mod_perl.pm view on Meta::CPAN
use constant MP2 => ( ($ENV{MOD_PERL_API_VERSION}||0) >= 2 or eval "require Apache2::Const");
BEGIN {
if (MP2) {
require Apache2::Connection;
require Apache2::RequestIO;
require Apache2::RequestRec;
require Apache2::RequestUtil;
require Apache2::Response;
require Apache2::Const;
Apache2::Const->import(qw(OK DECLINED SERVER_ERROR));
require APR::Base64;
*encode_base64 = \&APR::Base64::encode;
*decode_base64 = \&APR::Base64::decode;
*escape_html = sub {
my $s = shift;
$s =~ s/&/&/g;
$s =~ s/</</g;
$s =~ s/>/>/g;
return $s;
}
}
else {
require Apache::Constants;
Apache::Constants->import(qw(OK DECLINED SERVER_ERROR));
require Apache::Util;
Apache::Util->import(qw(escape_html));
require MIME::Base64;
MIME::Base64->import(qw(encode_base64 decode_base64));
}
}
use DBI::Gofer::Serializer::DataDumper;
use base qw(DBI::Gofer::Transport::Base);
our $transport = __PACKAGE__->new();
our %executor_configs = ( default => { } );
our %executor_cache;
our $show_client_hostname_in_status = 1;
our $datadumper_serializer = DBI::Gofer::Serializer::DataDumper->new;
_install_apache_status_menu_items(
DBI_gofer => [ 'DBI Gofer', \&_apache_status_dbi_gofer ],
);
sub handler : method {
my $self = shift;
my $r = shift;
my $time_received = dbi_time();
my $headers_in = $r->headers_in;
my ($frozen_request, $request, $request_serializer);
my ($frozen_response, $response, $response_serializer);
my $executor;
my $http_status = SERVER_ERROR;
my $remote_ip = $headers_in->{Client_ip} # e.g., cisco load balancer
|| $headers_in->{'X-Forwarded-For'} # e.g., mod_proxy (XXX may contain more than one ip)
|| $r->connection->remote_ip;
eval {
$executor = $self->executor_for_apache_request($r);
my $request_content_length = $headers_in->{'Content-Length'};
# XXX get content-type by response_content_type() meth call on serializer?
# (need to think-through content-type, transfer-encoding, disposition etc etc
my $response_content_type = 'application/x-perl-gofer-response-binary';
# XXX should probably contol flow via method: GET vs POST
my $of = "";
if (!$request_content_length) { # assume GET request
my $args = $r->args || '';
my %args = map { (split('=',$_,2))[0,1] } split /[&;]/, $args, -1;
my $req = $args{req}
or die "No req argument or Content-Length ($args)\n";
$frozen_request = decode_base64($req);
if ($args{_dd}) { # XXX temp hack
$response_serializer = $datadumper_serializer;
$response_content_type = 'text/plain';
if ($args{_dd} eq 'request') { # XXX even more of a temp hack
$request = $transport->thaw_request($frozen_request);
$r->pnotes(gofer_request => $request);
$frozen_response = $datadumper_serializer->serialize($request);
goto send_frozen_response;
}
}
}
else {
my $content_type = $headers_in->{'Content-Type'};
die "Unsupported gofer Content-Type"
unless $content_type eq 'application/x-perl-gofer-request-binary';
$r->read($frozen_request, $request_content_length);
if (length($frozen_request) != $request_content_length) {
die sprintf "Gofer request length (%d) doesn't match Content-Length header (%d)",
length($frozen_request), $request_content_length;
}
}
$request = $transport->thaw_request($frozen_request);
$r->pnotes(gofer_request => $request);
$response = $executor->execute_request( $request );
$r->pnotes(gofer_response => $response);
$frozen_response = $transport->freeze_response($response, $response_serializer);
send_frozen_response:
$r->content_type($response_content_type);
# setup http headers
# See http://perl.apache.org/docs/general/correct_headers/correct_headers.html
# provide Content-Length for KeepAlive so it works if people want it
$r->headers_out->{'Content-Length'} = do { use bytes; length($frozen_response) };
$r->print($frozen_response);
$http_status = OK;
};
if ($@) {
( run in 2.370 seconds using v1.01-cache-2.11-cpan-f56aa216473 )