Skip to content

Commit

Permalink
moved reverse_proxy attribute from Mojo::Server::Daemon to Mojo::Server
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Jul 2, 2014
1 parent dbe303b commit dbcbb11
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 12 deletions.
1 change: 1 addition & 0 deletions Changes
@@ -1,5 +1,6 @@

5.11 2014-07-02
- Moved reverse_proxy attribute from Mojo::Server::Daemon to Mojo::Server.
- Added delay and inactivity_timeout helpers to
Mojolicious::Plugin::DefaultHelpers.
- Improved error method in Mojolicious::Validator::Validation to return
Expand Down
16 changes: 15 additions & 1 deletion lib/Mojo/Server.pm
Expand Up @@ -9,6 +9,7 @@ use Scalar::Util 'blessed';

has app => sub { shift->build_app('Mojo::HelloWorld') };
has [qw(group user)];
has reverse_proxy => sub { $ENV{MOJO_REVERSE_PROXY} };

sub build_app {
my ($self, $app) = @_;
Expand All @@ -17,7 +18,12 @@ sub build_app {
die ref $e ? $e : qq{Couldn't find application class "$app".\n};
}

sub build_tx { shift->app->build_tx }
sub build_tx {
my $self = shift;
my $tx = $self->app->build_tx;
$tx->req->reverse_proxy(1) if $self->reverse_proxy;
return $tx;
}

sub daemonize {

Expand Down Expand Up @@ -159,6 +165,14 @@ Application this server handles, defaults to a L<Mojo::HelloWorld> object.
Group for server process.
=head2 reverse_proxy
my $bool = $server->reverse_proxy;
$server = $server->reverse_proxy($bool);
This server operates behind a reverse proxy, defaults to the value of the
C<MOJO_REVERSE_PROXY> environment variable.
=head2 user
my $user = $server->user;
Expand Down
10 changes: 0 additions & 10 deletions lib/Mojo/Server/Daemon.pm
Expand Up @@ -13,7 +13,6 @@ has inactivity_timeout => sub { $ENV{MOJO_INACTIVITY_TIMEOUT} // 15 };
has ioloop => sub { Mojo::IOLoop->singleton };
has listen => sub { [split ',', $ENV{MOJO_LISTEN} || 'http://*:3000'] };
has max_requests => 25;
has reverse_proxy => sub { $ENV{MOJO_REVERSE_PROXY} };

sub DESTROY {
my $self = shift;
Expand Down Expand Up @@ -67,7 +66,6 @@ sub _build_tx {
my $handle = $self->ioloop->stream($id)->handle;
$tx->local_address($handle->sockhost)->local_port($handle->sockport);
$tx->remote_address($handle->peerhost)->remote_port($handle->peerport);
$tx->req->reverse_proxy(1) if $self->reverse_proxy;
$tx->req->url->base->scheme('https') if $c->{tls};

# Handle upgrades and requests
Expand Down Expand Up @@ -410,14 +408,6 @@ L<Mojo::IOLoop/"max_connections">.
Maximum number of keep-alive requests per connection, defaults to C<25>.
=head2 reverse_proxy
my $bool = $daemon->reverse_proxy;
$daemon = $daemon->reverse_proxy($bool);
This server operates behind a reverse proxy, defaults to the value of the
C<MOJO_REVERSE_PROXY> environment variable.
=head2 silent
my $bool = $daemon->silent;
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Server/Hypnotoad.pm
Expand Up @@ -362,7 +362,7 @@ the server has been stopped.
Activate reverse proxy support, which allows for the C<X-Forwarded-For> and
C<X-Forwarded-Proto> headers to be picked up automatically, defaults to the
value of L<Mojo::Server::Daemon/"reverse_proxy">.
value of L<Mojo::Server/"reverse_proxy">.
=head2 upgrade_timeout
Expand Down
4 changes: 4 additions & 0 deletions lib/Mojo/Server/PSGI.pm
Expand Up @@ -107,6 +107,10 @@ See L<Mojolicious::Guides::Cookbook/"DEPLOYMENT"> for more.
L<Mojo::Server::PSGI> inherits all events from L<Mojo::Server>.
=head1 ATTRIBUTES
L<Mojo::Server::PSGI> inherits all attributes from L<Mojo::Server>.
=head1 METHODS
L<Mojo::Server::PSGI> inherits all methods from L<Mojo::Server> and implements
Expand Down
39 changes: 39 additions & 0 deletions t/mojo/cgi.t
Expand Up @@ -33,6 +33,20 @@ get '/params' => sub {
$c->render(json => $c->req->params->to_hash);
};

get '/proxy' => sub {
my $c = shift;
my $reverse = join ':', $c->tx->remote_address,
$c->req->url->to_abs->protocol;
$c->render(text => $reverse);
};

# Reverse proxy
{
ok !Mojo::Server::CGI->new->reverse_proxy, 'no reverse proxy';
local $ENV{MOJO_REVERSE_PROXY} = 25;
ok !!Mojo::Server::CGI->new->reverse_proxy, 'reverse proxy';
}

# Simple
my $msg = '';
{
Expand Down Expand Up @@ -149,4 +163,29 @@ is $res->headers->content_length, 27, 'right "Content-Length" value';
is $res->json->{lalala}, 23, 'right value';
is $res->json->{bar}, 'baz', 'right value';

# Reverse proxy
$msg = '';
{
local *STDOUT;
open STDOUT, '>', \$msg;
local %ENV = (
PATH_INFO => '/proxy',
REQUEST_METHOD => 'GET',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.0',
'HTTP_X_Forwarded_For' => '192.0.2.2, 192.0.2.1',
'HTTP_X_Forwarded_Proto' => 'https'
);
local $ENV{MOJO_REVERSE_PROXY} = 1;
is(Mojolicious::Command::cgi->new(app => app)->run, 200, 'right status');
}
$res = Mojo::Message::Response->new->parse("HTTP/1.1 200 OK\x0d\x0a$msg");
is $res->code, 200, 'right status';
is $res->headers->status, '200 OK', 'right "Status" value';
is $res->headers->content_length, 15, 'right "Content-Length" value';
is $res->headers->content_type, 'text/html;charset=UTF-8',
'right "Content-Type" value';
is $res->body, '192.0.2.1:https', 'right content';

done_testing();
7 changes: 7 additions & 0 deletions t/mojo/daemon.t
Expand Up @@ -38,6 +38,13 @@ use Mojolicious;
);
}

# Reverse proxy
{
ok !Mojo::Server::Daemon->new->reverse_proxy, 'no reverse proxy';
local $ENV{MOJO_REVERSE_PROXY} = 25;
ok !!Mojo::Server::Daemon->new->reverse_proxy, 'reverse proxy';
}

# Optional home detection
my @path = qw(th is mojo dir wil l never-ever exist);
my $app = Mojo->new(home => Mojo::Home->new(catdir @path));
Expand Down
49 changes: 49 additions & 0 deletions t/mojo/psgi.t
Expand Up @@ -27,6 +27,20 @@ post '/params' => sub {
$c->render(json => $c->req->params->to_hash);
};

get '/proxy' => sub {
my $c = shift;
my $reverse = join ':', $c->tx->remote_address,
$c->req->url->to_abs->protocol;
$c->render(text => $reverse);
};

# Reverse proxy
{
ok !Mojo::Server::PSGI->new->reverse_proxy, 'no reverse proxy';
local $ENV{MOJO_REVERSE_PROXY} = 25;
ok !!Mojo::Server::PSGI->new->reverse_proxy, 'reverse proxy';
}

# Binding
my $app = Mojo::Server::PSGI->new(app => app)->to_psgi_app;
my $content = 'hello=world';
Expand Down Expand Up @@ -184,4 +198,39 @@ my $i = 0;
for my $header (@{$res->[1]}) { $i++ if $header eq 'Set-Cookie' }
is $i, 2, 'right number of "Set-Cookie" headers';

# Reverse proxy
$env = {
CONTENT_LENGTH => 0,
PATH_INFO => '/proxy',
REQUEST_METHOD => 'GET',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.1',
'HTTP_X_Forwarded_For' => '192.0.2.2, 192.0.2.1',
'HTTP_X_Forwarded_Proto' => 'https',
'psgi.version' => [1, 0],
'psgi.url_scheme' => 'http',
'psgi.input' => *STDIN,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 0
};
{
local $ENV{MOJO_REVERSE_PROXY} = 1;
$app = Mojolicious::Command::psgi->new(app => app)->run;
$res = $app->($env);
}
is $res->[0], 200, 'right status';
%headers = @{$res->[1]};
is $headers{'Content-Length'}, 15, 'right "Content-Length" value';
is $headers{'Content-Type'}, 'text/html;charset=UTF-8',
'right "Content-Type" value';
$body = '';
while (defined(my $chunk = $res->[2]->getline)) { $body .= $chunk }
is $body, '192.0.2.1:https', 'right content';
is $ENV{MOJO_HELLO}, undef, 'finish event has not been emitted';
$res->[2]->close;
is delete $ENV{MOJO_HELLO}, 'world', 'finish event has been emitted';

done_testing();

0 comments on commit dbcbb11

Please sign in to comment.