use Mojo::Base -strict;
use Test::More;
use Mojo::JSON 'decode_json';
use Mojo::Server::PSGI;
use Mojolicious::Command::psgi;
use Mojolicious::Lite;
# Silence
app->log->level('fatal');
under sub {
shift->on(finish => sub { $ENV{MOJO_HELLO} = 'world' });
};
get '/' => {text => 'Your Mojo is working!'};
get '/cookies' => sub {
my $c = shift;
my $params = $c->req->params->to_hash;
for my $key (sort keys %$params) { $c->cookie($key, $params->{$key}) }
$c->render(text => 'nomnomnom');
};
post '/params' => sub {
my $c = shift;
$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} = 1;
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';
open my $body, '<', \$content;
my $env = {
CONTENT_LENGTH => 11,
CONTENT_TYPE => 'application/x-www-form-urlencoded',
PATH_INFO => '/params',
QUERY_STRING => 'lalala=23&bar=baz',
REQUEST_METHOD => 'POST',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.0',
'psgi.version' => [1, 0],
'psgi.url_scheme' => 'http',
'psgi.input' => $body,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 0
};
my $res = $app->($env);
is $res->[0], 200, 'right status';
my %headers = @{$res->[1]};
ok keys(%headers) >= 3, 'enough headers';
ok $headers{Date}, 'has "Date" value';
is $headers{'Content-Length'}, 43, 'right "Content-Length" value';
is $headers{'Content-Type'}, 'application/json;charset=UTF-8',
'right "Content-Type" value';
my $params = '';
while (defined(my $chunk = $res->[2]->getline)) { $params .= $chunk }
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';
is_deeply decode_json($params), {bar => 'baz', hello => 'world', lalala => 23},
'right structure';
# Command
$content = 'world=hello';
open $body, '<', \$content;
$env = {
CONTENT_LENGTH => 11,
CONTENT_TYPE => 'application/x-www-form-urlencoded',
PATH_INFO => '/params',
QUERY_STRING => 'lalala=23&bar=baz',
REQUEST_METHOD => 'POST',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.0',
'psgi.version' => [1, 0],
'psgi.url_scheme' => 'http',
'psgi.input' => $body,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 0
};
$app = Mojolicious::Command::psgi->new(app => app)->run;
$res = $app->($env);
is $res->[0], 200, 'right status';
%headers = @{$res->[1]};
ok keys(%headers) >= 3, 'enough headers';
ok $headers{Date}, 'has "Date" value';
is $headers{'Content-Length'}, 43, 'right "Content-Length" value';
is $headers{'Content-Type'}, 'application/json;charset=UTF-8',
'right "Content-Type" value';
$params = '';
while (defined(my $chunk = $res->[2]->getline)) { $params .= $chunk }
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';
is_deeply decode_json($params), {bar => 'baz', world => 'hello', lalala => 23},
'right structure';
# Simple
$env = {
CONTENT_LENGTH => 0,
PATH_INFO => '/',
REQUEST_METHOD => 'GET',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.1',
'psgi.version' => [1, 0],
'psgi.url_scheme' => 'http',
'psgi.input' => *STDIN,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 0
};
$app = Mojolicious::Command::psgi->new(app => app)->run;
$res = $app->($env);
is $res->[0], 200, 'right status';
%headers = @{$res->[1]};
is $headers{'Content-Length'}, 21, '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, 'Your Mojo is working!', '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';
# HEAD request
$env = {
CONTENT_LENGTH => 0,
PATH_INFO => '/',
REQUEST_METHOD => 'HEAD',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.1',
'psgi.version' => [1, 0],
'psgi.url_scheme' => 'http',
'psgi.input' => *STDIN,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 0
};
$app = Mojolicious::Command::psgi->new(app => app)->run;
$res = $app->($env);
is $res->[0], 200, 'right status';
%headers = @{$res->[1]};
is $headers{'Content-Length'}, 21, '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, '', 'no 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';
# Cookies
$env = {
CONTENT_LENGTH => 0,
PATH_INFO => '/cookies',
QUERY_STRING => 'lalala=23&bar=baz',
REQUEST_METHOD => 'GET',
SCRIPT_NAME => '/',
HTTP_HOST => 'localhost:8080',
SERVER_PROTOCOL => 'HTTP/1.1',
'psgi.version' => [1, 0],
'psgi.url_scheme' => 'http',
'psgi.input' => *STDIN,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 0
};
$app = Mojolicious::Command::psgi->new(app => app)->run;
$res = $app->($env);
is $res->[0], 200, 'right status';
ok scalar @{$res->[1]} >= 10, 'enough headers';
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();