1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
use Mojo::Base -strict;
BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' }
use Test::More;
use Test::Mojo;
use Mojo::Server::Daemon;
use Mojo::URL;
use Mojolicious;
use Mojolicious::Lite;
# Test server with various response variants
my $app = Mojolicious->new;
my $daemon = Mojo::Server::Daemon->new(listen => ['http://127.0.0.1'], silent => 1, app => $app);
my $port = $daemon->start->ports->[0];
my $url = Mojo::URL->new("http://127.0.0.1:$port");
my $r = $app->routes;
$r->get(
'/res1' => sub {
my $c = shift;
$c->res->headers->header('X-Mojo-App' => 'One');
$c->render(data => 'One!');
}
);
$r->get(
'/res2' => sub {
my $c = shift;
$c->res->headers->header('X-Mojo-App' => 'Two');
$c->write('Tw');
$c->write('o!');
$c->write('');
}
);
$r->any(
'/res3' => sub {
my $c = shift;
$c->res->headers->header('X-Mojo-App' => 'Three');
$c->res->headers->header('X-Mojo-Method' => $c->req->method);
$c->res->headers->header('X-Mojo-More' => $c->req->headers->header('X-Mojo-More') // '');
$c->res->headers->header('X-Mojo-Body' => length $c->req->body);
$c->write_chunk('Th');
$c->write_chunk('ree!');
$c->write_chunk('');
}
);
$r->get(
'/res4' => sub {
my $c = shift;
$c->res->headers->header('X-Mojo-App' => 'Four');
$c->render(data => '', status => 204);
}
);
$r->get(
'/res5' => sub {
my $c = shift;
Mojo::IOLoop->stream($c->tx->connection)->close;
}
);
$r->get(
'/res6' => sub {
my $c = shift;
$c->res->headers->content_length(4);
$c->write;
Mojo::IOLoop->timer(0.1 => sub { $c->write("Six!") });
}
);
get '/proxy1/*target' => sub {
my $c = shift;
my $target = $c->stash('target');
$c->proxy->get_p($url->path($target))->catch(sub {
my $err = shift;
$c->render(text => "Error: $err", status => 400);
});
};
patch '/proxy2/*target' => sub {
my $c = shift;
my $target = $c->stash('target');
$c->proxy->post_p($url->path($target), {'X-Mojo-More' => 'Less'}, 'Hello!');
};
get '/proxy3/:method/*target' => sub {
my $c = shift;
my $method = $c->stash('method');
my $target = $c->stash('target');
my $tx = $c->ua->build_tx($method, $url->path($target));
$c->proxy->start_p($tx);
$tx->res->content->once(
body => sub {
$c->res->headers->remove('X-Mojo-App');
$c->res->headers->header('X-Mojo-Proxy1' => 'just');
$c->res->headers->header('X-Mojo-Proxy2' => 'works!');
}
);
};
my $t = Test::Mojo->new;
subtest 'Various response variants' => sub {
$t->get_ok('/proxy1/res1')->status_is(200)->header_is('X-Mojo-App' => 'One')->content_is('One!');
$t->get_ok('/proxy1/res2')->status_is(200)->header_is('X-Mojo-App' => 'Two')->content_is('Two!');
$t->get_ok('/proxy1/res3')->status_is(200)->header_is('X-Mojo-App' => 'Three')->header_is('X-Mojo-Method' => 'GET')
->header_is('X-Mojo-More' => '')->header_is('X-Mojo-Body' => 0)->content_is('Three!');
$t->get_ok('/proxy1/res4')->status_is(204)->header_is('X-Mojo-App' => 'Four')->content_is('');
$t->get_ok('/proxy1/res5')->status_is(400)->content_like(qr/Error: /);
$t->get_ok('/proxy1/res6')->status_is(200)->content_is('Six!');
};
subtest 'Custom request' => sub {
$t->patch_ok('/proxy2/res3')->status_is(200)->header_is('X-Mojo-App' => 'Three')
->header_is('X-Mojo-Method' => 'POST')->header_is('X-Mojo-More' => 'Less')->header_is('X-Mojo-Body' => 6)
->content_is('Three!');
};
subtest 'Response modification' => sub {
$t->get_ok('/proxy3/GET/res1')->status_is(200)->header_exists_not('X-Mojo-App')->header_is('X-Mojo-Proxy1' => 'just')
->header_is('X-Mojo-Proxy2' => 'works!')->content_is('One!');
$t->get_ok('/proxy3/POST/res3')->status_is(200)->header_is('X-Mojo-Method' => 'POST')
->header_exists_not('X-Mojo-App')->header_is('X-Mojo-Proxy1' => 'just')->header_is('X-Mojo-Proxy2' => 'works!')
->content_is('Three!');
};
done_testing();
|