Hi,

I'm beginning with mod_perl (mod_perl-1.99_05 + Apache 2.0.40 from
RedHat 8.0) and I want to write a module for rewriting the documents
that passes through the Apache proxy. So, I looked at the
Apache::AdBlocker
(http://perl.apache.org/docs/tutorials/tips/mod_perl_tricks/mod_perl_tricks.html#A_Banner_Ad_Blocker)
module and I'm facing some problems for writing the content of the
documents back to the client.

My main problem is that I get a SEGFAULT when calling the "$r->print()"
or "$r->send_http_header()" method.
I get the request, copy the headers from "headers_in", make my own
request with LWP, copy the headers to "headers_out", then it SEGFAULT
when writing the document ... Are this methods deprecated/not fully
implemented ? what is the correct way to write data to the client ?

The other problem is that if I use the "$r->push_handlers(PerlHandler =>
\&proxy_handler)" mechanism, my "proxy_handler()" function is never
called, so I do the work directly into the handler sub, is this ok ?

I attached my test module below (I register it with a "PerlTransHandler
Apache::Plop" statement in httpd.conf)

Thanks for your help,
Jérôme

-- 

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;

Reply via email to