Подтвердить что ты не робот

Как подделать IP-адрес клиента в unit test для приложения Mojolicious?

В моем приложении Mojolicious мне нужно использовать IP-адрес клиента ($c->tx->remote_address) для ограничения скорости службы. Это хорошо работает.

Теперь я пытаюсь создать unit test для этой функции, но у меня возникают проблемы с подделкой IP-адреса клиента в моих тестах.

Сначала я подумал, что local_address в Mojo:: UserAgent может делать то, что я хочу, но тот, где пользовательский агент связывает приложение локально, и его изменение ломает все, потому что оно больше не может найти приложение.

Затем я попытался использовать Sub::Override для замены remote_address в 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), но эти подходы здесь не работают.

4b9b3361

Ответ 1

Автор Mojolicious указал на IRC, чтобы посмотреть модульные тесты на уровне Mojo для реализации заголовка X-Forwarded-For, поэтому я сделал.

Нам нужно установить $ENV{MOJO_REVERSE_PROXY} в истинное значение в unit test и перезапустить сервер, а затем отправить заголовок X-Forwarded-For с новым IP-адресом, и все будет работать.

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