view proxy-noclose.t @ 35:7bf0e8a1d66c

Tests: always define temp paths. This is required since nginx tries to create them at startup (and fails if it can't).
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 16 Oct 2008 19:16:46 +0400
parents 71ea39729fa0
children daa295331acd
line wrap: on
line source

#!/usr/bin/perl

# (C) Maxim Dounin

# Test for http backend not closing connection properly after sending full
# reply.  This is in fact backend bug, but it seems common, and anyway
# correct handling is required to support persistent connections.

# There are actually 2 nginx problems here:
#
# 1. It doesn't send reply in-time even if got Content-Length and all the data.
#
# 2. If upstream times out some data may be left in input buffer and won't be
#    sent to downstream.

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

use warnings;
use strict;

use Test::More tests => 4;

use IO::Select;

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

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

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

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

my $t = Test::Nginx->new();

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

master_process off;
daemon         off;

events {
    worker_connections  1024;
}

http {
    access_log    off;
    root          %%TESTDIR%%;

    client_body_temp_path  %%TESTDIR%%/client_body_temp;
    fastcgi_temp_path      %%TESTDIR%%/fastcgi_temp;
    proxy_temp_path        %%TESTDIR%%/proxy_temp;

    server {
        listen       localhost:8080;
        server_name  localhost;

        location / {
            proxy_pass http://localhost:8081;
            proxy_read_timeout 1s;
        }

        location /uselen {
            proxy_pass http://localhost:8081;

            # test will wait only 2s for reply, we it will fail if
            # Content-Length not used as a hint
 
            proxy_read_timeout 10s;
        }
    }
}

EOF

$t->run_daemon(\&http_noclose_daemon);
$t->run();

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

TODO: {
local $TODO = 'not fixed yet, patches under review';

like(http_get('/'), qr/SEE-THIS/, 'request to bad backend');
like(http_get('/multi'), qr/AND-THIS/, 'bad backend - multiple packets');
like(http_get('/nolen'), qr/SEE-THIS/, 'bad backend - no content length');
like(http_get('/uselen'), qr/SEE-THIS/, 'content-length actually used');

}

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

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

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

		my $multi = 0;
		my $nolen = 0;

        	while (<$client>) {
			$multi = 1 if /multi/;
			$nolen = 1 if /nolen/;
                	last if (/^\x0d?\x0a?$/);
        	}

		if ($nolen) {

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

TEST-OK-IF-YOU-SEE-THIS
EOF
		} elsif ($multi) {

        		print $client <<"EOF";
HTTP/1.1 200 OK
Content-Length: 32
Connection: close

TEST-OK-IF-YOU-SEE-THIS
EOF

			select undef, undef, undef, 0.1;
			print $client 'AND-THIS';

		} else {

        		print $client <<"EOF";
HTTP/1.1 200 OK
Content-Length: 24
Connection: close

TEST-OK-IF-YOU-SEE-THIS
EOF
		}

		my $select = IO::Select->new($client);
        	$select->can_read(10);
        	close $client;
	}
}

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