2017-10-26 1 views
11

私のMojoliciousアプリでは、サービスのレート制限にクライアントのIPアドレス($c->tx->remote_address)を使用する必要があります。これはうまくいく。MojoliciousアプリケーションのユニットテストでクライアントのIPアドレスを偽装するにはどうすればよいですか?

私は現在、この機能の単体テストを構築しようとしていますが、私のテストではクライアントのIPを偽装することに問題があります。

まずはlocal_address in Mojo::UserAgentが私の望んだことをするかもしれないと思ったのですが、それはユーザーエージェントがアプリケーションをローカルにバインドしていて、アプリケーションをそれ以上見つけることができないため、

私はその後、remote_address in Mojo::Transactionを交換するSub::Overrideを使用してみましたが、私は$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 and Dancer(または他のTest :: Plackベースのシステム)でこれを行う方法を知っていますが、ここではそれらのアプローチは機能しません。

答えて

10

Mojoliciousの著者は、X-Forwarded-Forヘッダー実装のMojo distのユニットテストをIRCで調べると指摘しました。so I did

ユニットテストで$ENV{MOJO_REVERSE_PROXY}をtrueに設定してサーバーを再起動し、新しいIPアドレスのX-Forwarded-Forヘッダーを送信するだけで正常に動作します。

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 
関連する問題