Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
409 changes: 409 additions & 0 deletions forward_proxy.t

Large diffs are not rendered by default.

170 changes: 170 additions & 0 deletions forward_proxy_conf.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/usr/bin/perl

# Tests for forward_proxy configuration conflicts and inheritance.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(5);

$t->write_file('error.log', '');

my ($rc, $out) = config_test($t, <<'EOF');
daemon off;

events {
}

http {
server {
listen 127.0.0.1:%%PORT_8080%%;
server_name localhost;

location / {
forward_proxy on;
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}
}
}
EOF
ok($rc != 0 && $out =~ /incompatible with/ms,
'same location rejects forward_proxy then proxy_pass');

($rc, $out) = config_test($t, <<'EOF');
daemon off;

events {
}

http {
server {
listen 127.0.0.1:%%PORT_8082%%;
server_name localhost;

location / {
proxy_pass http://127.0.0.1:%%PORT_8083%%;
forward_proxy on;
}
}
}
EOF
ok($rc != 0 && $out =~ /incompatible with/ms,
'same location rejects proxy_pass then forward_proxy');

($rc, $out) = config_test($t, <<'EOF');
daemon off;

events {
}

http {
server {
listen 127.0.0.1:%%PORT_8084%%;
server_name localhost;

location / {
forward_proxy on;

location /child {
proxy_pass http://127.0.0.1:%%PORT_8085%%;
}
}
}
}
EOF
ok($rc != 0 && $out =~ /incompatible with/ms,
'inherited forward_proxy rejects child proxy_pass');

($rc, $out) = config_test($t, <<'EOF');
daemon off;

events {
}

http {
server {
listen 127.0.0.1:%%PORT_8086%%;
server_name localhost;

location / {
proxy_pass http://127.0.0.1:%%PORT_8087%%;

location /child {
forward_proxy on;
}
}
}
}
EOF
ok($rc == 0,
'child forward_proxy is allowed under parent proxy_pass');

($rc, $out) = config_test($t, <<'EOF');
daemon off;

events {
}

http {
server {
listen 127.0.0.1:%%PORT_8088%%;
server_name localhost;

location / {
forward_proxy on;

location /child {
forward_proxy off;
proxy_pass http://127.0.0.1:%%PORT_8089%%;
}
}
}
}
EOF
ok($rc == 0, 'child forward_proxy off allows proxy_pass override');

###############################################################################

sub config_test {
my ($t, $conf) = @_;

my $testdir = $t->testdir();
my $cmd = join ' ',
shell_quote($Test::Nginx::NGINX),
'-p', shell_quote($testdir . '/'),
'-c', shell_quote('nginx.conf'),
'-e', shell_quote('error.log'),
'-t', '2>&1';

$t->write_file_expand('nginx.conf', $conf);
mkdir $testdir . '/logs';

my $out = `$cmd`;
my $rc = $? >> 8;

return ($rc, $out);
}

sub shell_quote {
my ($value) = @_;

$value =~ s/'/'"'"'/gms;

return "'$value'";
}

###############################################################################
123 changes: 123 additions & 0 deletions forward_proxy_ipv6.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/perl

# Tests for forward proxy IPv6 targets.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;
use Test::Nginx::HTTP2;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

plan(skip_all => 'win32') if $^O eq 'MSWin32';

my $t = Test::Nginx->new()->has(qw/http proxy http_v2/);

$t->write_file_expand('nginx.conf', <<'EOF');

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
%%TEST_GLOBALS_HTTP%%

server {
listen 127.0.0.1:8080;
server_name localhost;

location / {
forward_proxy on;
proxy_connect_timeout 2s;
proxy_read_timeout 2s;
proxy_send_timeout 2s;
}
}

server {
listen 127.0.0.1:8082;
server_name localhost;

http2 on;

location / {
forward_proxy on;
proxy_connect_timeout 2s;
proxy_read_timeout 2s;
proxy_send_timeout 2s;
}
}

server {
listen [::1]:%%PORT_8081%%;
server_name localhost;

location / {
add_header X-Method $request_method always;
add_header X-URI $request_uri always;
add_header X-Host $http_host always;
return 200 "method=$request_method\nuri=$request_uri\nhost=$http_host\n";
}
}
}

EOF

$t->try_run('no inet6 support')->plan(4);

###############################################################################

my $p = port(8081);

my $r = http(<<"EOF");
GET http://[::1]:$p/ipv6?x=1 HTTP/1.1
Host: ignored.example
Connection: close

EOF
like($r, qr/^HTTP\/1\.1 200 OK/ms, 'h1 ipv6 forward proxy request');
like($r, qr/X-Host: \[::1\]:$p/i, 'h1 ipv6 target preserves Host');

my ($headers, $body) = h2_forward(
path => '/h2-ipv6',
host => "[::1]:$p",
);
is($headers->{':status'}, '200', 'h2 ipv6 forward proxy request');
like($body, qr/method=GET\nuri=\/h2-ipv6\nhost=\[::1\]:$p\n/s,
'h2 ipv6 target preserves Host');

###############################################################################

sub h2_forward {
my (%args) = @_;

my $s = Test::Nginx::HTTP2->new(port(8082), pure => 1);
my $sid = $s->new_stream({
method => 'GET',
scheme => 'http',
path => $args{path},
host => $args{host},
});

my $frames = $s->read(all => [{ sid => $sid, fin => 1 }], wait => 2);
my ($headers) = map { $_->{headers} } grep { $_->{type} eq 'HEADERS' } @$frames;
my $body = join('', map { $_->{data} } grep { $_->{type} eq 'DATA' } @$frames);

return ($headers, $body);
}

###############################################################################
Loading