comparison fastcgi_keepalive.t @ 250:0c9f15938545

Tests: upstream keepalive tests imported.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 24 Jan 2013 02:00:03 +0400
parents
children df984d23f9d1
comparison
equal deleted inserted replaced
249:6a0d934950bc 250:0c9f15938545
1 #!/usr/bin/perl
2
3 # (C) Maxim Dounin
4
5 # Test for fastcgi backend with keepalive.
6
7 ###############################################################################
8
9 use warnings;
10 use strict;
11
12 use Test::More;
13
14 BEGIN { use FindBin; chdir($FindBin::Bin); }
15
16 use lib 'lib';
17 use Test::Nginx;
18
19 ###############################################################################
20
21 select STDERR; $| = 1;
22 select STDOUT; $| = 1;
23
24 my $t = Test::Nginx->new()->write_file_expand('nginx.conf', <<'EOF');
25
26 %%TEST_GLOBALS%%
27
28 daemon off;
29
30 events {
31 }
32
33 http {
34 %%TEST_GLOBALS_HTTP%%
35
36 upstream backend {
37 server 127.0.0.1:8081;
38 keepalive 1;
39 }
40
41 server {
42 listen 127.0.0.1:8080;
43 server_name localhost;
44
45 location / {
46 fastcgi_pass backend;
47 fastcgi_keep_conn on;
48 }
49 }
50 }
51
52 EOF
53
54 $t->run_daemon(\&fastcgi_test_daemon);
55
56 eval {
57 open OLDERR, ">&", \*STDERR; close STDERR;
58 $t->run();
59 open STDERR, ">&", \*OLDERR;
60 };
61 plan(skip_all => 'no keepalive patches') if $@;
62
63 $t->plan(6);
64
65 ###############################################################################
66
67 like(http_get('/'), qr/SEE-THIS/, 'fastcgi request');
68 like(http_get('/redir'), qr/302/, 'fastcgi redirect');
69 like(http_get('/'), qr/^request: 3$/m, 'fastcgi third request');
70
71 like(http_get('/single'), qr/^connection: 1$/m, 'single connection used');
72
73 # New connection to fastcgi application should be established after HEAD
74 # requests since nginx doesn't read whole response (as it doesn't need
75 # body).
76
77 unlike(http_head('/head'), qr/SEE-THIS/, 'no data in HEAD');
78
79 like(http_get('/after'), qr/^connection: 2$/m, 'new connection after HEAD');
80
81 ###############################################################################
82
83 # Simple FastCGI responder implementation. Unlike FCGI and FCGI::Async it's
84 # able to count connections.
85
86 # http://www.fastcgi.com/devkit/doc/fcgi-spec.html
87
88 sub fastcgi_read_record($) {
89 my ($socket) = @_;
90
91 my ($n, $h, $header);
92
93 $n = $socket->read($header, 8);
94 return undef if !defined $n or $n != 8;
95
96 @{$h}{qw/ version type id clen plen /} = unpack("CCnnC", $header);
97
98 $n = $socket->read($h->{content}, $h->{clen});
99 return undef if $n != $h->{clen};
100
101 $n = $socket->read($h->{padding}, $h->{plen});
102 return undef if $n != $h->{plen};
103
104 $h->{socket} = $socket;
105 return $h;
106 }
107
108 sub fastcgi_respond($$) {
109 my ($h, $body) = @_;
110
111 # stdout
112 $h->{socket}->write(pack("CCnnCx", $h->{version}, 6, $h->{id},
113 length($body), 0));
114 $h->{socket}->write($body);
115
116 # write some text to stdout and stderr splitted over multiple network
117 # packets to test if we correctly set pipe length in various places
118
119 my $tt = "test text, just for test";
120
121 $h->{socket}->write(pack("CCnnCx", $h->{version}, 6, $h->{id},
122 length($tt . $tt), 0) . $tt);
123 select(undef, undef, undef, 0.1);
124 $h->{socket}->write($tt . pack("CC", $h->{version}, 7));
125 select(undef, undef, undef, 0.1);
126 $h->{socket}->write(pack("nnCx", $h->{id}, length($tt), 0));
127 $h->{socket}->write($tt);
128
129 # close stdout
130 $h->{socket}->write(pack("CCnnCx", $h->{version}, 6, $h->{id}, 0, 0));
131
132 select(undef, undef, undef, 0.1);
133
134 # end request
135 $h->{socket}->write(pack("CCnnCx", $h->{version}, 3, $h->{id}, 8, 0));
136 $h->{socket}->write(pack("NCxxx", 0, 0));
137 }
138
139 sub fastcgi_test_daemon {
140 my $server = IO::Socket::INET->new(
141 Proto => 'tcp',
142 LocalAddr => '127.0.0.1:8081',
143 Listen => 5,
144 Reuse => 1
145 )
146 or die "Can't create listening socket: $!\n";
147
148 local $SIG{PIPE} = 'IGNORE';
149
150 my $ccount = 0;
151 my $rcount = 0;
152
153 while (my $client = $server->accept()) {
154 $client->autoflush(1);
155 Test::Nginx::log_core('||', "fastcgi connection");
156
157 $ccount++;
158
159 while (my $h = fastcgi_read_record($client)) {
160 Test::Nginx::log_core('||', "fastcgi record: "
161 . " $h->{version}, $h->{type}, $h->{id}, "
162 . "'$h->{content}'");
163
164 # skip everything unless stdin, then respond
165 next if $h->{type} != 5;
166
167 $rcount++;
168
169 # respond
170 fastcgi_respond($h, <<EOF);
171 Location: http://localhost:8080/redirect
172 Content-Type: text/html
173
174 SEE-THIS
175 request: $rcount
176 connection: $ccount
177 EOF
178 }
179
180 close $client;
181 }
182 }
183
184 ###############################################################################