Mercurial > hg > nginx-tests
annotate grpc_ssl.t @ 1701:408fe0dd3fed
Tests: fixed mail_imap_ssl.t too long shutdown.
Prior to literals support in IMAP test backend (e7f0b4ca0a1a), early backend
response was treated as invalid, with subsequent proxy connection close.
Now that the connection continues successfully, this requires connection
close before nginx shutdown. Otherwise, it would wait for proxy_timeout.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 17 Jun 2021 19:52:36 +0300 |
parents | 0190dd24d328 |
children | f4c79ee52d8f |
rev | line source |
---|---|
1303 | 1 #!/usr/bin/perl |
2 | |
3 # (C) Sergey Kandaurov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Tests for grpc backend with ssl. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use Test::More; | |
14 | |
15 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
16 | |
17 use lib 'lib'; | |
18 use Test::Nginx; | |
19 use Test::Nginx::HTTP2; | |
20 | |
21 ############################################################################### | |
22 | |
23 select STDERR; $| = 1; | |
24 select STDOUT; $| = 1; | |
25 | |
1312
6f95c0ed2335
Tests: removed proxy prerequisite from grpc tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1303
diff
changeset
|
26 my $t = Test::Nginx->new()->has(qw/http rewrite http_v2 grpc/) |
1378
ba7e2e60f8b6
Tests: fixed grpc_ssl.t prerequisites.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1376
diff
changeset
|
27 ->has(qw/upstream_keepalive http_ssl/)->has_daemon('openssl'); |
1303 | 28 |
29 $t->{_configure_args} =~ /OpenSSL ([\d\.]+)/; | |
30 plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2'; | |
31 | |
1381
97c8280de681
Tests: removed TODO and try_run() checks for legacy versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1378
diff
changeset
|
32 $t->write_file_expand('nginx.conf', <<'EOF')->plan(33); |
1303 | 33 |
34 %%TEST_GLOBALS%% | |
35 | |
36 daemon off; | |
37 | |
38 events { | |
39 } | |
40 | |
41 http { | |
42 %%TEST_GLOBALS_HTTP%% | |
43 | |
44 upstream u { | |
45 server 127.0.0.1:8081; | |
46 keepalive 1; | |
47 } | |
48 | |
49 server { | |
50 listen 127.0.0.1:8081 http2 ssl; | |
51 server_name localhost; | |
52 | |
53 ssl_certificate_key localhost.key; | |
54 ssl_certificate localhost.crt; | |
55 | |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
56 ssl_verify_client optional; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
57 ssl_client_certificate client.crt; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
58 |
1303 | 59 location / { |
60 grpc_pass 127.0.0.1:8082; | |
61 add_header X-Connection $connection; | |
62 } | |
63 } | |
64 | |
65 server { | |
66 listen 127.0.0.1:8080 http2; | |
67 server_name localhost; | |
68 | |
69 location / { | |
70 grpc_pass grpcs://127.0.0.1:8081; | |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
71 grpc_ssl_name localhost; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
72 grpc_ssl_verify on; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
73 grpc_ssl_trusted_certificate localhost.crt; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
74 |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
75 grpc_ssl_certificate client.crt; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
76 grpc_ssl_certificate_key client.key; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
77 grpc_ssl_password_file password; |
1303 | 78 |
79 if ($arg_if) { | |
80 # nothing | |
81 } | |
82 | |
83 limit_except GET { | |
84 # nothing | |
85 } | |
86 } | |
87 | |
88 location /KeepAlive { | |
89 grpc_pass grpcs://u; | |
90 } | |
91 } | |
92 } | |
93 | |
94 EOF | |
95 | |
96 $t->write_file('openssl.conf', <<EOF); | |
97 [ req ] | |
1488
dbce8fb5f5f8
Tests: align with OpenSSL security level 2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1415
diff
changeset
|
98 default_bits = 2048 |
1303 | 99 encrypt_key = no |
100 distinguished_name = req_distinguished_name | |
101 [ req_distinguished_name ] | |
102 EOF | |
103 | |
104 my $d = $t->testdir(); | |
105 | |
106 foreach my $name ('localhost') { | |
107 system('openssl req -x509 -new ' | |
108 . "-config $d/openssl.conf -subj /CN=$name/ " | |
109 . "-out $d/$name.crt -keyout $d/$name.key " | |
110 . ">>$d/openssl.out 2>&1") == 0 | |
111 or die "Can't create certificate for $name: $!\n"; | |
112 } | |
113 | |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
114 foreach my $name ('client') { |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
115 system("openssl genrsa -out $d/$name.key -passout pass:$name " |
1488
dbce8fb5f5f8
Tests: align with OpenSSL security level 2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1415
diff
changeset
|
116 . "-aes128 2048 >>$d/openssl.out 2>&1") == 0 |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
117 or die "Can't create private key: $!\n"; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
118 system('openssl req -x509 -new ' |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
119 . "-config $d/openssl.conf -subj /CN=$name/ " |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
120 . "-out $d/$name.crt " |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
121 . "-key $d/$name.key -passin pass:$name" |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
122 . ">>$d/openssl.out 2>&1") == 0 |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
123 or die "Can't create certificate for $name: $!\n"; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
124 } |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
125 |
1323
6eb3dd2d4d5a
Tests: postponed grpc_ssl.t startup on win32, see eadd24ccfda1.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
126 sleep 1 if $^O eq 'MSWin32'; |
6eb3dd2d4d5a
Tests: postponed grpc_ssl.t startup on win32, see eadd24ccfda1.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
127 |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
128 $t->write_file('password', 'client'); |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
129 |
1381
97c8280de681
Tests: removed TODO and try_run() checks for legacy versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1378
diff
changeset
|
130 $t->run(); |
1303 | 131 |
132 ############################################################################### | |
133 | |
134 my $p = port(8082); | |
135 my $f = grpc(); | |
136 | |
137 my $frames = $f->{http_start}('/SayHello'); | |
138 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
139 is($frame->{flags}, 4, 'request - HEADERS flags'); | |
140 ok((my $sid = $frame->{sid}) % 2, 'request - HEADERS sid odd'); | |
141 is($frame->{headers}{':method'}, 'POST', 'request - method'); | |
142 is($frame->{headers}{':scheme'}, 'http', 'request - scheme'); | |
143 is($frame->{headers}{':path'}, '/SayHello', 'request - path'); | |
144 is($frame->{headers}{':authority'}, "127.0.0.1:$p", 'request - authority'); | |
145 is($frame->{headers}{'content-type'}, 'application/grpc', | |
146 'request - content type'); | |
147 is($frame->{headers}{te}, 'trailers', 'request - te'); | |
148 | |
149 $frames = $f->{data}('Hello'); | |
150 ($frame) = grep { $_->{type} eq "SETTINGS" } @$frames; | |
151 is($frame->{flags}, 1, 'request - SETTINGS ack'); | |
152 is($frame->{sid}, 0, 'request - SETTINGS sid'); | |
153 is($frame->{length}, 0, 'request - SETTINGS length'); | |
154 | |
155 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
156 is($frame->{data}, 'Hello', 'request - DATA'); | |
157 is($frame->{length}, 5, 'request - DATA length'); | |
158 is($frame->{flags}, 1, 'request - DATA flags'); | |
159 is($frame->{sid}, $sid, 'request - DATA sid match'); | |
160 | |
161 $frames = $f->{http_end}(); | |
162 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
163 is($frame->{flags}, 4, 'response - HEADERS flags'); | |
164 is($frame->{sid}, 1, 'response - HEADERS sid'); | |
165 is($frame->{headers}{':status'}, '200', 'response - status'); | |
166 is($frame->{headers}{'content-type'}, 'application/grpc', | |
167 'response - content type'); | |
168 ok($frame->{headers}{server}, 'response - server'); | |
169 ok($frame->{headers}{date}, 'response - date'); | |
170 ok(my $c = $frame->{headers}{'x-connection'}, 'response - connection'); | |
171 | |
172 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
173 is($frame->{data}, 'Hello world', 'response - DATA'); | |
174 is($frame->{length}, 11, 'response - DATA length'); | |
175 is($frame->{flags}, 0, 'response - DATA flags'); | |
176 is($frame->{sid}, 1, 'response - DATA sid'); | |
177 | |
178 (undef, $frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
179 is($frame->{flags}, 5, 'response - trailers flags'); | |
180 is($frame->{sid}, 1, 'response - trailers sid'); | |
181 is($frame->{headers}{'grpc-message'}, '', 'response - trailers message'); | |
182 is($frame->{headers}{'grpc-status'}, '0', 'response - trailers status'); | |
183 | |
184 # next request is on a new backend connection, no sid incremented | |
185 | |
186 $f->{http_start}('/SayHello'); | |
187 $f->{data}('Hello'); | |
188 $frames = $f->{http_end}(); | |
189 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
190 cmp_ok($frame->{headers}{'x-connection'}, '>', $c, 'response 2 - connection'); | |
191 | |
192 # upstream keepalive | |
193 | |
194 $f->{http_start}('/KeepAlive'); | |
195 $f->{data}('Hello'); | |
196 $frames = $f->{http_end}(); | |
197 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
198 ok($c = $frame->{headers}{'x-connection'}, 'keepalive - connection'); | |
199 | |
200 $f->{http_start}('/KeepAlive'); | |
201 $f->{data}('Hello'); | |
202 $frames = $f->{http_end}(); | |
203 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
204 is($frame->{headers}{'x-connection'}, $c, 'keepalive - connection reuse'); | |
205 | |
206 ############################################################################### | |
207 | |
208 sub grpc { | |
209 my ($server, $client, $f, $s, $c, $sid, $uri); | |
210 | |
211 $server = IO::Socket::INET->new( | |
212 Proto => 'tcp', | |
213 LocalHost => '127.0.0.1', | |
214 LocalPort => $p, | |
215 Listen => 5, | |
216 Reuse => 1 | |
217 ) | |
218 or die "Can't create listening socket: $!\n"; | |
219 | |
220 $f->{http_start} = sub { | |
221 ($uri, my %extra) = @_; | |
222 my $body_more = 1 if $uri !~ /LongHeader/; | |
223 $s = Test::Nginx::HTTP2->new() if !defined $s; | |
224 $s->new_stream({ body_more => $body_more, headers => [ | |
225 { name => ':method', value => 'POST', mode => 0 }, | |
226 { name => ':scheme', value => 'http', mode => 0 }, | |
227 { name => ':path', value => $uri, }, | |
228 { name => ':authority', value => 'localhost' }, | |
229 { name => 'content-type', value => 'application/grpc' }, | |
230 { name => 'te', value => 'trailers', mode => 2 }]}); | |
231 | |
232 if (!$extra{reuse}) { | |
1321
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
233 eval { |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
234 local $SIG{ALRM} = sub { die "timeout\n" }; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
235 alarm(5); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
236 |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
237 $client = $server->accept() or return; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
238 |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
239 alarm(0); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
240 }; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
241 alarm(0); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
242 if ($@) { |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
243 log_in("died: $@"); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
244 return undef; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
245 } |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
246 |
1303 | 247 log2c("(new connection $client)"); |
248 | |
249 $client->sysread(my $buf, 24) == 24 or return; # preface | |
250 | |
251 $c = Test::Nginx::HTTP2->new(1, socket => $client, | |
252 pure => 1, preface => "") or return; | |
253 } | |
254 | |
255 my $frames = $c->read(all => [{ fin => 4 }]); | |
256 | |
257 if (!$extra{reuse}) { | |
258 $c->h2_settings(0); | |
259 $c->h2_settings(1); | |
260 } | |
261 | |
262 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
263 $sid = $frame->{sid}; | |
264 return $frames; | |
265 }; | |
266 $f->{data} = sub { | |
267 my ($body, %extra) = @_; | |
268 $s->h2_body($body, { %extra }); | |
269 return $c->read(all => [{ sid => $sid, | |
270 length => length($body) }]); | |
271 }; | |
272 $f->{http_end} = sub { | |
273 $c->new_stream({ body_more => 1, headers => [ | |
274 { name => ':status', value => '200', mode => 0 }, | |
275 { name => 'content-type', value => 'application/grpc', | |
276 mode => 1, huff => 1 }, | |
277 ]}, $sid); | |
278 $c->h2_body('Hello world', { body_more => 1 }); | |
279 $c->new_stream({ headers => [ | |
280 { name => 'grpc-status', value => '0', | |
281 mode => 2, huff => 1 }, | |
282 { name => 'grpc-message', value => '', | |
283 mode => 2, huff => 1 }, | |
284 ]}, $sid); | |
285 | |
286 return $s->read(all => [{ fin => 1 }]); | |
287 }; | |
288 return $f; | |
289 } | |
290 | |
291 sub log2i { Test::Nginx::log_core('|| <<', @_); } | |
292 sub log2o { Test::Nginx::log_core('|| >>', @_); } | |
293 sub log2c { Test::Nginx::log_core('||', @_); } | |
294 | |
295 ############################################################################### |