package Apache::LightBackhand;

use strict;
use LWP::UserAgent ();
use Apache::Constants qw(OK SERVER_ERROR);

$Apache::LightBackhand::VERSION = '0.10';

sub handler {
  my $http = shift;

  my ($ua, $response, $headers_out);
  my ($uri, %headers_in);
  
  $ua = LWP::UserAgent->new(
		env_proxy => 0,
		keep_alive => 0,
		timeout => 15,
		requests_redirectable => [],
	);
  $uri = $http->dir_config('BackhandURI') . $http->uri;
  $uri.= '?' . $http->args if ($http->args);

  $headers_out = HTTP::Headers->new;
  %headers_in = $http->headers_in;
  foreach (keys %headers_in) {
    $headers_out->header($_, $headers_in{$_});
  }
  $headers_out->header('X-Forwarded-For' => $http->connection->remote_ip);

  $response = $ua->request(
	HTTP::Request->new($http->method, $uri, $headers_out, scalar $http->content) );

  if ($response->is_error and $response->as_string =~ /^500 \(Internal Server Error\)/) {
    $http->log_reason($response->as_string);
    return SERVER_ERROR;
  } else {
    $http->status_line($response->status_line);
    $response->scan(sub { $http->header_out(@_) });
    $http->send_http_header;
    $http->print($response->content);
    return OK;
  }
}

1;

__END__

=head1 NAME

Apache::LightBackhand - Forward the request to a backhand server

=head1 SYNOPSIS

 #in httpd.conf

 <Files *.asp>
   SetHandler perl-script
   PerlHandler Apache::LightBackhand
   PerlSetVar BackhandURI http://ntserver/public
 </Files>

 <VirtualHost extranet.mycompany.com>
   SetHandler perl-script
   PerlHandler Apache::LightBackhand
   PerlSetVar BackhandURI http://intranet

   ...
 </VirtualHost>

=head1 DESCRIPTION

The handler will forward any request to another server. Every
header will be passed to the backhand webserver, including
POST contents, query strings and cookies.
The destination is mapped using the Perl variable I<BackhandURI>.

=head1 ISSUES

The request IP address on the backhand server will appear to
be the IP of the forwarding server. Any application that
rely on the IP address of the user for authentication or
state management will break. Also, the logging facility of
the webserver will log incorrect source addresses.
To help solve this problem, the handler encapsulates the IP
address of the resquest in a I<X-Forwarded-For> header.

=head1 BUGS

A too large file upload or download will consume too much memory.
This will be fixed in the future.

=head1 SEE ALSO

perl(1), mod_perl(3), Apache(3), mod_alias, Apache::Backhand(3)

=head1 AUTHOR

Ricardo C. A. de Basto
