I am using a self written mod_perl module that does proxy requests. It acts
as content handler and fetches the requestet documents via LWP::UserAgent.
The program works fine but when the request is a POST request and the
response is a redirection (301, 302, ...) with a Location: header, no data
is sent to the browser.

If I don't read the postet data, everything works. So my suspicion is the
following:
For any reason, if the module returns a redirecting result code (301, 302,
...), mod_perl tries to read again the posted data and waits forever.

My solution is simple: Just set the Content-lengt: header to undef:

        $r->header_in('Content-length' => undef);

Is this a bug or a feature?

I include my module and the part of my server config.

Peter

Server config:
==============

        <Directory proxy:>

                SetHandler perl-script
                PerlHandler Apache::Proxy_test

        </Directory>

Proxy_test.pm:
==============


package Apache::Proxy_test;

use strict;

use Apache::Constants qw(:response :methods :http);
use Apache::File ();
use Apache::Log ();
use Apache::ModuleConfig ();
use Apache::Table;
use Apache::URI ();

use LWP::UserAgent ();

my $UA = LWP::UserAgent->new;

sub handler {
        my $r = shift;

        my $not_modified = $r->meets_conditions == HTTP_NOT_MODIFIED;

        #
        # create request
        #
        my $filename = $r->filename();
        $filename =~ s/^proxy://;
        my $parsed_uri = $r->parsed_uri;
        my $query = $parsed_uri->query;
        $filename .= "?$query" if $query;

        $r->log->debug ("filename: $filename");

        my $request = HTTP::Request->new($r->method, $filename);
        $UA->agent ($r->header_in ('User-Agent'));

        # copy POST data, if any
        if($r->method eq 'POST') {
                my $len = $r->header_in('Content-length');
                my $buf;
                my $ret = read(STDIN, $buf, $len);
                $request->content($buf);
                # next line prevents bug !!!
                $r->header_in('Content-length' => undef);
        }

        $r->log->debug ("subrequest:\n\n", $request->as_string);

        #
        # evaluate response
        #

        my $response = $UA->simple_request($request);

        if ($response->code != 200) {
                $r->log->debug ("response not OK:\n\n",
$response->as_string);
                $response->scan(sub {
                        my ($header, $value) = @_;

                        $r->log->debug ("Header-out: $header $value");
                        $r->header_out($header, $value);
                });
        } else {
                $r->content_type($response->header('Content-type'));
                $r->status($response->code);
                $r->status_line(join " ", $response->code,
$response->message);
                $r->send_http_header();
                unless ($r->header_only) {
                        print $response->content;
                }
        }

        $r->log->debug("send:\n\n", $r->as_string);
        $r->log->debug("return ", $response->code);
        return $response->code;
}


1;

__END__

Reply via email to