The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Any::Daemon::HTTP::Proxy - proxy request to a remote server

INHERITANCE

 Any::Daemon::HTTP::Proxy
   is an Any::Daemon::HTTP::Source

SYNOPSIS

 my $proxy = Any::Daemon::HTTP::Proxy->new(path => '/forward');

 my $vh = Any::Daemon::HTTP::VirtualHost->new(proxies => $proxy);

DESCRIPTION

[Available since v0.24] Warning: new code, not intensively tested.

There are two kinds of proxies:

  1. Each Any::Daemon::HTTP::VirtualHost may define as many proxies as it needs: selected by location inside a virtual host namespace, just like other directories. These requests are forwarded to some proxy server.

  2. The HTTP daemon itself collects proxies which use forward_map's; mapping incoming requests for (one or) many domains to (one or) many destinations.

The current implementation does not support all features of proxies. For instance, it does not combine incoming connections into new outgoing connections. You may take a look at IOMux::HTTP::Gateway for that.

Proxy loop detection is used by adding Via header fields (which can be removed explicitly).

Extends "DESCRIPTION" in Any::Daemon::HTTP::Source.

METHODS

Extends "METHODS" in Any::Daemon::HTTP::Source.

Constructors

Extends "Constructors" in Any::Daemon::HTTP::Source.

Any::Daemon::HTTP::Proxy->new(%options|\%options)

A proxy has either a path various, in which case it is part of a single VirtualHost, or has a forward_map when it becomes a child of the http daemon itself.

 -Option            --Defined in               --Default
  add_req_headers                                []
  add_resp_headers                               []
  allow               Any::Daemon::HTTP::Source  <undef>
  change_request                                 undef
  change_response                                undef
  deny                Any::Daemon::HTTP::Source  <undef>
  forward_map                                    <undef>
  forward_timeout                                100
  name                Any::Daemon::HTTP::Source  path
  path                Any::Daemon::HTTP::Source  '/'
  remote_proxy                                   undef
  reverse                                        true
  strip_req_headers                              []
  strip_resp_headers                             []
  user_agent                                     undef
  via                                            "$host:$port"
add_req_headers => ARRAY|CODE
add_resp_headers => ARRAY|CODE
allow => CIDR|HOSTNAME|DOMAIN|CODE|ARRAY
change_request => CODE

After adding and deleting headers, you may make other changes to the request. The CODE is called with the proxy object, request and (rewritten) uri as parameters.

change_response => CODE

After adding and deleting headers, you may make other changes to the request. The CODE is called with the proxy object, request and (rewritten) uri as parameters.

deny => CIDR|HOSTNAME|DOMAIN|CODE|ARRAY
forward_map => CODE|'RELAY'

When there is a forward_map, you can only add this proxy object to the daemon. The map describes how incoming domains need to be handled.

The special constant RELAY will make all requests being accepted and forwarded without uri rewrite.

forward_timeout => SECONDS
name => STRING
path => PATH
remote_proxy => PROXY|CODE

When this proxy speaks to an other PROXY. This can either be a fixed address or name, or computed for each connection via a CODE reference. See remoteProxy().

reverse => BOOLEAN

Enable reverse proxy behavior as well, which means that redirection responses from the remote will be modified to have the redirected passing through this proxy as well.

strip_req_headers => NAME|REGEX|ARRAY|CODE

See stripHeaders().

strip_resp_headers => NAME|REGEX|ARRAY|CODE

See stripHeaders().

user_agent => LWP::UserAgent
via => WORD

To be included in the "Via" header line, which detects proxy loops.

Attributes

Extends "Attributes" in Any::Daemon::HTTP::Source.

$obj->name()

Inherited, see "Attributes" in Any::Daemon::HTTP::Source

$obj->path()

Inherited, see "Attributes" in Any::Daemon::HTTP::Source

$obj->remoteProxy($protocol, $session, $request, $uri)

Returns a list of remote proxies (at least one) to be used for $uri. If undef or empty, then there is direct connection to the destination.

$obj->userAgent()
$obj->via()

Permissions

Extends "Permissions" in Any::Daemon::HTTP::Source.

$obj->allow($session, $request, $uri)

Inherited, see "Permissions" in Any::Daemon::HTTP::Source

$obj->collect($vhost, $session, $request, $uri)

Inherited, see "Permissions" in Any::Daemon::HTTP::Source

Actions

Extends "Actions" in Any::Daemon::HTTP::Source.

Action

$obj->addHeaders($message, PAIRS|ARRAY|CODE)

Add header lines to the request or response $message. Existing headers with the same name are retained.

   add_req_headers   => [ Server => 'MSIE' ]
   add_req_headers   => sub { my ($proxy,$msg,$uri) = @_; ... }
$obj->forwardRequest($session, $request, $uri)
$obj->forwardRewrite($session, $request, $uri)
$obj->proxify($request, $uri)

The $uri is the result of a rewrite of the destination mentioned in the $request. To be able to forward the $request to the next server, we need to rewrite its headers.

It is also possible the the original request originates from browser which is not configured for proxying. That will be repared as well.

$obj->stripHeaders($message, $name|Regexp|ARRAY|CODE|LIST)

Convert a specification about which headers should be stripped into a singled CODE reference to remove the specified fields from a request (to a proxy) or response (by the proxy).

   strip_req_headers => 'ETag'
   strip_req_headers => qr/^X-/
   strip_req_headers => [ 'ETag', qr/^X-/ ]
   
   strip_req_headers => sub { my ($proxy,$msg,$uri) = @_; ... }

DETAILS

Extends "DETAILS" in Any::Daemon::HTTP::Source.

Resource restrictions

Extends "Resource restrictions" in Any::Daemon::HTTP::Source.

Using the proxy-map

The proxy map will only be used when the access rules permit the client to access this source. When the map returns a new URI as result, that will be the new destination of the request. When undef is returned, there may be an other proxy specification which will accept it.

A typical usage could be:

  Any::Daemon::HTTP::Proxy->new(forward_map => \&mapper);

  sub mapper($$$)
  {   my ($proxy, $session, $request, $uri) = @_;

      if(lc $uri->authority eq 'my.example.com')
      {   my $new = $uri->clone;
          $new->authority('somewhere.else.org');
          return $new;
      }

      undef;
  }

You can do anything you need: build lookup tables, rewrite parameter lists, and more. However: the final URI needs to be an absolute URI. Please create regression tests for your mapper function.

Proxy to a proxy

An open forwarding proxy can be made with

  Any::Daemon::HTTP::Proxy->new
    ( forward_map  => 'RELAY'
    , remote_proxy => 'proxy.firewall.me'
    );

SEE ALSO

This module is part of Any-Daemon-HTTP distribution version 0.30, built on April 06, 2020. Website: http://perl.overmeer.net/any-daemon/

LICENSE

Copyrights 2013-2020 by [Mark Overmeer]. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://dev.perl.org/licenses/