Mercurial > hg > nginx-tests
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); |