Ticket #543: http_keepalive_proxy.t

File http_keepalive_proxy.t, 5.3 KB (added by Markus Linnala, 12 years ago)
Line 
1#!/usr/bin/perl
2
3# (C) Maxim Dounin
4# (C) Markus Linnala
5
6# Tests keepalive is kept regardless proxy type.
7
8###############################################################################
9
10use warnings;
11use strict;
12
13use Test::More;
14
15use IO::Socket::INET;
16use Socket qw/ CRLF /;
17
18BEGIN { use FindBin; chdir($FindBin::Bin); }
19
20use lib 'lib';
21use Test::Nginx;
22
23###############################################################################
24
25select STDERR; $| = 1;
26select STDOUT; $| = 1;
27
28plan(skip_all => 'win32') if $^O eq 'MSWin32';
29
30my $t = Test::Nginx->new()->has(qw/http proxy upstream_keepalive sub/)->plan(16)
31 ->write_file_expand('nginx.conf', <<'EOF');
32
33%%TEST_GLOBALS%%
34
35daemon off;
36
37events {
38}
39
40http {
41 %%TEST_GLOBALS_HTTP%%
42
43 upstream backend {
44 server 127.0.0.1:8081;
45 keepalive 1;
46 }
47
48 server {
49 listen 127.0.0.1:8080;
50 server_name localhost;
51
52 location /cl {
53 proxy_pass http://backend;
54 }
55 location /ka {
56 proxy_pass http://backend;
57 proxy_read_timeout 2s;
58 proxy_http_version 1.1;
59 proxy_set_header Connection "";
60 }
61
62 location /cl-ch {
63 sub_filter foo bar;
64 sub_filter_types *;
65 proxy_pass http://backend;
66 }
67 location /ka-ch {
68 sub_filter foo bar;
69 sub_filter_types *;
70 proxy_pass http://backend;
71 proxy_read_timeout 2s;
72 proxy_http_version 1.1;
73 proxy_set_header Connection "";
74 }
75 }
76}
77
78EOF
79
80$t->run_daemon(\&http_daemon);
81$t->run()->waitforsocket('127.0.0.1:8081')
82 or die "Can't start test backend";
83
84###############################################################################
85
86sub http_ka {
87 my ($q, $p) = @_;
88 my_http(<<EOF, 'sleep' => 0.1);
89GET $q HTTP/$p
90Host: localhost
91Connection: Keep-Alive
92
93EOF
94}
95
96sub http_cl {
97 my ($q, $p) = @_;
98 my_http(<<EOF, 'sleep' => 0.1);
99GET $q HTTP/$p
100Host: localhost
101Connection: close
102
103EOF
104}
105
106###############################################################################
107
108like(http_ka('/ka','1.0'), qr/Connection: keep-alive/, 'ka-ka/1.0');
109like(http_cl('/ka','1.0'), qr/Connection: close/, 'ka-cl/1.0');
110
111like(http_ka('/ka','1.1'), qr/Connection: keep-alive/, 'ka-ka/1.1');
112like(http_cl('/ka','1.1'), qr/Connection: close/, 'ka-cl/1.1');
113
114like(http_ka('/cl','1.0'), qr/Connection: keep-alive/, 'cl-ka/1.0');
115like(http_cl('/cl','1.0'), qr/Connection: close/, 'cl-cl/1.0');
116
117like(http_ka('/cl','1.1'), qr/Connection: keep-alive/, 'cl-ka/1.1');
118like(http_cl('/cl','1.1'), qr/Connection: close/, 'cl-cl/1.1');
119
120like(http_ka('/ka-ch','1.0'), qr/Connection: keep-alive/, 'ka-ch-ka/1.0'); #
121like(http_cl('/ka-ch','1.0'), qr/Connection: close/, 'ka-ch-cl/1.0');
122
123like(http_ka('/ka-ch','1.1'), qr/Connection: keep-alive/, 'ka-ch-ka/1.1');
124like(http_cl('/ka-ch','1.1'), qr/Connection: close/, 'ka-ch-cl/1.1');
125
126like(http_ka('/cl-ch','1.0'), qr/Connection: keep-alive/, 'cl-ch-ka/1.0'); #
127like(http_cl('/cl-ch','1.0'), qr/Connection: close/, 'cl-ch-cl/1.0');
128
129like(http_ka('/cl-ch','1.1'), qr/Connection: keep-alive/, 'cl-ch-ka/1.1');
130like(http_cl('/cl-ch','1.1'), qr/Connection: close/, 'cl-ch-cl/1.1');
131
132###############################################################################
133
134sub my_http {
135 my ($request, %extra) = @_;
136 my $reply;
137
138 eval {
139 local $SIG{ALRM} = sub { die "timeout\n" };
140 local $SIG{PIPE} = sub { die "sigpipe\n" };
141 alarm(5);
142
143 my $s = $extra{socket} || IO::Socket::INET->new(
144 Proto => 'tcp',
145 PeerAddr => '127.0.0.1:8080',
146 )
147 or die "Can't connect to nginx: $!\n";
148
149 log_out($request);
150 $s->print($request);
151
152 select undef, undef, undef, $extra{sleep} if $extra{sleep};
153 return '' if $extra{aborted};
154
155 if ($extra{body}) {
156 log_out($extra{body});
157 $s->print($extra{body});
158 }
159
160 # Done writing
161 $s->shutdown(1);
162
163 local $/;
164 $reply = $s->getline();
165
166 alarm(0);
167 };
168 alarm(0);
169 if ($@) {
170 log_in("died: $@");
171 return undef;
172 }
173
174 log_in($reply);
175 return $reply;
176}
177
178sub http_daemon {
179 my $server = IO::Socket::INET->new(
180 Proto => 'tcp',
181 LocalHost => '127.0.0.1:8081',
182 Listen => 5,
183 Reuse => 1
184 )
185 or die "Can't create listening socket: $!\n";
186
187 my $ccount = 0;
188 my $rcount = 0;
189
190 # dumb server which is able to keep connections alive
191
192 while (my $client = $server->accept()) {
193 $client->autoflush(1);
194 $ccount++;
195
196 while (1) {
197 my $headers = '';
198 my $uri = '';
199
200 while (<$client>) {
201 $headers .= $_;
202 last if (/^\x0d?\x0a?$/);
203 }
204
205 last if $headers eq '';
206 $rcount++;
207
208 $uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
209
210 if (1) {
211 print { $client }
212 "HTTP/1.1 200 OK" . CRLF .
213 "X-Request: $rcount" . CRLF .
214 "X-Connection: $ccount" . CRLF .
215 "Content-Length: 10000" . CRLF . CRLF;
216 print { $client } ('X' x 10000)
217 unless $headers =~ /^HEAD/i;
218
219 last;
220 }
221 }
222
223 close $client;
224 }
225}
226
227###############################################################################