comparison proxy_request_buffering.t @ 542:e7e3ced702f5

Tests: unbuffered request body.
author Sergey Kandaurov <pluknet@nginx.com>
date Mon, 06 Apr 2015 18:02:30 +0300
parents
children dbf8fb0f3d30
comparison
equal deleted inserted replaced
541:53d0d963eb40 542:e7e3ced702f5
1 #!/usr/bin/perl
2
3 # (C) Maxim Dounin
4 # (C) Sergey Kandaurov
5 # (C) Nginx, Inc.
6
7 # Tests for unbuffered request body.
8
9 ###############################################################################
10
11 use warnings;
12 use strict;
13
14 use Test::More;
15 use Socket qw/ CRLF /;
16
17 BEGIN { use FindBin; chdir($FindBin::Bin); }
18
19 use lib 'lib';
20 use Test::Nginx;
21
22 ###############################################################################
23
24 select STDERR; $| = 1;
25 select STDOUT; $| = 1;
26
27 my $t = Test::Nginx->new()->has(qw/http proxy rewrite/);
28
29 $t->write_file_expand('nginx.conf', <<'EOF');
30
31 %%TEST_GLOBALS%%
32
33 daemon off;
34
35 events {
36 }
37
38 http {
39 %%TEST_GLOBALS_HTTP%%
40
41 server {
42 listen 127.0.0.1:8080;
43 server_name localhost;
44
45 client_header_buffer_size 1k;
46 proxy_request_buffering off;
47
48 location / {
49 client_body_buffer_size 2k;
50 add_header X-Body "$request_body";
51 proxy_pass http://127.0.0.1:8081;
52 }
53 location /small {
54 client_body_in_file_only on;
55 proxy_pass http://127.0.0.1:8080/;
56 }
57 location /single {
58 client_body_in_single_buffer on;
59 add_header X-Body "$request_body";
60 proxy_pass http://127.0.0.1:8081;
61 }
62 location /discard {
63 return 200 "TEST\n";
64 }
65 location /preread {
66 proxy_pass http://127.0.0.1:8082/;
67 }
68 location /error_page {
69 proxy_pass http://127.0.0.1:8081/404;
70 error_page 404 /404;
71 proxy_intercept_errors on;
72 }
73 location /404 {
74 return 200 "$request_body\n";
75 }
76 }
77
78 server {
79 listen 127.0.0.1:8081;
80 server_name localhost;
81
82 location / {
83 return 204;
84 }
85 location /404 { }
86 }
87 }
88
89 EOF
90
91 $t->try_run('no proxy_request_buffering')->plan(18);
92
93 ###############################################################################
94
95 unlike(http_get('/'), qr/X-Body:/ms, 'no body');
96
97 like(http_get_body('/', '0123456789'),
98 qr/X-Body: 0123456789\x0d?$/ms, 'body');
99
100 like(http_get_body('/', '0123456789' x 128),
101 qr/X-Body: (0123456789){128}\x0d?$/ms, 'body in two buffers');
102
103 like(http_get_body('/single', '0123456789' x 128),
104 qr/X-Body: (0123456789){128}\x0d?$/ms, 'body in single buffer');
105
106 like(http_get_body('/error_page', '0123456789'),
107 qr/^0123456789$/m, 'body in error page');
108
109 # pipelined requests
110
111 like(http_get_body('/', '0123456789', '0123456789' x 128, '0123456789' x 512,
112 'foobar'), qr/X-Body: foobar\x0d?$/ms, 'body pipelined');
113 like(http_get_body('/', '0123456789' x 128, '0123456789' x 512, '0123456789',
114 'foobar'), qr/X-Body: foobar\x0d?$/ms, 'body pipelined 2');
115
116 like(http_get_body('/discard', '0123456789', '0123456789' x 128,
117 '0123456789' x 512, 'foobar'), qr/(TEST.*){4}/ms,
118 'body discard');
119 like(http_get_body('/discard', '0123456789' x 128, '0123456789' x 512,
120 '0123456789', 'foobar'), qr/(TEST.*){4}/ms,
121 'body discard 2');
122
123 # proxy with file only is disabled in unbuffered mode
124
125 like(http_get_body('/small', '0123456789'),
126 qr/X-Body: 0123456789\x0d?$/ms, 'small body in file only');
127
128 # interactive tests
129
130 my $s = get_body('/preread', 8082, 10);
131 ok($s, 'no preread');
132
133 SKIP: {
134 skip 'no preread failed', 3 unless $s;
135
136 is($s->{upload}('01234'), '01234', 'no preread - body part');
137 is($s->{upload}('56789'), '56789', 'no preread - body part 2');
138
139 like($s->{http_end}(), qr/200 OK/, 'no preread - response');
140
141 }
142
143 $s = get_body('/preread', 8082, 10, '01234');
144 ok($s, 'preread');
145
146 SKIP: {
147 skip 'preread failed', 3 unless $s;
148
149 is($s->{preread}, '01234', 'preread - preread');
150 is($s->{upload}('56789'), '56789', 'preread - body');
151
152 like($s->{http_end}(), qr/200 OK/, 'preread - response');
153
154 }
155
156 ###############################################################################
157
158 sub http_get_body {
159 my $uri = shift;
160 my $last = pop;
161 return http( join '', (map {
162 my $body = $_;
163 "GET $uri HTTP/1.1" . CRLF
164 . "Host: localhost" . CRLF
165 . "Content-Length: " . (length $body) . CRLF . CRLF
166 . $body
167 } @_),
168 "GET $uri HTTP/1.1" . CRLF
169 . "Host: localhost" . CRLF
170 . "Connection: close" . CRLF
171 . "Content-Length: " . (length $last) . CRLF . CRLF
172 . $last
173 );
174 }
175
176 sub get_body {
177 my ($url, $port, $length, $body) = @_;
178 my ($server, $client, $s);
179
180 $server = IO::Socket::INET->new(
181 Proto => 'tcp',
182 LocalHost => '127.0.0.1',
183 LocalPort => $port,
184 Listen => 5,
185 Reuse => 1
186 )
187 or die "Can't create listening socket: $!\n";
188
189 my $r = <<EOF;
190 GET $url HTTP/1.1
191 Host: localhost
192 Connection: close
193 Content-Length: $length
194
195 EOF
196
197 if (defined $body) {
198 $r .= $body;
199 }
200
201 $s = http($r, start => 1);
202
203 eval {
204 local $SIG{ALRM} = sub { die "timeout\n" };
205 local $SIG{PIPE} = sub { die "sigpipe\n" };
206 alarm(5);
207
208 $client = $server->accept();
209
210 alarm(0);
211 };
212 alarm(0);
213 if ($@) {
214 log_in("died: $@");
215 return undef;
216 }
217
218 $client->sysread(my $buf, 1024);
219 $buf =~ s/.*?\x0d\x0a?\x0d\x0a?(.*)/$1/ms;
220
221 my $f = { preread => $buf };
222 $f->{upload} = sub {
223 my $buf = shift;
224
225 eval {
226 local $SIG{ALRM} = sub { die "timeout\n" };
227 local $SIG{PIPE} = sub { die "sigpipe\n" };
228 alarm(5);
229
230 $s->write($buf);
231 $client->sysread($buf, 1024);
232
233 alarm(0);
234 };
235 alarm(0);
236 if ($@) {
237 log_in("died: $@");
238 return undef;
239 }
240
241 return $buf;
242 };
243 $f->{http_end} = sub {
244 my $buf = '';
245
246 $client->write(<<EOF);
247 HTTP/1.1 200 OK
248 Connection: close
249 X-Port: $port
250
251 OK
252 EOF
253
254 $client->close;
255
256 eval {
257 local $SIG{ALRM} = sub { die "timeout\n" };
258 local $SIG{PIPE} = sub { die "sigpipe\n" };
259 alarm(5);
260
261 $s->sysread($buf, 1024);
262
263 alarm(0);
264 };
265 alarm(0);
266 if ($@) {
267 log_in("died: $@");
268 return undef;
269 }
270
271 return $buf;
272 };
273 return $f;
274 }
275
276 ###############################################################################