-
-
Save xantus/5a5b4e0c12ee55a30263 to your computer and use it in GitHub Desktop.
Mojolicious Reverse Proxy Plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Mojolicious::Plugin::ReverseProxy; | |
use strict; | |
use warnings; | |
use base 'Mojolicious::Plugin'; | |
# ugh | |
$ENV{MOJO_MAX_MESSAGE_SIZE} = 5242880; | |
sub register { | |
my ( $plugin, $app, $cfg ) = @_; | |
die "route and url params are required" unless ref $cfg eq 'HASH' && @{$cfg}{qw( route url )}; | |
$cfg->{url} = Mojo::URL->new( $cfg->{url} ) unless UNIVERSAL::isa( $cfg->{url}, 'Mojo::URL' ); | |
my $cb = sub { $plugin->_proxy( @_, $cfg ) }; | |
$app->routes->route( $cfg->{route}.'(*proxypath)' )->to({ cb => $cb, 'proxy.url' => $cfg->{url} }); | |
$app->routes->route( $cfg->{route} )->to({ cb => $cb, 'proxy.url' => $cfg->{url} }); | |
} | |
sub _proxy { | |
my ( $self, $c, $cfg ) = @_; | |
my $host = $c->req->headers->host; | |
my $tx = Mojo::Transaction::HTTP->new; | |
$tx->req( $c->req ); | |
# fix up the request url | |
my $file = $c->stash( 'proxypath' ) || '/'; | |
my $url = $c->stash( 'proxy.url' )->clone; | |
$url->path->append( grep { length $_ } split( '/', $file ) ); | |
$url->path->trailing_slash(0) unless substr( $file, -1, 1 ) eq '/'; | |
$tx->req->url( $url ); | |
$tx->req->headers->header( 'X-Forwarded-For' => $c->tx->remote_address ); | |
$tx->req->headers->header( 'X-Forwarded-Host' => $host ) if $host; | |
$tx->req->headers->header( 'Host' => $url->host . ( $url->port ? ':'.$url->port : '' ) ); | |
# XXX X-Forwarded-Server | |
# TODO add a flag for this | |
if ( my $bigip = $c->req->headers->header( 'X-BIGIP-Client' ) && $cfg->{behind_bigip} ) { | |
$tx->req->headers->header( 'X-BIGIP-Client' => $bigip ); | |
} | |
# make the request | |
$c->pause; | |
$c->client->async->process($tx => sub { | |
my ( $cli, $t ) = @_; | |
$c->render_data($t->res->body); | |
$c->res->headers->from_hash( {} ); # delete all current headers | |
$c->res->headers->from_hash( $t->res->headers->to_hash ); | |
$c->finish; | |
})->process; | |
return; | |
}; | |
1; | |
__END__ | |
# example | |
use Mojolicious::Lite; | |
# auto daemon | |
@ARGV = qw( daemon ) unless @ARGV; | |
# proxy couchdb | |
app->plugin( 'reverse_proxy' => { route => '/', url => 'http://localhost:5984/' } ); | |
app->start; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment