如何在 Mojolicious 应用程序的单元测试中伪造客户端 IP 地址?
How do I fake the client IP address in a unit test for a Mojolicious app?
在我的 Mojolicious 应用程序中,我需要使用客户端的 IP 地址 ($c->tx->remote_address
) 来限制服务的速率。这很好用。
我现在正在尝试为此功能构建单元测试,但我在测试中无法伪造客户端的 IP。
首先我认为 local_address
in Mojo::UserAgent 可能会做我想做的事,但那是用户代理在本地绑定应用程序的地方,更改它会破坏一切,因为它无法再找到该应用程序。
然后我尝试使用 Sub::Override to replace the remote_address
in Mojo::Transaction,但是当我使用 $t->post_ok
时它已经适用于客户端,它尝试向不存在的 IP 发送请求,因为远程地址在客户端是服务器的地址,我被一个永远不会成功的等待阻塞请求卡住了,因为它想要的服务器不存在。
您可以使用以下 MCVE 进行尝试。预期结果是测试通过。
use strict;
use warnings;
use Test::More;
use Test::Mojo;
use Mojolicious::Lite;
get '/foo' => sub { my $c = shift; $c->render( text => $c->tx->remote_address ) };
my $t = Test::Mojo->new;
$t->get_ok('/foo')->content_like(qr/\Q127.0.0.1/);
# TODO change client IP address to 10.1.1.1
# in a way that the /foo route sees it
$t->get_ok('/foo')->content_like(qr/\Q10.1.1.1/);
done_testing;
我知道如何使用 Catalyst 和 Dancer(或其他基于 Test::Plack 的系统)执行此操作,但这些方法在这里不起作用。
Mojolicious 的作者在 IRC 上指出要查看 X-Forwarded-For
header 实现的 Mojo 分区中的单元测试,so I did.
我们需要在单元测试中将 $ENV{MOJO_REVERSE_PROXY}
设置为真值并重新启动服务器,然后使用新 IP 地址发送 X-Forwarded-For
header工作。
use strict;
use warnings;
use Test::More;
use Test::Mojo;
use Mojolicious::Lite;
get '/foo' => sub { my $c = shift; $c->render( text => $c->tx->remote_address ) };
my $t = Test::Mojo->new;
$t->get_ok('/foo')->content_like(qr/\Q127.0.0.1/);
{
local $ENV{MOJO_REVERSE_PROXY} = 1;
$t->ua->server->restart;
$t->get_ok( '/foo' => { 'X-Forwarded-For' => '10.1.1.1' } )->content_like(qr/\Q10.1.1.1/);
}
done_testing;
测试现在通过了。
ok 1 - GET /foo
ok 2 - content is similar
ok 3 - GET /foo
ok 4 - content is similar
1..4
在我的 Mojolicious 应用程序中,我需要使用客户端的 IP 地址 ($c->tx->remote_address
) 来限制服务的速率。这很好用。
我现在正在尝试为此功能构建单元测试,但我在测试中无法伪造客户端的 IP。
首先我认为 local_address
in Mojo::UserAgent 可能会做我想做的事,但那是用户代理在本地绑定应用程序的地方,更改它会破坏一切,因为它无法再找到该应用程序。
然后我尝试使用 Sub::Override to replace the remote_address
in Mojo::Transaction,但是当我使用 $t->post_ok
时它已经适用于客户端,它尝试向不存在的 IP 发送请求,因为远程地址在客户端是服务器的地址,我被一个永远不会成功的等待阻塞请求卡住了,因为它想要的服务器不存在。
您可以使用以下 MCVE 进行尝试。预期结果是测试通过。
use strict;
use warnings;
use Test::More;
use Test::Mojo;
use Mojolicious::Lite;
get '/foo' => sub { my $c = shift; $c->render( text => $c->tx->remote_address ) };
my $t = Test::Mojo->new;
$t->get_ok('/foo')->content_like(qr/\Q127.0.0.1/);
# TODO change client IP address to 10.1.1.1
# in a way that the /foo route sees it
$t->get_ok('/foo')->content_like(qr/\Q10.1.1.1/);
done_testing;
我知道如何使用 Catalyst 和 Dancer(或其他基于 Test::Plack 的系统)执行此操作,但这些方法在这里不起作用。
Mojolicious 的作者在 IRC 上指出要查看 X-Forwarded-For
header 实现的 Mojo 分区中的单元测试,so I did.
我们需要在单元测试中将 $ENV{MOJO_REVERSE_PROXY}
设置为真值并重新启动服务器,然后使用新 IP 地址发送 X-Forwarded-For
header工作。
use strict;
use warnings;
use Test::More;
use Test::Mojo;
use Mojolicious::Lite;
get '/foo' => sub { my $c = shift; $c->render( text => $c->tx->remote_address ) };
my $t = Test::Mojo->new;
$t->get_ok('/foo')->content_like(qr/\Q127.0.0.1/);
{
local $ENV{MOJO_REVERSE_PROXY} = 1;
$t->ua->server->restart;
$t->get_ok( '/foo' => { 'X-Forwarded-For' => '10.1.1.1' } )->content_like(qr/\Q10.1.1.1/);
}
done_testing;
测试现在通过了。
ok 1 - GET /foo
ok 2 - content is similar
ok 3 - GET /foo
ok 4 - content is similar
1..4