Configuring Catalyst for use behind a front-end proxy

A typical catalyst setup might have the server running on a cluster of machines, which are proxied by a light-weight frontend server such as Apache or nginx. This means that the catalyst app needs to know the publically-viewable URI base it's going to be accessed from, so that c.uri_for constructs and similar refer to the correct absolute path where necessary.

There are (at least) three ways of doing this:

  1. Set $c->config->{using_frontend_proxy} = 1. This causes catalyst to look for X-Forwarded-Path and X-Forwarded-Port headers in incoming requests, and infer the correct URI base for it. This is a problem if your proxy doesn't provide these headers, or doesn't let you specify custom ones (e.g. Apache 1.3 - although http://allafrica.com/tools/apache/mod_proxy/ helps with this. But if you can patch your apache, you might as well be upgrading it to 2.2...)

  2. Catalyst::TraitFor::Request::ProxyBase. This lets you use a single X-Request-Base header rather than the above combinations. Again, not useful if you can't add headers in your frontend proxy.

  3. Specify it in the app itself, rather than the frontend. The easiest way of doing this seems to be:

package MyApp;

use Moose; # must be before use Catalyst
use Catalyst::Runtime 5.80;

__PACKAGE__->setup();

# must be after ->setup();
after prepare_path => sub {
    my $c = shift;
    $c->req->base(URI->new($c->config->{base}));
};

This has the disadvantage that it only fixes up things which look at $c->req->base, such as c.uri_for - things like c->req->uri will still refer to the wrong URI. To fix this, you probably want to use an approach like Catalyst::TraitFor::Request::ProxyBase.

Another approach is probably to inject an X- header into the request in the backend using a similar Moose hook to the above.

My tags:
 
Popular tags:
 
Powered by Catalyst
Powered by MojoMojo Hosted by Shadowcat - Managed by Nordaaker