代码之家  ›  专栏  ›  技术社区  ›  simbabque

如何在一个mojolicous应用程序的单元测试中伪造客户端IP地址?

  •  13
  • simbabque  · 技术社区  · 7 年前

    在我的Mojolicious应用程序中,我需要使用客户端的IP地址( $c->tx->remote_address

    首先我认为 local_address in Mojo::UserAgent 可能会做我想做的,但这就是用户代理在本地绑定应用程序的地方,更改它会破坏一切,因为它再也找不到应用程序了。

    然后我试着使用 Sub::Override 更换 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(或其他基于测试::Plack的系统)实现这一点,但这些方法在这里不起作用。

    1 回复  |  直到 7 年前
        1
  •  13
  •   simbabque    7 年前

    Mojolicious的作者在IRC上指出,要查看Mojo dist中的单元测试 X-Forwarded-For 标头实现, so I did .

    我们需要设置 $ENV{MOJO_REVERSE_PROXY} 并重新启动服务器,然后发送一个 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