view proxy_variables.t @ 1410:a1a3164faec8

Tests: harden proxy_variables.t, avoid uninitialized warnings.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 04 Dec 2018 17:07:18 +0300
parents 3783b937a1dc
children 16a8962ff246
line wrap: on
line source

#!/usr/bin/perl

# (C) Sergey Kandaurov
# (C) Nginx, Inc.

# Tests for http proxy module with upstream variables.

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

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(24)
	->write_file_expand('nginx.conf', <<'EOF');

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
    %%TEST_GLOBALS_HTTP%%

    upstream u {
        server 127.0.0.1:8081;
        server 127.0.0.1:8081;
    }

    log_format time '$upstream_connect_time:$upstream_header_time:'
                    '$upstream_response_time';

    server {
        listen       127.0.0.1:8080;
        server_name  localhost;

        add_header X-Connect $upstream_connect_time;
        add_header X-Header $upstream_header_time;
        add_header X-Response $upstream_response_time;

        location / {
            proxy_pass http://127.0.0.1:8081;
            access_log %%TESTDIR%%/time.log time;
        }

        location /pnu {
            proxy_pass http://u/bad;
        }

        location /vars {
            proxy_pass http://127.0.0.1:8080/stub;

            add_header X-Proxy-Host $proxy_host;
            add_header X-Proxy-Port $proxy_port;
            add_header X-Proxy-Forwarded $proxy_add_x_forwarded_for;
        }

        location /stub { }
    }
}

EOF

$t->write_file('stub', '');
$t->run_daemon(\&http_daemon, port(8081));
$t->run();

$t->waitforsocket('127.0.0.1:' . port(8081));

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

my $re = qr/(\d\.\d{3})/;
my $p0 = port(8080);
my ($ct, $ht, $rt, $ct2, $ht2, $rt2, $ct3, $ht3, $rt3);

like(http_get('/vars'), qr/X-Proxy-Host:\s127\.0\.0\.1:$p0/, 'proxy_host');
like(http_get('/vars'), qr/X-Proxy-Port:\s$p0/, 'proxy_port');
like(http_xff('/vars', '192.0.2.1'), qr/X-Proxy-Forwarded:.*192\.0\.2\.1/,
	'proxy_add_x_forwarded_for');

($ct, $ht) = get('/header');
cmp_ok($ct, '<', 1, 'connect time - slow response header');
cmp_ok($ht, '>=', 1, 'header time - slow response header');

($ct, $ht) = get('/body');
cmp_ok($ct, '<', 1, 'connect time - slow response body');
cmp_ok($ht, '<', 1, 'header time - slow response body');

my $s = http_get('/header_close', start => 1);
select undef, undef, undef, 0.4;
close ($s);

# expect no header time in 1st (bad) upstream, no (yet) response time in 2nd

$re = qr/(\d\.\d{3}|-)/;
($ct, $ct2, $ht, $ht2, $rt, $rt2) = get('/pnu', many => 1);
cmp_ok($ct, '<', 1, 'connect time - next');
cmp_ok($ct2, '<', 1, 'connect time - next 2');

TODO: {
local $TODO = 'not yet' unless $t->has_version('1.15.7');

is($ht, '-', 'header time - next');

}

cmp_ok($ht2, '<', 1, 'header time - next 2');
cmp_ok($rt, '>=', 1, 'response time - next');

TODO: {
local $TODO = 'not yet' unless $t->has_version('1.15.7');

is($rt2, '-', 'response time - next 2');

}

$t->stop();

($ct, $ht, $rt, $ct2, $ht2, $rt2, $ct3, $ht3, $rt3)
	= $t->read_file('time.log') =~ /^$re:$re:$re\n$re:$re:$re\n$re:$re:$re$/;

cmp_ok($ct, '<', 1, 'connect time log - slow response header');
cmp_ok($ct2, '<', 1, 'connect time log - slow response body');

TODO: {
local $TODO = 'not yet' unless $t->has_version('1.15.7');

isnt($ct3, '-', 'connect time log - client close set');

}

$ct3 = 0 if $ct3 eq '-';
cmp_ok($ct3, '<', 1, 'connect time log - client close');

cmp_ok($ht, '>=', 1, 'header time log - slow response header');
cmp_ok($ht2, '<', 1, 'header time log - slow response body');
is($ht3, '-', 'header time log - client close');

cmp_ok($rt, '>=', 1, 'response time log - slow response header');
cmp_ok($rt2, '>=', 1, 'response time log - slow response body');

TODO: {
local $TODO = 'not yet' unless $t->has_version('1.15.7');

isnt($rt3, '-', 'response time log - client close set');
$rt3 = 0 if $rt3 eq '-';
cmp_ok($rt3, '>', $ct3, 'response time log - client close');

}

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

sub get {
	my ($uri, %extra) = @_;
	my $re = $extra{many} ? qr/$re, $re?/ : $re;
	my $r = http_get($uri);
	$r =~ /X-Connect: $re/, $r =~ /X-Header: $re/, $r =~ /X-Response: $re/;
}

sub http_xff {
	my ($uri, $xff) = @_;
	return http(<<EOF);
GET $uri HTTP/1.0
Host: localhost
X-Forwarded-For: $xff

EOF
}

sub http_daemon {
	my ($port) = @_;
	my $once = 1;

	my $server = IO::Socket::INET->new(
		Proto => 'tcp',
		LocalHost => '127.0.0.1',
		LocalPort => $port,
		Listen => 5,
		Reuse => 1
	)
		or die "Can't create listening socket: $!\n";

	local $SIG{PIPE} = 'IGNORE';

	while (my $client = $server->accept()) {
		$client->autoflush(1);

		my $headers = '';
		my $uri = '';

		while (<$client>) {
			$headers .= $_;
			last if (/^\x0d?\x0a?$/);
		}

		$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
		next unless defined $uri;

		if ($uri =~ 'bad' && $once) {
			$once = 0;
			select undef, undef, undef, 1.1;
			next;
		}

		if ($uri =~ 'header') {
			select undef, undef, undef, 1.1;
		}

		print $client <<EOF;
HTTP/1.1 200 OK
Connection: close

SEE-THIS-
EOF

		if ($uri =~ 'body') {
			select undef, undef, undef, 1.1;
		}

		print $client 'AND-THIS';
	}
}

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