comparison t/fastcgi-keepalive.t @ 14:28af4b0b32c1

Keepalive: experimental fastcgi support. Works only with patched nginx and must be explicitly activated by define (./configure --with-cc-opt="-D NGX_UPSTREAM_KEEPALIVE_PATCHED").
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 15 Apr 2009 19:22:11 +0400
parents
children 4fe7e417c424
comparison
equal deleted inserted replaced
13:181a487581b7 14:28af4b0b32c1
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 use Test::Nginx;
14
15 ###############################################################################
16
17 select STDERR; $| = 1;
18 select STDOUT; $| = 1;
19
20 my $t = Test::Nginx->new()->plan(6)
21 ->write_file_expand('nginx.conf', <<'EOF');
22
23 master_process off;
24 daemon off;
25
26 events {
27 worker_connections 1024;
28 }
29
30 http {
31 access_log off;
32
33 client_body_temp_path %%TESTDIR%%/client_body_temp;
34 fastcgi_temp_path %%TESTDIR%%/fastcgi_temp;
35 proxy_temp_path %%TESTDIR%%/proxy_temp;
36
37 upstream backend {
38 server 127.0.0.1:8081;
39 keepalive 1;
40 }
41
42 server {
43 listen localhost:8080;
44 server_name localhost;
45
46 location / {
47 fastcgi_pass backend;
48 }
49 }
50 }
51
52 EOF
53
54 $t->run_daemon(\&fastcgi_test_daemon);
55 $t->run();
56
57 ###############################################################################
58
59 like(http_get('/'), qr/SEE-THIS/, 'fastcgi request');
60 like(http_get('/redir'), qr/302/, 'fastcgi redirect');
61 like(http_get('/'), qr/^request: 3$/m, 'fastcgi third request');
62
63 {
64 local $TODO = 'needs experimental patches';
65
66 like(http_get('/single'), qr/^connection: 1$/m, 'single connection used');
67
68 }
69
70 # New connection to fastcgi application should be established after HEAD
71 # requests since nginx doesn't read whole response (as it doesn't need
72 # body).
73
74 unlike(http_head('/head'), qr/SEE-THIS/, 'no data in HEAD');
75
76 {
77 local $TODO = 'needs experimental patches';
78
79 like(http_get('/after'), qr/^connection: 2$/m, 'new connection after HEAD');
80 }
81
82 ###############################################################################
83
84 # Simple FastCGI responder implementation. Unlike FCGI and FCGI::Async it's
85 # able to count connections.
86
87 # http://www.fastcgi.com/devkit/doc/fcgi-spec.html
88
89 sub fastcgi_read_record($) {
90 my ($socket) = @_;
91
92 my ($n, $h, $header);
93
94 $n = $socket->read($header, 8);
95 return undef if !defined $n or $n != 8;
96
97 @{$h}{qw/ version type id clen plen /} = unpack("CCnnC", $header);
98
99 $n = $socket->read($h->{content}, $h->{clen});
100 return undef if $n != $h->{clen};
101
102 $n = $socket->read($h->{padding}, $h->{plen});
103 return undef if $n != $h->{plen};
104
105 $h->{socket} = $socket;
106 return $h;
107 }
108
109 sub fastcgi_respond($$) {
110 my ($h, $body) = @_;
111
112 # stdout
113 $h->{socket}->write(pack("CCnnCx", $h->{version}, 6, $h->{id},
114 length($body), 0));
115 $h->{socket}->write($body);
116
117 select(undef, undef, undef, 0.1);
118
119 # close stdout
120 $h->{socket}->write(pack("CCnnCx", $h->{version}, 6, $h->{id}, 0, 0));
121
122 select(undef, undef, undef, 0.1);
123
124 # end request
125 $h->{socket}->write(pack("CCnnCx", $h->{version}, 3, $h->{id}, 8, 0));
126 $h->{socket}->write(pack("NCxxx", 0, 0));
127 }
128
129 sub fastcgi_test_daemon {
130 my $server = IO::Socket::INET->new(
131 Proto => 'tcp',
132 LocalAddr => '127.0.0.1:8081',
133 Listen => 5,
134 Reuse => 1
135 )
136 or die "Can't create listening socket: $!\n";
137
138 local $SIG{PIPE} = 'IGNORE';
139
140 my $ccount = 0;
141 my $rcount = 0;
142
143 while (my $client = $server->accept()) {
144 $client->autoflush(1);
145 Test::Nginx::log_core('||', "fastcgi connection");
146
147 $ccount++;
148
149 while (my $h = fastcgi_read_record($client)) {
150 Test::Nginx::log_core('||', "fastcgi record: "
151 . " $h->{version}, $h->{type}, $h->{id}, "
152 . "'$h->{content}'");
153
154 # skip everything unless stdin, then respond
155 next if $h->{type} != 5;
156
157 $rcount++;
158
159 # respond
160 fastcgi_respond($h, <<EOF);
161 Location: http://localhost:8080/redirect
162 Content-Type: text/html
163
164 SEE-THIS
165 request: $rcount
166 connection: $ccount
167 EOF
168 }
169
170 close $client;
171 }
172 }
173
174 ###############################################################################