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__