Hi,
I'm beginning with mod_perl (mod_perl-1.99_05 + Apache-2.0.40 from Linux RedHat 8.0) and I would like to write a module that rewrite the documents that passes through the Apache proxy module.
I found an
Apache::AdBlocker
module but it is for mod_perl 1.0 and do not seems to work with mod_perl 2.0.
So I tried to follow it and write my own module. Here is the test code I wrote, its goal is to intercept the request, fetch the real document with
LWP, modify the html document, then send the modified document back to the client . It almost work but I get a SEGFAULT when sending the modified document back to the client :
package Apache::Plop;
use strict;
use Apache::RequestRec;
use Apache::RequestIO;
use Apache::RequestUtil;
use Apache::Const;
use Apache::ServerUtil;
use Apache::Response;
use APR::Table;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
sub handler {
my $r = shift;
if( ! $r->proxyreq ) {
return Apache::DECLINED;
}
print STDERR "Good, this is a proxyreq ...\n";
# -->
# if I use this push_handlers, I never reach the "proxy_handler" sub
# So I commented it out and tried to do the work directly in "handler"
# $r->handler("perl-script"); #ok, let's do it
# $r->push_handlers(PerlHandler => \&proxy_handler);
#}
#
#sub proxy_handler {
# my $r = shift;
# <--
if( $r->method ne "GET" ) {
return Apache::DECLINED;
}
print STDERR "Good, this is a GET method ...\n";
# prepare the "real" request
my $request = HTTP::Request->new( $r->method, $r->uri );
# copy headers from client request
my %headers_in;
print STDERR "-- client headers --\n";
$r->headers_in()->do(
sub {
print STDERR "$_[0]: $_[1]\n";
$headers_in{$_[0]} = $_[1];
$request->header( {$_[0]}, $_[0] );
}
);
print STDERR "-- end --\n";
# make the "real" request myself
$ua->agent( $headers_in{ 'User-Agent' } );
my $response = $ua->request( $request );
if( ! $response->is_success() ) {
print STDERR "== ERROR ==\n";
return Apache::DECLINED;
}
print STDERR "-- server headers --\n";
my %headers_out;
$response->headers()->scan(
sub {
print STDERR "$_[0]: $_[1]\n";
$headers_out{$_[0]} = $_[1];
}
);
print STDERR "-- end --\n";
# simply override the content
my $content = $response->content;
$content = "<html><body>plop</body></html>";
# adjust the headers for the new content
$headers_out{ 'Content-length' } = length( $content );
$headers_out{ 'Content-type' } = 'text/html';
# copy the modified response headers back to Apache
foreach (keys %headers_out) {
$r->headers_out->{$_} = $headers_out{$_};
}
$r->content_type( $headers_out{ 'Content-type' } );
print STDERR "-- send/print --\n";
# -->
# here is where the SEGFAULT occurs
$r->send_http_header();
$r->print( $content );
# I don't know how to write a content back to the client
# <--
print STDERR "-- end --\n";
return Apache::OK;
}
1;
This module is registered with a "
PerlTransHandler Apache::Plop" and is correctly launched but I'm facing two problems with this code :
- First, if I use the
$r->push_handlers() mecanism I never reach the
proxy_handler subroutine ...
- Second, if I do the work directly in
handler(), I can get the request, make the real request, modify the content but I don't know how to write back a document to the client. I get a
SEGFAULT when it reach the
$r->send_http_header/$r->print statement. If I remove the
send_http_header it SEGFAULT on the
print ...
Any hints ?
Thanks for your help
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.