comparison grpc_request_buffering.t @ 1353:65730ba03b42

Tests: body cleanup test with preserve_output (ticket #1565).
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 04 Jul 2018 12:24:53 +0300
parents 351b95be742b
children ca6fe31f74c4
comparison
equal deleted inserted replaced
1352:32156faf018e 1353:65730ba03b42
21 ############################################################################### 21 ###############################################################################
22 22
23 select STDERR; $| = 1; 23 select STDERR; $| = 1;
24 select STDOUT; $| = 1; 24 select STDOUT; $| = 1;
25 25
26 my $t = Test::Nginx->new()->has(qw/http http_v2 grpc mirror/); 26 my $t = Test::Nginx->new()->has(qw/http http_v2 grpc mirror proxy/);
27 27
28 $t->write_file_expand('nginx.conf', <<'EOF'); 28 $t->write_file_expand('nginx.conf', <<'EOF');
29 29
30 %%TEST_GLOBALS%% 30 %%TEST_GLOBALS%%
31 31
37 http { 37 http {
38 %%TEST_GLOBALS_HTTP%% 38 %%TEST_GLOBALS_HTTP%%
39 39
40 server { 40 server {
41 listen 127.0.0.1:8080 http2; 41 listen 127.0.0.1:8080 http2;
42 listen 127.0.0.1:8082;
42 server_name localhost; 43 server_name localhost;
43 44
44 location /mirror { } 45 location /mirror { }
45 46
46 location / { 47 location / {
47 grpc_pass 127.0.0.1:8081; 48 grpc_pass 127.0.0.1:8081;
48 add_header X-Body $request_body; 49 add_header X-Body $request_body;
49 mirror /mirror; 50 mirror /mirror;
50 } 51 }
52
53 location /proxy {
54 proxy_pass http://127.0.0.1:8082/mirror;
55 proxy_intercept_errors on;
56 error_page 404 = @fallback;
57 }
58
59 location @fallback {
60 grpc_pass 127.0.0.1:8081;
61 }
51 } 62 }
52 } 63 }
53 64
54 EOF 65 EOF
55 66
56 $t->try_run('no grpc')->plan(9); 67 $t->try_run('no grpc')->plan(12);
57 68
58 ############################################################################### 69 ###############################################################################
59 70
60 my $p = port(8081); 71 my $p = port(8081);
61 my $f = grpc(); 72 my $f = grpc();
74 is($frame->{flags}, 1, 'request - DATA flags'); 85 is($frame->{flags}, 1, 'request - DATA flags');
75 86
76 $frames = $f->{http_end}(); 87 $frames = $f->{http_end}();
77 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; 88 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
78 is($frame->{headers}{'x-body'}, 'Hello', 'request body in memory'); 89 is($frame->{headers}{'x-body'}, 'Hello', 'request body in memory');
90
91 # expect body cleanup is disabled with preserve_output (ticket #1565).
92 # after request body first bytes were proxied on behalf of initial window size,
93 # send response header from upstream, this leads to body cleanup code path
94
95 $frames = $f->{http_start}('/proxy');
96 is(eval(join '+', map { $_->{length} } grep { $_->{type} eq "DATA" } @$frames),
97 65535, 'preserve_output - first body bytes');
98
99 TODO: {
100 local $TODO = 'not yet' unless $t->has_version('1.15.1');
101
102 $frames = $f->{http_end}();
103 is(eval(join '+', map { $_->{length} } grep { $_->{type} eq "DATA" } @$frames),
104 465, 'preserve_output - last body bytes');
105
106 like(`grep -F '[crit]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no crits');
107
108 }
109
110 $t->todo_alerts() if $t->read_file('nginx.conf') =~ /sendfile on/
111 and !$t->has_version('1.15.1');
79 112
80 ############################################################################### 113 ###############################################################################
81 114
82 sub grpc { 115 sub grpc {
83 my ($server, $client, $f, $s, $c, $sid, $uri); 116 my ($server, $client, $f, $s, $c, $sid, $uri);
92 or die "Can't create listening socket: $!\n"; 125 or die "Can't create listening socket: $!\n";
93 126
94 $f->{http_start} = sub { 127 $f->{http_start} = sub {
95 ($uri, my %extra) = @_; 128 ($uri, my %extra) = @_;
96 $s = Test::Nginx::HTTP2->new() if !defined $s; 129 $s = Test::Nginx::HTTP2->new() if !defined $s;
97 $s->new_stream({ body => 'Hello', headers => [ 130 my ($body) = $uri eq '/proxy' ? 'Hello' x 13200 : 'Hello';
131 $s->new_stream({ body => $body, headers => [
98 { name => ':method', value => 'POST', mode => 0 }, 132 { name => ':method', value => 'POST', mode => 0 },
99 { name => ':scheme', value => 'http', mode => 0 }, 133 { name => ':scheme', value => 'http', mode => 0 },
100 { name => ':path', value => $uri }, 134 { name => ':path', value => $uri },
101 { name => ':authority', value => 'localhost' }, 135 { name => ':authority', value => 'localhost' },
102 { name => 'content-length', value => '5' }]}); 136 { name => 'content-length', value => length($body) }]});
103 137
104 if (!$extra{reuse}) { 138 if (!$extra{reuse}) {
105 eval { 139 eval {
106 local $SIG{ALRM} = sub { die "timeout\n" }; 140 local $SIG{ALRM} = sub { die "timeout\n" };
107 alarm(5); 141 alarm(5);
122 156
123 $c = Test::Nginx::HTTP2->new(1, socket => $client, 157 $c = Test::Nginx::HTTP2->new(1, socket => $client,
124 pure => 1, preface => "") or return; 158 pure => 1, preface => "") or return;
125 } 159 }
126 160
127 my $frames = $c->read(all => [{ fin => 1 }]); 161 my $frames = $uri eq '/proxy'
162 ? $c->read(all => [{ length => 65535 }])
163 : $c->read(all => [{ fin => 1 }]);
128 164
129 if (!$extra{reuse}) { 165 if (!$extra{reuse}) {
130 $c->h2_settings(0); 166 $c->h2_settings(0);
131 $c->h2_settings(1); 167 $c->h2_settings(1);
132 } 168 }
138 $f->{http_end} = sub { 174 $f->{http_end} = sub {
139 $c->new_stream({ body_more => 1, headers => [ 175 $c->new_stream({ body_more => 1, headers => [
140 { name => ':status', value => '200', mode => 0 }, 176 { name => ':status', value => '200', mode => 0 },
141 { name => 'content-type', value => 'application/grpc' }, 177 { name => 'content-type', value => 'application/grpc' },
142 ]}, $sid); 178 ]}, $sid);
179
180 # reopen window for request body after response HEADERS is sent
181
182 if ($uri eq '/proxy') {
183 $c->h2_window(2**16, $sid);
184 $c->h2_window(2**16);
185 return $c->read(all => [{ sid => $sid, fin => 1 }]);
186 }
187
143 $c->h2_body('Hello world', { body_more => 1 }); 188 $c->h2_body('Hello world', { body_more => 1 });
144 $c->new_stream({ headers => [ 189 $c->new_stream({ headers => [
145 { name => 'grpc-status', value => '0', mode => 2 }, 190 { name => 'grpc-status', value => '0', mode => 2 },
146 { name => 'grpc-message', value => '', mode => 2 }, 191 { name => 'grpc-message', value => '', mode => 2 },
147 ]}, $sid); 192 ]}, $sid);