blob: 7436321d697ea1e8c01bd3fcf3751986b33625f0 [file] [log] [blame]
#!/usr/bin/perl
# (C) Maxim Dounin
# Tests for http proxy module related to use with the "if" directive.
# See http://wiki.nginx.org/IfIsEvil for more details.
###############################################################################
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 rewrite http_ssl/)
->has_daemon('openssl')->plan(15);
$t->write_file_expand('nginx.conf', <<'EOF')->todo_alerts();
%%TEST_GLOBALS%%
daemon off;
events {
}
http {
%%TEST_GLOBALS_HTTP%%
server {
listen 127.0.0.1:8080;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8081/;
}
# request was sent to backend without uri changed
# to '/' due to if
location /proxy-pass-uri {
proxy_pass http://127.0.0.1:8081/replacement;
if ($arg_if) {
# nothing
}
location /proxy-pass-uri/inner {
# no proxy_pass here, static
if ($arg_if) {
# nothing
}
}
}
# same as the above, but there is a special handling
# in configuration merge; it used to do wrong things with
# nested locations though
location /proxy-pass-uri-lmt {
proxy_pass http://127.0.0.1:8081/replacement;
limit_except POST {
# nothing
}
location /proxy-pass-uri-lmt/inner {
# no proxy_pass here, static
limit_except POST {
# nothing
}
}
}
location /proxy-pass-uri-lmt-different {
proxy_pass http://127.0.0.1:8081/replacement;
limit_except POST {
proxy_pass http://127.0.0.1:8081;
}
}
# segmentation fault in old versions,
# fixed to return 500 Internal Error in nginx 1.3.10
location /proxy-inside-if-crash {
set $true 1;
if ($true) {
# proxy_pass inside if
proxy_pass http://127.0.0.1:8081;
}
if ($true) {
# no handler here
}
}
# normal proxy_pass and proxy_pass with variables
# use distinct field, and inheritance should be mutually
# exclusive
location /variables {
proxy_pass http://127.0.0.1:8081/outer/$host;
if ($arg_if) {
proxy_pass http://127.0.0.1:8081;
}
location /variables/inner {
proxy_pass http://127.0.0.1:8081;
}
}
# ssl context shouldn't be inherited into nested
# locations with different proxy_pass, but should
# be correctly inherited into if's
location /ssl {
proxy_pass https://127.0.0.1:8082/outer;
if ($arg_if) {
# inherited from outer
}
location /ssl/inner {
proxy_pass http://127.0.0.1:8081;
}
}
}
server {
listen 127.0.0.1:8081;
listen 127.0.0.1:8082 ssl;
server_name localhost;
ssl_certificate localhost.crt;
ssl_certificate_key localhost.key;
return 200 "uri:$uri\n";
}
}
EOF
$t->write_file('openssl.conf', <<EOF);
[ req ]
default_bits = 1024
encrypt_key = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
EOF
my $d = $t->testdir();
foreach my $name ('localhost') {
system('openssl req -x509 -new '
. "-config $d/openssl.conf -subj /CN=$name/ "
. "-out $d/$name.crt -keyout $d/$name.key "
. ">>$d/openssl.out 2>&1") == 0
or die "Can't create certificate for $name: $!\n";
}
$t->run();
###############################################################################
like(http_get('/'), qr!uri:/$!, 'proxy request');
like(http_get('/proxy-pass-uri'), qr!uri:/replacement$!,
'proxy_pass uri changed');
# due to missing information about an original location where
# proxy_pass was specified, this used to pass request with
# original unmodified uri
like(http_get('/proxy-pass-uri?if=1'), qr!uri:/replacement$!,
'proxy_pass uri changed in if');
like(http_get('/proxy-pass-uri/inner'), qr!404 Not Found!,
'proxy_pass uri changed inner');
like(http_get('/proxy-pass-uri/inner?if=1'), qr!404 Not Found!,
'proxy_pass uri changed inner in if');
# limit_except
like(http_get('/proxy-pass-uri-lmt'), qr!uri:/replacement$!,
'proxy_pass uri and limit_except');
# special handling of limit_except resulted in wrong handling
# of requests in nested locations
like(http_get('/proxy-pass-uri-lmt/inner'), qr!404 Not Found!,
'proxy_pass uri and limit_except, inner');
like(http_get('/proxy-pass-uri-lmt-different'),
qr!uri:/proxy-pass-uri-lmt-different!,
'proxy_pass and limit_except with different proxy_pass');
# segmentation fault in old versions,
# fixed to return 500 Internal Error in nginx 1.3.10
like(http_get('/proxy-inside-if-crash'), qr!500 Internal Server Error!,
'proxy_pass inside if');
# normal proxy_pass and proxy_pass with variables
# use distinct field, and inheritance should be mutually
# exclusive, see ticket #645
like(http_get('/variables'), qr!uri:/outer!,
'proxy_pass variables');
like(http_get('/variables?if=1'), qr!uri:/variables!,
'proxy_pass variables if');
like(http_get('/variables/inner'), qr!uri:/variables/inner!,
'proxy_pass variables nested');
# ssl context shouldn't be inherited into nested
# locations with different proxy_pass, but should
# be correctly inherited into if's
like(http_get('/ssl'), qr!uri:/outer!,
'proxy_pass ssl');
like(http_get('/ssl?if=1'), qr!uri:/outer!,
'proxy_pass ssl inside if');
like(http_get('/ssl/inner'), qr!uri:/ssl/inner!,
'proxy_pass nossl inside ssl');
###############################################################################