Mercurial > hg > nginx-tests
annotate h2.t @ 712:649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Otherwise, perl reacts badly on dereferencing an undefined value.
Notably, this can happen due to an nginx bug in HTTP/2 that leads
to premature connection close and is already noted in tests with
todo_alerts().
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 24 Sep 2015 16:05:19 +0300 |
parents | 01e5d5717815 |
children | ccc9f389e1f8 |
rev | line source |
---|---|
646 | 1 #!/usr/bin/perl |
2 | |
3 # (C) Sergey Kandaurov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Tests for HTTP/2 protocol [RFC7540]. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use Test::More; | |
14 | |
15 use IO::Select; | |
16 use Socket qw/ CRLF /; | |
17 | |
18 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
19 | |
20 use lib 'lib'; | |
21 use Test::Nginx; | |
22 | |
23 ############################################################################### | |
24 | |
25 select STDERR; $| = 1; | |
26 select STDOUT; $| = 1; | |
27 | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
28 eval { require IO::Socket::SSL; }; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
29 plan(skip_all => 'IO::Socket::SSL not installed') if $@; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
30 eval { IO::Socket::SSL::SSL_VERIFY_NONE(); }; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
31 plan(skip_all => 'IO::Socket::SSL too old') if $@; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
32 |
646 | 33 my $t = Test::Nginx->new()->has(qw/http http_ssl http_v2 proxy cache/) |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
34 ->has(qw/limit_conn rewrite realip shmem/) |
704
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
35 ->has_daemon('openssl')->plan(196); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
36 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
37 # FreeBSD has a bug in not treating zero iovcnt as EINVAL |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
38 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
39 $t->todo_alerts() unless $^O eq 'freebsd'; |
646 | 40 |
41 $t->write_file_expand('nginx.conf', <<'EOF'); | |
42 | |
43 %%TEST_GLOBALS%% | |
44 | |
45 daemon off; | |
46 | |
47 events { | |
48 } | |
49 | |
50 http { | |
51 %%TEST_GLOBALS_HTTP%% | |
52 | |
53 proxy_cache_path %%TESTDIR%%/cache keys_zone=NAME:1m; | |
54 limit_conn_zone $binary_remote_addr zone=conn:1m; | |
55 | |
56 server { | |
57 listen 127.0.0.1:8080 http2; | |
58 listen 127.0.0.1:8081; | |
59 listen 127.0.0.1:8082 proxy_protocol http2; | |
60 listen 127.0.0.1:8084 http2 ssl; | |
61 server_name localhost; | |
62 | |
63 ssl_certificate_key localhost.key; | |
64 ssl_certificate localhost.crt; | |
696
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
65 http2_max_field_size 128k; |
698
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
66 http2_max_header_size 128k; |
646 | 67 |
68 location / { | |
69 add_header X-Header X-Foo; | |
70 add_header X-Sent-Foo $http_x_foo; | |
71 add_header X-Referer $http_referer; | |
72 return 200 'body'; | |
73 } | |
74 location /t { | |
75 } | |
76 location /t3.html { | |
77 limit_conn conn 1; | |
78 } | |
79 location /gzip.html { | |
80 gzip on; | |
81 gzip_min_length 0; | |
82 alias %%TESTDIR%%/t2.html; | |
83 } | |
680
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
84 location /frame_size { |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
85 http2_chunk_size 64k; |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
86 alias %%TESTDIR%%/t1.html; |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
87 output_buffers 2 1m; |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
88 } |
696
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
89 location /continuation { |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
90 add_header X-LongHeader $arg_h; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
91 add_header X-LongHeader $arg_h; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
92 add_header X-LongHeader $arg_h; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
93 return 200 body; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
94 |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
95 location /continuation/204 { |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
96 return 204; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
97 } |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
98 } |
646 | 99 location /pp { |
100 set_real_ip_from 127.0.0.1/32; | |
101 real_ip_header proxy_protocol; | |
102 alias %%TESTDIR%%/t2.html; | |
103 add_header X-PP $remote_addr; | |
104 } | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
105 location /h2 { |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
106 return 200 $http2; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
107 } |
651
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
108 location /chunk_size { |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
109 http2_chunk_size 1; |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
110 return 200 'body'; |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
111 } |
646 | 112 location /redirect { |
113 error_page 405 /; | |
114 return 405; | |
115 } | |
116 location /return301 { | |
117 return 301; | |
118 } | |
119 location /return301_absolute { | |
120 return 301 text; | |
121 } | |
122 location /return301_relative { | |
123 return 301 /; | |
124 } | |
125 location /proxy/ { | |
126 add_header X-UC-a $upstream_cookie_a; | |
127 add_header X-UC-c $upstream_cookie_c; | |
128 proxy_pass http://127.0.0.1:8083/; | |
129 proxy_cache NAME; | |
130 proxy_cache_valid 1m; | |
652
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
131 proxy_set_header X-Cookie-a $cookie_a; |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
132 proxy_set_header X-Cookie-c $cookie_c; |
646 | 133 } |
134 location /proxy2/ { | |
135 add_header X-Body "$request_body"; | |
136 proxy_pass http://127.0.0.1:8081/; | |
137 proxy_cache NAME; | |
138 proxy_cache_valid 1m; | |
139 } | |
140 location /proxy_buffering_off { | |
141 proxy_pass http://127.0.0.1:8081/; | |
142 proxy_cache NAME; | |
143 proxy_cache_valid 1m; | |
144 proxy_buffering off; | |
145 } | |
146 location /set-cookie { | |
147 add_header Set-Cookie a=b; | |
148 add_header Set-Cookie c=d; | |
149 return 200; | |
150 } | |
151 location /cookie { | |
152 add_header X-Cookie $http_cookie; | |
153 add_header X-Cookie-a $cookie_a; | |
154 add_header X-Cookie-c $cookie_c; | |
155 return 200; | |
156 } | |
157 } | |
158 | |
159 server { | |
160 listen 127.0.0.1:8085 http2; | |
161 server_name localhost; | |
162 return 200 first; | |
163 } | |
164 | |
165 server { | |
166 listen 127.0.0.1:8085 http2; | |
167 server_name localhost2; | |
168 return 200 second; | |
169 } | |
654
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
170 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
171 server { |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
172 listen 127.0.0.1:8086 http2; |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
173 server_name localhost; |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
174 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
175 http2_max_concurrent_streams 1; |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
176 } |
684
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
177 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
178 server { |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
179 listen 127.0.0.1:8087 http2; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
180 server_name localhost; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
181 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
182 http2_max_field_size 32; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
183 } |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
184 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
185 server { |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
186 listen 127.0.0.1:8088 http2; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
187 server_name localhost; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
188 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
189 http2_max_header_size 64; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
190 } |
646 | 191 } |
192 | |
193 EOF | |
194 | |
195 $t->write_file('openssl.conf', <<EOF); | |
196 [ req ] | |
197 default_bits = 2048 | |
198 encrypt_key = no | |
199 distinguished_name = req_distinguished_name | |
200 [ req_distinguished_name ] | |
201 EOF | |
202 | |
203 my $d = $t->testdir(); | |
204 | |
205 foreach my $name ('localhost') { | |
206 system('openssl req -x509 -new ' | |
207 . "-config '$d/openssl.conf' -subj '/CN=$name/' " | |
208 . "-out '$d/$name.crt' -keyout '$d/$name.key' " | |
209 . ">>$d/openssl.out 2>&1") == 0 | |
210 or die "Can't create certificate for $name: $!\n"; | |
211 } | |
212 | |
213 $t->run_daemon(\&http_daemon); | |
214 $t->run()->waitforsocket('127.0.0.1:8083'); | |
215 | |
216 # file size is slightly beyond initial window size: 2**16 + 80 bytes | |
217 | |
218 $t->write_file('t1.html', | |
219 join('', map { sprintf "X%04dXXX", $_ } (1 .. 8202))); | |
220 $t->write_file('tbig.html', | |
704
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
221 join('', map { sprintf "XX%06dXX", $_ } (1 .. 100000))); |
646 | 222 |
223 $t->write_file('t2.html', 'SEE-THIS'); | |
224 $t->write_file('t3.html', 'SEE-THIS'); | |
225 | |
226 my %cframe = ( | |
227 0 => { name => 'DATA', value => \&data }, | |
228 1 => { name => 'HEADERS', value => \&headers }, | |
229 # 2 => { name => 'PRIORITY', value => \&priority }, | |
230 3 => { name => 'RST_STREAM', value => \&rst_stream }, | |
231 4 => { name => 'SETTINGS', value => \&settings }, | |
232 # 5 => { name => 'PUSH_PROIMSE', value => \&push_promise }, | |
233 6 => { name => 'PING', value => \&ping }, | |
234 7 => { name => 'GOAWAY', value => \&goaway }, | |
235 8 => { name => 'WINDOW_UPDATE', value => \&window_update }, | |
696
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
236 9 => { name => 'CONTINUATION', value => \&headers }, |
646 | 237 ); |
238 | |
239 ############################################################################### | |
240 | |
241 # SETTINGS | |
242 | |
243 my $sess = new_session(); | |
244 my $frames = h2_read($sess, all => [ | |
245 { type => 'WINDOW_UPDATE' }, | |
246 { type => 'SETTINGS'} | |
247 ]); | |
248 | |
249 my ($frame) = grep { $_->{type} eq 'WINDOW_UPDATE' } @$frames; | |
250 ok($frame, 'WINDOW_UPDATE frame'); | |
251 is($frame->{flags}, 0, 'WINDOW_UPDATE zero flags'); | |
252 is($frame->{sid}, 0, 'WINDOW_UPDATE zero sid'); | |
253 is($frame->{length}, 4, 'WINDOW_UPDATE fixed length'); | |
254 | |
255 ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; | |
256 ok($frame, 'SETTINGS frame'); | |
257 is($frame->{flags}, 0, 'SETTINGS flags'); | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
258 is($frame->{sid}, 0, 'SETTINGS stream'); |
646 | 259 |
260 h2_settings($sess, 1); | |
261 h2_settings($sess, 0); | |
262 | |
263 $frames = h2_read($sess, all => [{ type => 'SETTINGS' }]); | |
264 | |
265 ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; | |
266 ok($frame, 'SETTINGS frame ack'); | |
267 is($frame->{flags}, 1, 'SETTINGS flags ack'); | |
268 | |
269 # PING | |
270 | |
271 h2_ping($sess, 'SEE-THIS'); | |
272 $frames = h2_read($sess, all => [{ type => 'PING' }]); | |
273 | |
274 ($frame) = grep { $_->{type} eq "PING" } @$frames; | |
275 ok($frame, 'PING frame'); | |
276 is($frame->{value}, 'SEE-THIS', 'PING payload'); | |
277 is($frame->{flags}, 1, 'PING flags ack'); | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
278 is($frame->{sid}, 0, 'PING stream'); |
646 | 279 |
280 # GET | |
281 | |
282 my $sid = new_stream($sess); | |
283 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
284 | |
285 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
286 ok($frame, 'HEADERS frame'); | |
287 is($frame->{sid}, $sid, 'HEADERS stream'); | |
288 is($frame->{headers}->{':status'}, 200, 'HEADERS status'); | |
289 is($frame->{headers}->{'x-header'}, 'X-Foo', 'HEADERS header'); | |
290 | |
291 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
292 ok($frame, 'DATA frame'); | |
293 is($frame->{length}, length 'body', 'DATA length'); | |
294 is($frame->{data}, 'body', 'DATA payload'); | |
295 | |
296 # GET in the new stream on same connection | |
297 | |
298 $sid = new_stream($sess); | |
299 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
300 | |
301 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
302 is($frame->{sid}, $sid, 'HEADERS stream 2'); | |
303 is($frame->{headers}->{':status'}, 200, 'HEADERS status 2'); | |
304 is($frame->{headers}->{'x-header'}, 'X-Foo', 'HEADERS header 2'); | |
305 | |
306 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
307 ok($frame, 'DATA frame 2'); | |
308 is($frame->{sid}, $sid, 'HEADERS stream 2'); | |
309 is($frame->{length}, length 'body', 'DATA length 2'); | |
310 is($frame->{data}, 'body', 'DATA payload 2'); | |
311 | |
312 # various HEADERS compression/encoding, see hpack() for mode details | |
313 | |
314 # 6.1. Indexed Header Field Representation | |
315 | |
316 $sid = new_stream($sess, { headers => [ | |
317 { name => ':method', value => 'GET', mode => 0 }, | |
318 { name => ':scheme', value => 'http', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
319 { name => ':path', value => '/', mode => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
320 { name => ':authority', value => 'localhost', mode => 1 }]}); |
646 | 321 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
322 | |
323 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
324 is($frame->{headers}->{':status'}, 200, 'indexed header field'); | |
325 | |
326 # 6.2.1. Literal Header Field with Incremental Indexing | |
327 | |
328 $sid = new_stream($sess, { headers => [ | |
329 { name => ':method', value => 'GET', mode => 1, huff => 0 }, | |
330 { name => ':scheme', value => 'http', mode => 1, huff => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
331 { name => ':path', value => '/', mode => 1, huff => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
332 { name => ':authority', value => 'localhost', mode => 1, huff => 0 }]}); |
646 | 333 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
334 | |
335 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
336 is($frame->{headers}->{':status'}, 200, 'literal with indexing'); | |
337 | |
338 $sid = new_stream($sess, { headers => [ | |
339 { name => ':method', value => 'GET', mode => 1, huff => 1 }, | |
340 { name => ':scheme', value => 'http', mode => 1, huff => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
341 { name => ':path', value => '/', mode => 1, huff => 1 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
342 { name => ':authority', value => 'localhost', mode => 1, huff => 1 }]}); |
646 | 343 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
344 | |
345 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
346 is($frame->{headers}->{':status'}, 200, 'literal with indexing - huffman'); | |
347 | |
348 # 6.2.1. Literal Header Field with Incremental Indexing -- New Name | |
349 | |
350 $sid = new_stream($sess, { headers => [ | |
351 { name => ':method', value => 'GET', mode => 2, huff => 0 }, | |
352 { name => ':scheme', value => 'http', mode => 2, huff => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
353 { name => ':path', value => '/', mode => 2, huff => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
354 { name => ':authority', value => 'localhost', mode => 2, huff => 0 }]}); |
646 | 355 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
356 | |
357 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
358 is($frame->{headers}->{':status'}, 200, 'literal with indexing - new'); | |
359 | |
360 $sid = new_stream($sess, { headers => [ | |
361 { name => ':method', value => 'GET', mode => 2, huff => 1 }, | |
362 { name => ':scheme', value => 'http', mode => 2, huff => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
363 { name => ':path', value => '/', mode => 2, huff => 1 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
364 { name => ':authority', value => 'localhost', mode => 2, huff => 1 }]}); |
646 | 365 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
366 | |
367 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
368 is($frame->{headers}->{':status'}, 200, 'literal with indexing - new huffman'); | |
369 | |
370 # 6.2.2. Literal Header Field without Indexing | |
371 | |
372 $sid = new_stream($sess, { headers => [ | |
373 { name => ':method', value => 'GET', mode => 3, huff => 0 }, | |
374 { name => ':scheme', value => 'http', mode => 3, huff => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
375 { name => ':path', value => '/', mode => 3, huff => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
376 { name => ':authority', value => 'localhost', mode => 3, huff => 0 }]}); |
646 | 377 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
378 | |
379 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
380 is($frame->{headers}->{':status'}, 200, 'literal without indexing'); | |
381 | |
382 $sid = new_stream($sess, { headers => [ | |
383 { name => ':method', value => 'GET', mode => 3, huff => 1 }, | |
384 { name => ':scheme', value => 'http', mode => 3, huff => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
385 { name => ':path', value => '/', mode => 3, huff => 1 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
386 { name => ':authority', value => 'localhost', mode => 3, huff => 1 }]}); |
646 | 387 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
388 | |
389 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
390 is($frame->{headers}->{':status'}, 200, 'literal without indexing - huffman'); | |
391 | |
392 # 6.2.2. Literal Header Field without Indexing -- New Name | |
393 | |
394 $sid = new_stream($sess, { headers => [ | |
395 { name => ':method', value => 'GET', mode => 4, huff => 0 }, | |
396 { name => ':scheme', value => 'http', mode => 4, huff => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
397 { name => ':path', value => '/', mode => 4, huff => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
398 { name => ':authority', value => 'localhost', mode => 4, huff => 0 }]}); |
646 | 399 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
400 | |
401 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
402 is($frame->{headers}->{':status'}, 200, 'literal without indexing - new'); | |
403 | |
404 $sid = new_stream($sess, { headers => [ | |
405 { name => ':method', value => 'GET', mode => 4, huff => 1 }, | |
406 { name => ':scheme', value => 'http', mode => 4, huff => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
407 { name => ':path', value => '/', mode => 4, huff => 1 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
408 { name => ':authority', value => 'localhost', mode => 4, huff => 1 }]}); |
646 | 409 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
410 | |
411 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
412 is($frame->{headers}->{':status'}, 200, 'literal without indexing - new huffman'); | |
413 | |
414 # 6.2.3. Literal Header Field Never Indexed | |
415 | |
416 $sid = new_stream($sess, { headers => [ | |
417 { name => ':method', value => 'GET', mode => 5, huff => 0 }, | |
418 { name => ':scheme', value => 'http', mode => 5, huff => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
419 { name => ':path', value => '/', mode => 5, huff => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
420 { name => ':authority', value => 'localhost', mode => 5, huff => 0 }]}); |
646 | 421 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
422 | |
423 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
424 is($frame->{headers}->{':status'}, 200, 'literal never indexed'); | |
425 | |
426 $sid = new_stream($sess, { headers => [ | |
427 { name => ':method', value => 'GET', mode => 5, huff => 1 }, | |
428 { name => ':scheme', value => 'http', mode => 5, huff => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
429 { name => ':path', value => '/', mode => 5, huff => 1 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
430 { name => ':authority', value => 'localhost', mode => 5, huff => 1 }]}); |
646 | 431 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
432 | |
433 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
434 is($frame->{headers}->{':status'}, 200, 'literal never indexed - huffman'); | |
435 | |
436 # 6.2.2. Literal Header Field Never Indexed -- New Name | |
437 | |
438 $sid = new_stream($sess, { headers => [ | |
439 { name => ':method', value => 'GET', mode => 6, huff => 0 }, | |
440 { name => ':scheme', value => 'http', mode => 6, huff => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
441 { name => ':path', value => '/', mode => 6, huff => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
442 { name => ':authority', value => 'localhost', mode => 6, huff => 0 }]}); |
646 | 443 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
444 | |
445 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
446 is($frame->{headers}->{':status'}, 200, 'literal never indexed - new'); | |
447 | |
448 $sid = new_stream($sess, { headers => [ | |
449 { name => ':method', value => 'GET', mode => 6, huff => 1 }, | |
450 { name => ':scheme', value => 'http', mode => 6, huff => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
451 { name => ':path', value => '/', mode => 6, huff => 1 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
452 { name => ':authority', value => 'localhost', mode => 6, huff => 1 }]}); |
646 | 453 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
454 | |
455 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
456 is($frame->{headers}->{':status'}, 200, 'literal never indexed - new huffman'); | |
457 | |
458 # reuse literal with indexing | |
459 | |
460 $sess = new_session(); | |
461 $sid = new_stream($sess, { headers => [ | |
462 { name => ':method', value => 'GET', mode => 0 }, | |
463 { name => ':scheme', value => 'http', mode => 0 }, | |
464 { name => ':path', value => '/', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
465 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 466 { name => 'referer', value => 'foo', mode => 1 }]}); |
467 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
468 | |
469 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
470 is($frame->{headers}->{'x-referer'}, 'foo', 'value with indexing - new'); | |
471 | |
472 $sid = new_stream($sess, { headers => [ | |
473 { name => ':method', value => 'GET', mode => 0 }, | |
474 { name => ':scheme', value => 'http', mode => 0 }, | |
475 { name => ':path', value => '/', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
476 { name => ':authority', value => 'localhost', mode => 0 }, |
646 | 477 { name => 'referer', value => 'foo', mode => 0 }]}); |
478 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
479 | |
480 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
481 is($frame->{headers}->{'x-referer'}, 'foo', 'value with indexing - indexed'); | |
482 | |
483 $sid = new_stream($sess, { headers => [ | |
484 { name => ':method', value => 'GET', mode => 0 }, | |
485 { name => ':scheme', value => 'http', mode => 0 }, | |
486 { name => ':path', value => '/', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
487 { name => ':authority', value => 'localhost', mode => 0 }, |
646 | 488 { name => 'x-foo', value => 'X-Bar', mode => 2 }]}); |
489 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
490 | |
491 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
492 is($frame->{headers}->{'x-sent-foo'}, 'X-Bar', 'name with indexing - new'); | |
493 | |
494 # reuse literal with indexing - reused name | |
495 | |
496 $sid = new_stream($sess, { headers => [ | |
497 { name => ':method', value => 'GET', mode => 0 }, | |
498 { name => ':scheme', value => 'http', mode => 0 }, | |
499 { name => ':path', value => '/', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
500 { name => ':authority', value => 'localhost', mode => 0 }, |
646 | 501 { name => 'x-foo', value => 'X-Bar', mode => 0 }]}); |
502 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
503 | |
504 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
505 is($frame->{headers}->{'x-sent-foo'}, 'X-Bar', 'name with indexing - indexed'); | |
506 | |
507 # 6.3. Dynamic Table Size Update | |
508 | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
509 # remove some indexed headers from the dynamic table |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
510 # by maintaining dynamic table space only for index 0 |
646 | 511 # 'x-foo' has index 0, and 'referer' has index 1 |
512 | |
513 $sid = new_stream($sess, { table_size => 61, headers => [ | |
514 { name => ':method', value => 'GET', mode => 0 }, | |
515 { name => ':scheme', value => 'http', mode => 0 }, | |
516 { name => ':path', value => '/', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
517 { name => 'x-foo', value => 'X-Bar', mode => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
518 { name => ':authority', value => 'localhost', mode => 1 }]}); |
646 | 519 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
520 | |
521 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
522 isnt($frame, undef, 'updated table size - remaining index'); | |
523 | |
524 $sid = new_stream($sess, { headers => [ | |
525 { name => ':method', value => 'GET', mode => 0 }, | |
526 { name => ':scheme', value => 'http', mode => 0 }, | |
527 { name => ':path', value => '/', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
528 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 529 { name => 'referer', value => 'foo', mode => 0 }]}); |
530 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
531 | |
532 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
672
66f94d6c5047
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
671
diff
changeset
|
533 is($frame, undef, 'invalid index'); |
646 | 534 |
535 # 5.4.1. Connection Error Handling | |
536 # An endpoint that encounters a connection error SHOULD first send a | |
537 # GOAWAY frame <..> | |
538 | |
539 ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; | |
672
66f94d6c5047
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
671
diff
changeset
|
540 ok($frame, 'invalid index - GOAWAY'); |
646 | 541 |
691
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
542 # RFC 7541, 2.3.3. Index Address Space |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
543 # Indices strictly greater than the sum of the lengths of both tables |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
544 # MUST be treated as a decoding error. |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
545 |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
546 # 4.3. Header Compression and Decompression |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
547 # A decoding error in a header block MUST be treated |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
548 # as a connection error of type COMPRESSION_ERROR. |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
549 |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
550 is($frame->{last_sid}, $sid, 'invalid index - GOAWAY last stream'); |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
551 is($frame->{code}, 9, 'invalid index - GOAWAY COMPRESSION_ERROR'); |
3f4a132c6463
Tests: extended HTTP/2 tests for GOAWAY on compression error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
685
diff
changeset
|
552 |
646 | 553 # HEAD |
554 | |
555 $sess = new_session(); | |
556 $sid = new_stream($sess, { method => 'HEAD' }); | |
557 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); | |
558 | |
559 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
560 is($frame->{sid}, $sid, 'HEAD - HEADERS'); | |
561 is($frame->{headers}->{':status'}, 200, 'HEAD - HEADERS status'); | |
562 is($frame->{headers}->{'x-header'}, 'X-Foo', 'HEAD - HEADERS header'); | |
563 | |
564 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
565 is($frame, undef, 'HEAD - no body'); | |
566 | |
567 # GET with PROXY protocol | |
568 | |
569 my $proxy = 'PROXY TCP4 192.0.2.1 192.0.2.2 1234 5678' . CRLF; | |
570 $sess = new_session(8082, proxy => $proxy); | |
571 $sid = new_stream($sess, { path => '/pp' }); | |
572 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
573 | |
574 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
575 ok($frame, 'PROXY HEADERS frame'); | |
576 is($frame->{headers}->{'x-pp'}, '192.0.2.1', 'PROXY remote addr'); | |
577 | |
578 # range filter | |
579 | |
580 $sess = new_session(); | |
581 $sid = new_stream($sess, { headers => [ | |
582 { name => ':method', value => 'GET', mode => 0 }, | |
583 { name => ':scheme', value => 'http', mode => 0 }, | |
584 { name => ':path', value => '/t1.html', mode => 1 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
585 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 586 { name => 'range', value => 'bytes=10-19', mode => 1 }]}); |
587 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
588 | |
589 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
590 is($frame->{headers}->{':status'}, 206, 'range - HEADERS status'); | |
591 | |
592 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
593 is($frame->{length}, 10, 'range - DATA length'); | |
594 is($frame->{data}, '002XXXX000', 'range - DATA payload'); | |
595 | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
596 # $http2 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
597 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
598 $sess = new_session(); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
599 $sid = new_stream($sess, { path => '/h2' }); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
600 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
601 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
602 ($frame) = grep { $_->{type} eq "DATA" } @$frames; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
603 is($frame->{data}, 'h2c', 'http variable - h2c'); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
604 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
605 # SSL/TLS connection, NPN |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
606 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
607 SKIP: { |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
608 eval { IO::Socket::SSL->can_npn() or die; }; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
609 skip 'OpenSSL NPN support required', 1 if $@; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
610 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
611 $sess = new_session(8084, SSL => 1, npn => 'h2'); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
612 $sid = new_stream($sess, { path => '/h2' }); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
613 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
614 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
615 ($frame) = grep { $_->{type} eq "DATA" } @$frames; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
616 is($frame->{data}, 'h2', 'http variable - npn'); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
617 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
618 } |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
619 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
620 # SSL/TLS connection, ALPN |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
621 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
622 SKIP: { |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
623 eval { IO::Socket::SSL->can_alpn() or die; }; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
624 skip 'OpenSSL ALPN support required', 1 if $@; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
625 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
626 $sess = new_session(8084, SSL => 1, alpn => 'h2'); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
627 $sid = new_stream($sess, { path => '/h2' }); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
628 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
629 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
630 ($frame) = grep { $_->{type} eq "DATA" } @$frames; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
631 is($frame->{data}, 'h2', 'http variable - alpn'); |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
632 |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
633 } |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
634 |
651
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
635 # http2_chunk_size=1 |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
636 |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
637 $sess = new_session(); |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
638 $sid = new_stream($sess, { path => '/chunk_size' }); |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
639 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
640 |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
641 my @data = grep { $_->{type} eq "DATA" } @$frames; |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
642 is(@data, 4, 'chunk_size frames'); |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
643 is(join(' ', map { $_->{data} } @data), 'b o d y', 'chunk_size data'); |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
644 is(join(' ', map { $_->{flags} } @data), '0 0 0 1', 'chunk_size flags'); |
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
645 |
646 | 646 # CONTINUATION |
647 | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
648 $sess = new_session(); |
646 | 649 $sid = new_stream($sess, { continuation => 1, headers => [ |
650 { name => ':method', value => 'HEAD', mode => 1 }, | |
651 { name => ':scheme', value => 'http', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
652 { name => ':path', value => '/', mode => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
653 { name => ':authority', value => 'localhost', mode => 1 }]}); |
646 | 654 h2_continue($sess, $sid, { continuation => 1, headers => [ |
655 { name => 'x-foo', value => 'X-Bar', mode => 2 }]}); | |
656 h2_continue($sess, $sid, { headers => [ | |
657 { name => 'referer', value => 'foo', mode => 2 }]}); | |
658 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
659 | |
660 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
661 is($frame, undef, 'CONTINUATION - fragment 1'); | |
662 | |
663 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
664 is($frame->{headers}->{'x-sent-foo'}, 'X-Bar', 'CONTINUATION - fragment 2'); | |
665 is($frame->{headers}->{'x-referer'}, 'foo', 'CONTINUATION - fragment 3'); | |
666 | |
699
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
667 # CONTINUATION - in the middle of request header field |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
668 |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
669 $sess = new_session(); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
670 $sid = new_stream($sess, { continuation => [ 2, 4, 1, 5 ], headers => [ |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
671 { name => ':method', value => 'HEAD', mode => 1 }, |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
672 { name => ':scheme', value => 'http', mode => 0 }, |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
673 { name => ':path', value => '/', mode => 0 }, |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
674 { name => ':authority', value => 'localhost', mode => 1 }]}); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
675 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
676 |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
677 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
678 is($frame->{headers}->{':status'}, 200, 'CONTINUATION - in header field'); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
679 |
646 | 680 # frame padding |
681 | |
682 $sess = new_session(); | |
683 $sid = new_stream($sess, { padding => 42, headers => [ | |
684 { name => ':method', value => 'GET', mode => 0 }, | |
685 { name => ':scheme', value => 'http', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
686 { name => ':path', value => '/', mode => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
687 { name => ':authority', value => 'localhost', mode => 1 }]}); |
646 | 688 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
689 | |
690 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
691 is($frame->{headers}->{':status'}, 200, 'padding - HEADERS status'); | |
692 | |
693 $sid = new_stream($sess, { headers => [ | |
694 { name => ':method', value => 'GET', mode => 0 }, | |
695 { name => ':scheme', value => 'http', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
696 { name => ':path', value => '/', mode => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
697 { name => ':authority', value => 'localhost', mode => 1 }]}); |
646 | 698 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
699 | |
700 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
701 is($frame->{headers}->{':status'}, 200, 'padding - next stream'); | |
702 | |
703 # request header field with multiple values | |
704 | |
705 # 8.1.2.5. Compressing the Cookie Header Field | |
706 # To allow for better compression efficiency, the Cookie header field | |
707 # MAY be split into separate header fields <..>. | |
708 | |
709 $sess = new_session(); | |
710 $sid = new_stream($sess, { headers => [ | |
711 { name => ':method', value => 'GET', mode => 0 }, | |
712 { name => ':scheme', value => 'http', mode => 0 }, | |
713 { name => ':path', value => '/cookie', mode => 2 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
714 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 715 { name => 'cookie', value => 'a=b', mode => 2}, |
716 { name => 'cookie', value => 'c=d', mode => 2}]}); | |
717 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
718 | |
719 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
720 is($frame->{headers}->{'x-cookie-a'}, 'b', | |
721 'multiple request header fields - cookie'); | |
722 is($frame->{headers}->{'x-cookie-c'}, 'd', | |
723 'multiple request header fields - cookie 2'); | |
724 is($frame->{headers}->{'x-cookie'}, 'a=b; c=d', | |
725 'multiple request header fields - semi-colon'); | |
726 | |
727 # request header field with multiple values to HTTP backend | |
728 | |
729 # 8.1.2.5. Compressing the Cookie Header Field | |
730 # these MUST be concatenated into a single octet string | |
731 # using the two-octet delimiter of 0x3B, 0x20 (the ASCII string "; ") | |
732 # before being passed into a non-HTTP/2 context, such as an HTTP/1.1 | |
733 # connection <..> | |
734 | |
735 $sess = new_session(); | |
736 $sid = new_stream($sess, { headers => [ | |
737 { name => ':method', value => 'GET', mode => 0 }, | |
738 { name => ':scheme', value => 'http', mode => 0 }, | |
739 { name => ':path', value => '/proxy/cookie', mode => 2 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
740 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 741 { name => 'cookie', value => 'a=b', mode => 2 }, |
742 { name => 'cookie', value => 'c=d', mode => 2 }]}); | |
743 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
744 | |
745 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
652
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
746 is($frame->{headers}->{'x-sent-cookie'}, 'a=b; c=d', |
646 | 747 'multiple request header fields proxied - semi-colon'); |
652
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
748 is($frame->{headers}->{'x-sent-cookie2'}, '', |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
749 'multiple request header fields proxied - dublicate cookie'); |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
750 is($frame->{headers}->{'x-sent-cookie-a'}, 'b', |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
751 'multiple request header fields proxied - cookie 1'); |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
752 is($frame->{headers}->{'x-sent-cookie-c'}, 'd', |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
753 'multiple request header fields proxied - cookie 2'); |
646 | 754 |
755 # response header field with multiple values | |
756 | |
757 $sess = new_session(); | |
758 $sid = new_stream($sess, { path => '/set-cookie' }); | |
759 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
760 | |
761 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
762 is($frame->{headers}->{'set-cookie'}[0], 'a=b', | |
763 'multiple response header fields - cookie'); | |
764 is($frame->{headers}->{'set-cookie'}[1], 'c=d', | |
765 'multiple response header fields - cookie 2'); | |
766 | |
767 # response header field with multiple values from HTTP backend | |
768 | |
769 $sess = new_session(); | |
770 $sid = new_stream($sess, { path => '/proxy/set-cookie' }); | |
771 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
772 | |
773 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
774 is($frame->{headers}->{'set-cookie'}[0], 'a=b', | |
775 'multiple response header proxied - cookie'); | |
776 is($frame->{headers}->{'set-cookie'}[1], 'c=d', | |
777 'multiple response header proxied - cookie 2'); | |
778 is($frame->{headers}->{'x-uc-a'}, 'b', | |
779 'multiple response header proxied - upstream cookie'); | |
780 is($frame->{headers}->{'x-uc-c'}, 'd', | |
781 'multiple response header proxied - upstream cookie 2'); | |
782 | |
783 # internal redirect | |
784 | |
785 $sess = new_session(); | |
786 $sid = new_stream($sess, { path => '/redirect' }); | |
787 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
788 | |
789 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
790 is($frame->{headers}->{':status'}, 405, 'redirect - HEADERS'); | |
791 | |
792 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
793 ok($frame, 'redirect - DATA'); | |
794 is($frame->{data}, 'body', 'redirect - DATA payload'); | |
795 | |
796 # return 301 with absolute URI | |
797 | |
798 $sess = new_session(); | |
799 $sid = new_stream($sess, { path => '/return301_absolute' }); | |
800 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
801 | |
802 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
803 is($frame->{headers}->{':status'}, 301, 'return 301 absolute - status'); | |
804 is($frame->{headers}->{'location'}, 'text', 'return 301 absolute - location'); | |
805 | |
806 # return 301 with relative URI | |
807 | |
808 $sess = new_session(); | |
809 $sid = new_stream($sess, { path => '/return301_relative' }); | |
810 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
811 | |
812 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
813 is($frame->{headers}->{':status'}, 301, 'return 301 relative - status'); | |
814 is($frame->{headers}->{'location'}, 'http://127.0.0.1:8080/', | |
815 'return 301 relative - location'); | |
816 | |
817 # return 301 with relative URI and ':authority' request header field | |
818 | |
819 $sess = new_session(); | |
820 $sid = new_stream($sess, { headers => [ | |
821 { name => ':method', value => 'GET', mode => 0 }, | |
822 { name => ':scheme', value => 'http', mode => 0 }, | |
823 { name => ':path', value => '/return301_relative', mode => 2 }, | |
824 { name => ':authority', value => 'localhost', mode => 2 }]}); | |
825 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
826 | |
827 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
828 is($frame->{headers}->{':status'}, 301, | |
829 'return 301 relative - authority - status'); | |
830 is($frame->{headers}->{'location'}, 'http://localhost:8080/', | |
831 'return 301 relative - authority - location'); | |
832 | |
833 # return 301 with relative URI and 'host' request header field | |
834 | |
835 $sess = new_session(); | |
836 $sid = new_stream($sess, { headers => [ | |
837 { name => ':method', value => 'GET', mode => 0 }, | |
838 { name => ':scheme', value => 'http', mode => 0 }, | |
839 { name => ':path', value => '/return301_relative', mode => 2 }, | |
840 { name => 'host', value => 'localhost', mode => 2 }]}); | |
841 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
842 | |
843 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
844 is($frame->{headers}->{':status'}, 301, | |
845 'return 301 relative - host - status'); | |
846 is($frame->{headers}->{'location'}, 'http://localhost:8080/', | |
847 'return 301 relative - host - location'); | |
848 | |
849 # virtual host | |
850 | |
851 $sess = new_session(8085); | |
852 $sid = new_stream($sess, { headers => [ | |
853 { name => ':method', value => 'GET', mode => 0 }, | |
854 { name => ':scheme', value => 'http', mode => 0 }, | |
855 { name => ':path', value => '/', mode => 0 }, | |
856 { name => 'host', value => 'localhost', mode => 2 }]}); | |
857 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
858 | |
859 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
860 is($frame->{headers}->{':status'}, 200, | |
861 'virtual host - host - status'); | |
862 | |
863 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
864 is($frame->{data}, 'first', 'virtual host - host - DATA'); | |
865 | |
866 $sid = new_stream($sess, { headers => [ | |
867 { name => ':method', value => 'GET', mode => 0 }, | |
868 { name => ':scheme', value => 'http', mode => 0 }, | |
869 { name => ':path', value => '/', mode => 0 }, | |
870 { name => ':authority', value => 'localhost', mode => 2 }]}); | |
871 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
872 | |
873 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
874 is($frame->{headers}->{':status'}, 200, | |
875 'virtual host - authority - status'); | |
876 | |
877 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
878 is($frame->{data}, 'first', 'virtual host - authority - DATA'); | |
879 | |
880 # virtual host - second | |
881 | |
882 $sid = new_stream($sess, { headers => [ | |
883 { name => ':method', value => 'GET', mode => 0 }, | |
884 { name => ':scheme', value => 'http', mode => 0 }, | |
885 { name => ':path', value => '/', mode => 0 }, | |
886 { name => 'host', value => 'localhost2', mode => 2 }]}); | |
887 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
888 | |
889 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
890 is($frame->{headers}->{':status'}, 200, | |
891 'virtual host 2 - host - status'); | |
892 | |
893 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
894 is($frame->{data}, 'second', 'virtual host 2 - host - DATA'); | |
895 | |
896 $sid = new_stream($sess, { headers => [ | |
897 { name => ':method', value => 'GET', mode => 0 }, | |
898 { name => ':scheme', value => 'http', mode => 0 }, | |
899 { name => ':path', value => '/', mode => 0 }, | |
900 { name => ':authority', value => 'localhost2', mode => 2 }]}); | |
901 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
902 | |
903 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
904 is($frame->{headers}->{':status'}, 200, | |
905 'virtual host 2 - authority - status'); | |
906 | |
907 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
908 is($frame->{data}, 'second', 'virtual host 2 - authority - DATA'); | |
909 | |
910 # gzip tests for internal nginx version | |
911 | |
912 $sess = new_session(); | |
913 $sid = new_stream($sess, { headers => [ | |
914 { name => ':method', value => 'GET', mode => 0 }, | |
915 { name => ':scheme', value => 'http', mode => 0 }, | |
916 { name => ':path', value => '/gzip.html' }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
917 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 918 { name => 'accept-encoding', value => 'gzip' }]}); |
919 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
920 | |
921 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
922 is($frame->{headers}->{'content-encoding'}, 'gzip', 'gzip - encoding'); | |
923 | |
924 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
647
4e36550410b3
Tests: h2.t fixes for older perl versions, and gzip test.
Sergey Kandaurov <pluknet@nginx.com>
parents:
646
diff
changeset
|
925 gunzip_like($frame->{data}, qr/^SEE-THIS\Z/, 'gzip - DATA'); |
646 | 926 |
927 # simple proxy cache test | |
928 | |
929 $sess = new_session(); | |
930 $sid = new_stream($sess, { path => '/proxy2/t2.html?2' }); | |
931 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
932 | |
933 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
934 is($frame->{headers}->{':status'}, '200', 'proxy cache'); | |
935 | |
936 my $etag = $frame->{headers}->{'etag'}; | |
937 | |
938 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
939 is($frame->{length}, length 'SEE-THIS', 'proxy cache - DATA'); | |
940 is($frame->{data}, 'SEE-THIS', 'proxy cache - DATA payload'); | |
941 | |
942 $sid = new_stream($sess, { headers => [ | |
943 { name => ':method', value => 'GET', mode => 0 }, | |
944 { name => ':scheme', value => 'http', mode => 0 }, | |
945 { name => ':path', value => '/proxy2/t2.html?2' }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
946 { name => ':authority', value => 'localhost', mode => 1 }, |
646 | 947 { name => 'if-none-match', value => $etag }]}); |
948 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
949 | |
950 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
951 is($frame->{headers}->{':status'}, 304, 'proxy cache conditional'); | |
952 | |
953 # HEADERS could be received with fin, followed by DATA | |
954 | |
955 $sess = new_session(); | |
956 $sid = new_stream($sess, { path => '/proxy2/t2.html', method => 'HEAD' }); | |
957 | |
958 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
959 push @$frames, $_ for @{h2_read($sess, all => [{ sid => $sid }])}; | |
960 ok(!grep ({ $_->{type} eq "DATA" } @$frames), 'proxy cache HEAD - no body'); | |
961 | |
962 # HEAD on empty cache with proxy_buffering off | |
963 | |
964 $sess = new_session(); | |
965 $sid = new_stream($sess, | |
966 { path => '/proxy_buffering_off/t2.html?1', method => 'HEAD' }); | |
967 | |
968 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
969 push @$frames, $_ for @{h2_read($sess, all => [{ sid => $sid }])}; | |
970 ok(!grep ({ $_->{type} eq "DATA" } @$frames), | |
971 'proxy cache HEAD buffering off - no body'); | |
972 | |
973 # request body (uses proxied response) | |
974 | |
975 $sess = new_session(); | |
976 $sid = new_stream($sess, { path => '/proxy2/t2.html', body => 'TEST' }); | |
977 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
978 | |
979 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
980 is($frame->{headers}->{'x-body'}, 'TEST', 'request body'); | |
981 | |
982 # request body with padding (uses proxied response) | |
983 | |
984 $sess = new_session(); | |
985 $sid = new_stream($sess, | |
986 { path => '/proxy2/t2.html', body => 'TEST', body_padding => 42 }); | |
987 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
988 | |
989 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
990 is($frame->{headers}->{'x-body'}, 'TEST', 'request body with padding'); | |
991 | |
992 $sid = new_stream($sess); | |
993 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
994 | |
995 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
996 is($frame->{headers}->{':status'}, '200', 'request body with padding - next'); | |
997 | |
998 # initial window size, client side | |
999 | |
1000 # 6.9.2. Initial Flow-Control Window Size | |
1001 # When an HTTP/2 connection is first established, new streams are | |
1002 # created with an initial flow-control window size of 65,535 octets. | |
1003 # The connection flow-control window is also 65,535 octets. | |
1004 | |
1005 $sess = new_session(); | |
1006 $sid = new_stream($sess, { path => '/t1.html' }); | |
1007 $frames = h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1008 | |
1009 # with the default http2_chunk_size, data is divided into 8 data frames | |
1010 | |
651
9f66f0029dca
Tests: HTTP/2 tests for http2_chunk_size directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
650
diff
changeset
|
1011 @data = grep { $_->{type} eq "DATA" } @$frames; |
646 | 1012 my $lengths = join ' ', map { $_->{length} } @data; |
1013 is($lengths, '8192 8192 8192 8192 8192 8192 8192 8191', | |
1014 'iws - stream blocked on initial window size'); | |
1015 | |
1016 h2_ping($sess, 'SEE-THIS'); | |
1017 $frames = h2_read($sess, all => [{ type => 'PING' }]); | |
1018 | |
1019 ($frame) = grep { $_->{type} eq "PING" && $_->{flags} & 0x1 } @$frames; | |
1020 ok($frame, 'iws - PING not blocked'); | |
1021 | |
1022 h2_window($sess, 2**16, $sid); | |
1023 $frames = h2_read($sess); | |
1024 is(@$frames, 0, 'iws - updated stream window'); | |
1025 | |
1026 h2_window($sess, 2**16); | |
1027 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
1028 | |
1029 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1030 my $sum = eval join '+', map { $_->{length} } @data; | |
1031 is($sum, 81, 'iws - updated connection window'); | |
1032 | |
1033 # SETTINGS (initial window size, client side) | |
1034 | |
1035 # 6.9.2. Initial Flow-Control Window Size | |
1036 # Both endpoints can adjust the initial window size for new streams by | |
1037 # including a value for SETTINGS_INITIAL_WINDOW_SIZE in the SETTINGS | |
1038 # frame that forms part of the connection preface. The connection | |
1039 # flow-control window can only be changed using WINDOW_UPDATE frames. | |
1040 | |
1041 $sess = new_session(); | |
1042 h2_settings($sess, 0, 0x4 => 2**17); | |
1043 h2_window($sess, 2**17); | |
1044 | |
1045 $sid = new_stream($sess, { path => '/t1.html' }); | |
1046 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
1047 | |
1048 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1049 $sum = eval join '+', map { $_->{length} } @data; | |
1050 is($sum, 2**16 + 80, 'iws - increased'); | |
1051 | |
1052 # probe for negative available space in a flow control window | |
1053 | |
1054 # 6.9.2. Initial Flow-Control Window Size | |
1055 # A change to SETTINGS_INITIAL_WINDOW_SIZE can cause the available | |
1056 # space in a flow-control window to become negative. A sender MUST | |
1057 # track the negative flow-control window and MUST NOT send new flow- | |
1058 # controlled frames until it receives WINDOW_UPDATE frames that cause | |
1059 # the flow-control window to become positive. | |
1060 | |
1061 $sess = new_session(); | |
1062 $sid = new_stream($sess, { path => '/t1.html' }); | |
1063 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1064 | |
1065 h2_window($sess, 1); | |
1066 h2_settings($sess, 0, 0x4 => 42); | |
1067 h2_window($sess, 1024, $sid); | |
1068 | |
1069 $frames = h2_read($sess, all => [{ type => 'SETTINGS' }]); | |
1070 | |
1071 ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; | |
1072 ok($frame, 'negative window - SETTINGS frame ack'); | |
1073 is($frame->{flags}, 1, 'negative window - SETTINGS flags ack'); | |
1074 | |
1075 ($frame) = grep { $_->{type} ne 'SETTINGS' } @$frames; | |
1076 is($frame, undef, 'negative window - no data'); | |
1077 | |
1078 # predefined window size, minus new iws settings, minus window update | |
1079 | |
1080 h2_window($sess, 2**16 - 1 - 42 - 1024, $sid); | |
1081 | |
1082 $frames = h2_read($sess); | |
1083 is(@$frames, 0, 'zero window - no data'); | |
1084 | |
1085 h2_window($sess, 1, $sid); | |
1086 | |
1087 $frames = h2_read($sess, all => [{ sid => $sid, length => 1 }]); | |
1088 is(@$frames, 1, 'positive window'); | |
712
649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Sergey Kandaurov <pluknet@nginx.com>
parents:
707
diff
changeset
|
1089 |
649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Sergey Kandaurov <pluknet@nginx.com>
parents:
707
diff
changeset
|
1090 SKIP: { |
649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Sergey Kandaurov <pluknet@nginx.com>
parents:
707
diff
changeset
|
1091 skip 'failed connection', 2 unless @$frames; |
649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Sergey Kandaurov <pluknet@nginx.com>
parents:
707
diff
changeset
|
1092 |
646 | 1093 is(@$frames[0]->{type}, 'DATA', 'positive window - data'); |
1094 is(@$frames[0]->{length}, 1, 'positive window - data length'); | |
1095 | |
712
649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Sergey Kandaurov <pluknet@nginx.com>
parents:
707
diff
changeset
|
1096 } |
649af6069976
Tests: skipped some HTTP/2 tests is case of a failed connection.
Sergey Kandaurov <pluknet@nginx.com>
parents:
707
diff
changeset
|
1097 |
704
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1098 # ask write handler in sending large response |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1099 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1100 $sid = new_stream($sess, { path => '/tbig.html' }); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1101 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1102 h2_window($sess, 2**30, $sid); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1103 h2_window($sess, 2**30); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1104 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1105 sleep 1; |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1106 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1107 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1108 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1109 is($frame->{headers}->{':status'}, 200, 'large response - HEADERS'); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1110 |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1111 @data = grep { $_->{type} eq "DATA" } @$frames; |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1112 $sum = eval join '+', map { $_->{length} } @data; |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1113 is($sum, 1000000, 'large response - DATA'); |
626bc3a0fdaa
Tests: SPDY and HTTP/2 write handler tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
702
diff
changeset
|
1114 |
680
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1115 # SETTINGS_MAX_FRAME_SIZE |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1116 |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1117 $sess = new_session(); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1118 $sid = new_stream($sess, { path => '/frame_size' }); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1119 h2_window($sess, 2**18, 1); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1120 h2_window($sess, 2**18); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1121 |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1122 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1123 @data = grep { $_->{type} eq "DATA" } @$frames; |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1124 is($data[0]->{length}, 2**14, 'max frame size - default'); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1125 |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1126 $sess = new_session(); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1127 h2_settings($sess, 0, 0x5 => 2**15); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1128 $sid = new_stream($sess, { path => '/frame_size' }); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1129 h2_window($sess, 2**18, 1); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1130 h2_window($sess, 2**18); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1131 |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1132 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1133 @data = grep { $_->{type} eq "DATA" } @$frames; |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1134 is($data[0]->{length}, 2**15, 'max frame size - custom'); |
85e368105c8b
Tests: added HTTP/2 tests for SETTINGS_MAX_FRAME_SIZE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
679
diff
changeset
|
1135 |
696
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1136 # CONTINUATION in response |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1137 # put three long header fields (not less than SETTINGS_MAX_FRAME_SIZE/2) |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1138 # to break header block into separate frames, one such field per frame |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1139 |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1140 $sess = new_session(); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1141 $sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**13 }); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1142 |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1143 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1144 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1145 is(@data, 3, 'response CONTINUATION - header block frames'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1146 is($data[0]->{type}, 'HEADERS', 'response CONTINUATION - first'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1147 is($data[0]->{flags}, 0, 'response CONTINUATION - first flags'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1148 is($data[1]->{type}, 'CONTINUATION', 'response CONTINUATION - second'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1149 is($data[1]->{flags}, 0, 'response CONTINUATION - second flags'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1150 is($data[2]->{type}, 'CONTINUATION', 'response CONTINUATION - third'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1151 is($data[2]->{flags}, 4, 'response CONTINUATION - third flags'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1152 |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1153 # same but without response DATA frames |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1154 |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1155 $sess = new_session(); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1156 $sid = new_stream($sess, { path => '/continuation/204?h=' . 'x' x 2**13 }); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1157 |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1158 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1159 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1160 is(@data, 3, 'no body CONTINUATION - header block frames'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1161 is($data[0]->{type}, 'HEADERS', 'no body CONTINUATION - first'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1162 is($data[0]->{flags}, 1, 'no body CONTINUATION - first flags'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1163 is($data[1]->{type}, 'CONTINUATION', 'no body CONTINUATION - second'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1164 is($data[1]->{flags}, 0, 'no body CONTINUATION - second flags'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1165 is($data[2]->{type}, 'CONTINUATION', 'no body CONTINUATION - third'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1166 is($data[2]->{flags}, 4, 'no body CONTINUATION - third flags'); |
beab9da9b731
Tests: added HTTP/2 tests for CONTINUATION frame in response.
Sergey Kandaurov <pluknet@nginx.com>
parents:
694
diff
changeset
|
1167 |
698
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1168 # response header block is always split by SETTINGS_MAX_FRAME_SIZE |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1169 |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1170 TODO: { |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1171 local $TODO = 'not yet'; |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1172 |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1173 $sess = new_session(); |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1174 $sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**14 }); |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1175 |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1176 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1177 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1178 @data = sort { $a <=> $b } map { $_->{length} } @data; |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1179 cmp_ok($data[-1], '<=', 2**14, 'response header frames limited'); |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1180 |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1181 } |
f86c8314d205
Tests: one more HTTP/2 test for max frame size.
Sergey Kandaurov <pluknet@nginx.com>
parents:
697
diff
changeset
|
1182 |
684
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1183 # max_field_size |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1184 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1185 $sess = new_session(8087); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1186 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1187 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1188 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1189 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1190 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1191 { name => 'longname10', value => 'valu5' x 4 . 'x', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1192 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1193 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1194 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1195 ok($frame, 'field size less'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1196 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1197 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1198 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1199 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1200 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1201 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1202 { name => 'longname10', value => 'valu5' x 4 . 'x', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1203 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1204 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1205 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1206 ok($frame, 'field size second'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1207 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1208 $sess = new_session(8087); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1209 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1210 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1211 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1212 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1213 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1214 { name => 'longname10', value => 'valu5' x 4 . 'xx', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1215 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1216 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1217 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1218 ok($frame, 'field size equal'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1219 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1220 $sess = new_session(8087); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1221 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1222 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1223 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1224 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1225 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1226 { name => 'longname10', value => 'valu5' x 4 . 'xxx', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1227 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1228 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1229 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1230 is($frame, undef, 'field size greater'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1231 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1232 # max_header_size |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1233 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1234 $sess = new_session(8088); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1235 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1236 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1237 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1238 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1239 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1240 { name => 'longname9', value => 'x', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1241 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1242 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1243 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1244 ok($frame, 'header size less'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1245 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1246 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1247 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1248 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1249 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1250 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1251 { name => 'longname9', value => 'x', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1252 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1253 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1254 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1255 ok($frame, 'header size second'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1256 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1257 $sess = new_session(8088); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1258 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1259 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1260 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1261 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1262 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1263 { name => 'longname9', value => 'xx', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1264 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1265 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1266 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1267 ok($frame, 'header size equal'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1268 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1269 $sess = new_session(8088); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1270 $sid = new_stream($sess, { headers => [ |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1271 { name => ':method', value => 'GET', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1272 { name => ':scheme', value => 'http', mode => 0 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1273 { name => ':path', value => '/t2.html', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1274 { name => ':authority', value => 'localhost', mode => 1 }, |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1275 { name => 'longname9', value => 'xxx', mode => 2 }]}); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1276 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1277 |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1278 ($frame) = grep { $_->{type} eq 'DATA' } @$frames; |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1279 is($frame, undef, 'header size greater'); |
96666f621dbc
Tests: added http2_max_field_size and http2_max_header_size tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
680
diff
changeset
|
1280 |
646 | 1281 # stream multiplexing + WINDOW_UPDATE |
1282 | |
1283 $sess = new_session(); | |
1284 $sid = new_stream($sess, { path => '/t1.html' }); | |
1285 $frames = h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1286 | |
1287 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1288 $sum = eval join '+', map { $_->{length} } @data; | |
1289 is($sum, 2**16 - 1, 'multiple - stream1 data'); | |
1290 | |
1291 my $sid2 = new_stream($sess, { path => '/t1.html' }); | |
1292 $frames = h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1293 | |
1294 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1295 is(@data, 0, 'multiple - stream2 no data'); | |
1296 | |
1297 h2_window($sess, 2**17, $sid); | |
1298 h2_window($sess, 2**17, $sid2); | |
1299 h2_window($sess, 2**17); | |
1300 | |
1301 $frames = h2_read($sess, all => [ | |
1302 { sid => $sid, fin => 1 }, | |
1303 { sid => $sid2, fin => 1 } | |
1304 ]); | |
1305 | |
1306 @data = grep { $_->{type} eq "DATA" && $_->{sid} == $sid } @$frames; | |
1307 $sum = eval join '+', map { $_->{length} } @data; | |
1308 is($sum, 81, 'multiple - stream1 remain data'); | |
1309 | |
1310 @data = grep { $_->{type} eq "DATA" && $_->{sid} == $sid2 } @$frames; | |
1311 $sum = eval join '+', map { $_->{length} } @data; | |
1312 is($sum, 2**16 + 80, 'multiple - stream2 full data'); | |
1313 | |
1314 # stream muliplexing + PRIORITY frames | |
1315 | |
1316 $sess = new_session(); | |
1317 $sid = new_stream($sess, { path => '/t1.html' }); | |
1318 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1319 | |
1320 $sid2 = new_stream($sess, { path => '/t2.html' }); | |
1321 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1322 | |
1323 h2_priority($sess, 0, $sid); | |
1324 h2_priority($sess, 255, $sid2); | |
1325 | |
1326 h2_window($sess, 2**17, $sid); | |
1327 h2_window($sess, 2**17, $sid2); | |
1328 h2_window($sess, 2**17); | |
1329 | |
1330 $frames = h2_read($sess, all => [ | |
1331 { sid => $sid, fin => 1 }, | |
1332 { sid => $sid2, fin => 1 } | |
1333 ]); | |
1334 | |
1335 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1336 is(join(' ', map { $_->{sid} } @data), "$sid2 $sid", 'weight - PRIORITY 1'); | |
1337 | |
1338 # and vice versa | |
1339 | |
1340 $sess = new_session(); | |
1341 $sid = new_stream($sess, { path => '/t1.html' }); | |
1342 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1343 | |
1344 $sid2 = new_stream($sess, { path => '/t2.html' }); | |
1345 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1346 | |
1347 h2_priority($sess, 255, $sid); | |
1348 h2_priority($sess, 0, $sid2); | |
1349 | |
1350 h2_window($sess, 2**17, $sid); | |
1351 h2_window($sess, 2**17, $sid2); | |
1352 h2_window($sess, 2**17); | |
1353 | |
1354 $frames = h2_read($sess, all => [ | |
1355 { sid => $sid, fin => 1 }, | |
1356 { sid => $sid2, fin => 1 } | |
1357 ]); | |
1358 | |
1359 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1360 is(join(' ', map { $_->{sid} } @data), "$sid $sid2", 'weight - PRIORITY 2'); | |
1361 | |
1362 # stream muliplexing + HEADERS PRIORITY flag | |
1363 | |
1364 $sess = new_session(); | |
1365 $sid = new_stream($sess, { path => '/t1.html', prio => 0 }); | |
1366 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1367 | |
1368 $sid2 = new_stream($sess, { path => '/t2.html', prio => 255 }); | |
1369 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1370 | |
1371 h2_window($sess, 2**17, $sid); | |
1372 h2_window($sess, 2**17, $sid2); | |
1373 h2_window($sess, 2**17); | |
1374 | |
1375 $frames = h2_read($sess, all => [ | |
1376 { sid => $sid, fin => 1 }, | |
1377 { sid => $sid2, fin => 1 } | |
1378 ]); | |
1379 | |
1380 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1381 my $sids = join ' ', map { $_->{sid} } @data; | |
1382 is($sids, "$sid2 $sid", 'weight - HEADERS PRIORITY 1'); | |
1383 | |
1384 # and vice versa | |
1385 | |
1386 $sess = new_session(); | |
1387 $sid = new_stream($sess, { path => '/t1.html', prio => 255 }); | |
1388 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1389 | |
1390 $sid2 = new_stream($sess, { path => '/t2.html', prio => 0 }); | |
1391 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1392 | |
1393 h2_window($sess, 2**17, $sid); | |
1394 h2_window($sess, 2**17, $sid2); | |
1395 h2_window($sess, 2**17); | |
1396 | |
1397 $frames = h2_read($sess, all => [ | |
1398 { sid => $sid, fin => 1 }, | |
1399 { sid => $sid2, fin => 1 } | |
1400 ]); | |
1401 | |
1402 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1403 $sids = join ' ', map { $_->{sid} } @data; | |
1404 is($sids, "$sid $sid2", 'weight - HEADERS PRIORITY 2'); | |
1405 | |
1406 # 5.3.1. Stream Dependencies | |
1407 | |
1408 # PRIORITY frame | |
1409 | |
1410 $sess = new_session(); | |
1411 | |
1412 h2_priority($sess, 16, 3, 0); | |
1413 h2_priority($sess, 16, 1, 3); | |
1414 | |
1415 $sid = new_stream($sess, { path => '/t1.html' }); | |
1416 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1417 | |
1418 $sid2 = new_stream($sess, { path => '/t2.html' }); | |
1419 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1420 | |
1421 h2_window($sess, 2**17, $sid); | |
1422 h2_window($sess, 2**17, $sid2); | |
1423 h2_window($sess, 2**17); | |
1424 | |
1425 $frames = h2_read($sess, all => [ | |
1426 { sid => $sid, fin => 1 }, | |
1427 { sid => $sid2, fin => 1 }, | |
1428 ]); | |
1429 | |
1430 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1431 $sids = join ' ', map { $_->{sid} } @data; | |
1432 is($sids, "$sid2 $sid", 'dependency - PRIORITY 1'); | |
1433 | |
1434 # and vice versa | |
1435 | |
1436 $sess = new_session(); | |
1437 | |
1438 h2_priority($sess, 16, 1, 0); | |
1439 h2_priority($sess, 16, 3, 1); | |
1440 | |
1441 $sid = new_stream($sess, { path => '/t1.html' }); | |
1442 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1443 | |
1444 $sid2 = new_stream($sess, { path => '/t2.html' }); | |
1445 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1446 | |
1447 h2_window($sess, 2**17, $sid); | |
1448 h2_window($sess, 2**17, $sid2); | |
1449 h2_window($sess, 2**17); | |
1450 | |
1451 $frames = h2_read($sess, all => [ | |
1452 { sid => $sid, fin => 1 }, | |
1453 { sid => $sid2, fin => 1 }, | |
1454 ]); | |
1455 | |
1456 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1457 $sids = join ' ', map { $_->{sid} } @data; | |
1458 is($sids, "$sid $sid2", 'dependency - PRIORITY 2'); | |
1459 | |
1460 # HEADERS PRIORITY flag, reprioritize prior PRIORITY frame records | |
1461 | |
1462 $sess = new_session(); | |
1463 | |
1464 h2_priority($sess, 16, 1, 0); | |
1465 h2_priority($sess, 16, 3, 0); | |
1466 | |
1467 $sid = new_stream($sess, { path => '/t1.html', dep => 3 }); | |
1468 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1469 | |
1470 $sid2 = new_stream($sess, { path => '/t2.html' }); | |
1471 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1472 | |
1473 h2_window($sess, 2**17, $sid); | |
1474 h2_window($sess, 2**17, $sid2); | |
1475 h2_window($sess, 2**17); | |
1476 | |
1477 $frames = h2_read($sess, all => [ | |
1478 { sid => $sid, fin => 1 }, | |
1479 { sid => $sid2, fin => 1 }, | |
1480 ]); | |
1481 | |
1482 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1483 $sids = join ' ', map { $_->{sid} } @data; | |
1484 is($sids, "$sid2 $sid", 'dependency - HEADERS PRIORITY 1'); | |
1485 | |
1486 # and vice versa | |
1487 | |
1488 $sess = new_session(); | |
1489 | |
1490 h2_priority($sess, 16, 1, 0); | |
1491 h2_priority($sess, 16, 3, 0); | |
1492 | |
1493 $sid = new_stream($sess, { path => '/t1.html' }); | |
1494 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1495 | |
1496 $sid2 = new_stream($sess, { path => '/t2.html', dep => 1 }); | |
1497 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); | |
1498 | |
1499 h2_window($sess, 2**17, $sid); | |
1500 h2_window($sess, 2**17, $sid2); | |
1501 h2_window($sess, 2**17); | |
1502 | |
1503 $frames = h2_read($sess, all => [ | |
1504 { sid => $sid, fin => 1 }, | |
1505 { sid => $sid2, fin => 1 }, | |
1506 ]); | |
1507 | |
1508 @data = grep { $_->{type} eq "DATA" } @$frames; | |
1509 $sids = join ' ', map { $_->{sid} } @data; | |
1510 is($sids, "$sid $sid2", 'dependency - HEADERS PRIORITY 2'); | |
1511 | |
662
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1512 # PRIORITY frame, weighted dependencies |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1513 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1514 $sess = new_session(); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1515 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1516 h2_priority($sess, 16, 5, 0); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1517 h2_priority($sess, 255, 1, 5); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1518 h2_priority($sess, 0, 3, 5); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1519 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1520 $sid = new_stream($sess, { path => '/t1.html' }); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1521 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1522 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1523 $sid2 = new_stream($sess, { path => '/t2.html' }); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1524 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1525 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1526 my $sid3 = new_stream($sess, { path => '/t2.html' }); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1527 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1528 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1529 h2_window($sess, 2**16, 1); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1530 h2_window($sess, 2**16, 3); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1531 h2_window($sess, 2**16, 5); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1532 h2_window($sess, 2**16); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1533 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1534 $frames = h2_read($sess, all => [ |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1535 { sid => $sid, fin => 1 }, |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1536 { sid => $sid2, fin => 1 }, |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1537 { sid => $sid3, fin => 1 }, |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1538 ]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1539 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1540 @data = grep { $_->{type} eq "DATA" } @$frames; |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1541 $sids = join ' ', map { $_->{sid} } @data; |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1542 is($sids, "$sid3 $sid $sid2", 'weighted dependency - PRIORITY 1'); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1543 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1544 # and vice versa |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1545 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1546 $sess = new_session(); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1547 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1548 h2_priority($sess, 16, 5, 0); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1549 h2_priority($sess, 0, 1, 5); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1550 h2_priority($sess, 255, 3, 5); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1551 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1552 $sid = new_stream($sess, { path => '/t1.html' }); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1553 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1554 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1555 $sid2 = new_stream($sess, { path => '/t2.html' }); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1556 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1557 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1558 $sid3 = new_stream($sess, { path => '/t2.html' }); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1559 h2_read($sess, all => [{ sid => $sid2, fin => 0x4 }]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1560 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1561 h2_window($sess, 2**16, 1); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1562 h2_window($sess, 2**16, 3); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1563 h2_window($sess, 2**16, 5); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1564 h2_window($sess, 2**16); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1565 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1566 $frames = h2_read($sess, all => [ |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1567 { sid => $sid, fin => 1 }, |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1568 { sid => $sid2, fin => 1 }, |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1569 { sid => $sid3, fin => 1 }, |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1570 ]); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1571 |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1572 @data = grep { $_->{type} eq "DATA" } @$frames; |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1573 $sids = join ' ', map { $_->{sid} } @data; |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1574 is($sids, "$sid3 $sid2 $sid", 'weighted dependency - PRIORITY 2'); |
07de3d202eb7
Tests: more HTTP/2 tests for streams priority.
Sergey Kandaurov <pluknet@nginx.com>
parents:
661
diff
changeset
|
1575 |
646 | 1576 # limit_conn |
1577 | |
1578 $sess = new_session(); | |
1579 h2_settings($sess, 0, 0x4 => 1); | |
1580 | |
1581 $sid = new_stream($sess, { path => '/t3.html' }); | |
1582 $frames = h2_read($sess, all => [{ sid => $sid, length => 1 }]); | |
1583 | |
1584 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; | |
1585 is($frame->{headers}->{':status'}, 200, 'limit_conn first stream'); | |
1586 | |
1587 $sid2 = new_stream($sess, { path => '/t3.html' }); | |
1588 $frames = h2_read($sess, all => [{ sid => $sid2, fin => 0 }]); | |
1589 | |
1590 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid2 } @$frames; | |
1591 is($frame->{headers}->{':status'}, 503, 'limit_conn rejected'); | |
1592 | |
1593 h2_settings($sess, 0, 0x4 => 2**16); | |
1594 | |
1595 h2_read($sess, all => [ | |
1596 { sid => $sid, fin => 1 }, | |
1597 { sid => $sid2, fin => 1 } | |
1598 ]); | |
1599 | |
1600 # limit_conn + client's RST_STREAM | |
1601 | |
1602 $sess = new_session(); | |
1603 h2_settings($sess, 0, 0x4 => 1); | |
1604 | |
1605 $sid = new_stream($sess, { path => '/t3.html' }); | |
1606 $frames = h2_read($sess, all => [{ sid => $sid, length => 1 }]); | |
1607 h2_rst($sess, $sid, 5); | |
1608 | |
1609 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; | |
1610 is($frame->{headers}->{':status'}, 200, 'RST_STREAM 1'); | |
1611 | |
1612 $sid2 = new_stream($sess, { path => '/t3.html' }); | |
1613 $frames = h2_read($sess, all => [{ sid => $sid2, fin => 0 }]); | |
1614 | |
1615 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid2 } @$frames; | |
1616 is($frame->{headers}->{':status'}, 200, 'RST_STREAM 2'); | |
1617 | |
654
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1618 # http2_max_concurrent_streams |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1619 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1620 $sess = new_session(8086); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1621 $frames = h2_read($sess, all => [{ type => 'SETTINGS' }]); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1622 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1623 ($frame) = grep { $_->{type} eq 'SETTINGS' } @$frames; |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1624 is($frame->{3}, 1, 'http2_max_concurrent_streams SETTINGS'); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1625 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1626 h2_window($sess, 2**18); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1627 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1628 $sid = new_stream($sess, { path => '/t1.html' }); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1629 $frames = h2_read($sess, all => [{ sid => $sid, length => 2 ** 16 - 1 }]); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1630 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1631 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1632 is($frame->{headers}->{':status'}, 200, 'http2_max_concurrent_streams'); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1633 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1634 $sid2 = new_stream($sess, { path => '/t1.html' }); |
667
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1635 $frames = h2_read($sess, all => [{ type => 'RST_STREAM' }]); |
654
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1636 |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1637 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid2 } @$frames; |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1638 isnt($frame->{headers}->{':status'}, 200, 'http2_max_concurrent_streams 2'); |
a64fe1054fb4
Tests: HTTP/2 tests for http2_max_concurrent_streams directive.
Sergey Kandaurov <pluknet@nginx.com>
parents:
653
diff
changeset
|
1639 |
667
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1640 ($frame) = grep { $_->{type} eq "RST_STREAM" && $_->{sid} == $sid2 } @$frames; |
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1641 is($frame->{sid}, $sid2, 'http2_max_concurrent_streams RST_STREAM sid'); |
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1642 is($frame->{length}, 4, 'http2_max_concurrent_streams RST_STREAM length'); |
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1643 is($frame->{flags}, 0, 'http2_max_concurrent_streams RST_STREAM flags'); |
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1644 is($frame->{code}, 7, 'http2_max_concurrent_streams RST_STREAM code'); |
0247e314e991
Tests: more HTTP/2 error handling tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
662
diff
changeset
|
1645 |
661
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1646 h2_window($sess, 2**16, $sid); |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1647 h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1648 |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1649 $sid = new_stream($sess, { path => '/t2.html' }); |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1650 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1651 |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1652 ($frame) = grep { $_->{type} eq "HEADERS" && $_->{sid} == $sid } @$frames; |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1653 is($frame->{headers}->{':status'}, 200, 'http2_max_concurrent_streams 3'); |
c99c30afc1c9
Tests: one more test for http2_max_concurrent_streams.
Sergey Kandaurov <pluknet@nginx.com>
parents:
660
diff
changeset
|
1654 |
646 | 1655 |
1656 # some invalid cases below | |
1657 | |
675
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1658 # ensure that request header field value with newline doesn't get split |
677
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1659 # |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1660 # 10.3. Intermediary Encapsulation Attacks |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1661 # Any request or response that contains a character not permitted |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1662 # in a header field value MUST be treated as malformed. |
675
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1663 |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1664 $sess = new_session(); |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1665 $sid = new_stream($sess, { headers => [ |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1666 { name => ':method', value => 'GET', mode => 0 }, |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1667 { name => ':scheme', value => 'http', mode => 0 }, |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1668 { name => ':path', value => '/proxy2/', mode => 1 }, |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1669 { name => ':authority', value => 'localhost', mode => 1 }, |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1670 { name => 'x-foo', value => "x-bar\r\nreferer:see-this", mode => 2 }]}); |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1671 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1672 |
677
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1673 # 10.3. Intermediary Encapsulation Attacks |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1674 # An intermediary therefore cannot translate an HTTP/2 request or response |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1675 # containing an invalid field name into an HTTP/1.1 message. |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1676 |
675
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1677 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1678 isnt($frame->{headers}->{'x-referer'}, 'see-this', 'newline in request header'); |
42de9efd11ee
Tests: added HTTP/2 test for request header with newline.
Sergey Kandaurov <pluknet@nginx.com>
parents:
673
diff
changeset
|
1679 |
677
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1680 # 8.1.2.6. Malformed Requests and Responses |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1681 # Malformed requests or responses that are detected MUST be treated |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1682 # as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1683 |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1684 ($frame) = grep { $_->{type} eq "RST_STREAM" } @$frames; |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1685 is($frame->{sid}, $sid, 'newline in request header - RST_STREAM sid'); |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1686 is($frame->{length}, 4, 'newline in request header - RST_STREAM length'); |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1687 is($frame->{flags}, 0, 'newline in request header - RST_STREAM flags'); |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1688 is($frame->{code}, 1, 'newline in request header - RST_STREAM code'); |
5d258aa5ebc5
Tests: more HTTP/2 tests for newline in request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
675
diff
changeset
|
1689 |
646 | 1690 # GOAWAY on SYN_STREAM with even StreamID |
1691 | |
1692 $sess = new_session(); | |
1693 new_stream($sess, { path => '/' }, 2); | |
1694 $frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); | |
1695 | |
1696 ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; | |
1697 ok($frame, 'even stream - GOAWAY frame'); | |
1698 is($frame->{code}, 1, 'even stream - error code'); | |
669
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1699 is($frame->{last_sid}, 0, 'even stream - last stream'); |
646 | 1700 |
1701 # GOAWAY on SYN_STREAM with backward StreamID | |
1702 | |
669
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1703 # 5.1.1. Stream Identifiers |
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1704 # The first use of a new stream identifier implicitly closes all |
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1705 # streams in the "idle" state <..> with a lower-valued stream identifier. |
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1706 |
646 | 1707 $sess = new_session(); |
1708 $sid = new_stream($sess, { path => '/' }, 3); | |
1709 h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
1710 | |
1711 $sid2 = new_stream($sess, { path => '/' }, 1); | |
1712 $frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); | |
1713 | |
1714 ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; | |
1715 ok($frame, 'backward stream - GOAWAY frame'); | |
1716 is($frame->{code}, 1, 'backward stream - error code'); | |
669
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1717 is($frame->{last_sid}, $sid, 'backward stream - last stream'); |
646 | 1718 |
669
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1719 # GOAWAY on the second SYN_STREAM with same StreamID |
646 | 1720 |
1721 $sess = new_session(); | |
1722 $sid = new_stream($sess, { path => '/' }); | |
1723 h2_read($sess, all => [{ sid => $sid, fin => 1 }]); | |
1724 | |
1725 $sid2 = new_stream($sess, { path => '/' }, $sid); | |
669
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1726 $frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); |
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1727 |
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1728 ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; |
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1729 ok($frame, 'dup stream - GOAWAY frame'); |
646 | 1730 is($frame->{code}, 1, 'dup stream - error code'); |
669
0c442e551ba1
Tests: corrected HTTP/2 tests for GOAWAY.
Sergey Kandaurov <pluknet@nginx.com>
parents:
668
diff
changeset
|
1731 is($frame->{last_sid}, $sid, 'dup stream - last stream'); |
646 | 1732 |
1733 # missing mandatory request header ':scheme' | |
1734 | |
1735 TODO: { | |
1736 local $TODO = 'not yet'; | |
1737 | |
1738 $sess = new_session(); | |
1739 $sid = new_stream($sess, { headers => [ | |
1740 { name => ':method', value => 'GET', mode => 0 }, | |
653
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
1741 { name => ':path', value => '/', mode => 0 }, |
5ad620022234
Tests: HTTP/2 tests adapted to send ':authority' where needed.
Sergey Kandaurov <pluknet@nginx.com>
parents:
652
diff
changeset
|
1742 { name => ':authority', value => 'localhost', mode => 1 }]}); |
646 | 1743 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
1744 | |
1745 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
1746 is($frame->{headers}->{':status'}, 400, 'incomplete headers'); | |
1747 | |
1748 } | |
1749 | |
673
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1750 # empty request header ':authority' |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1751 |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1752 $sess = new_session(); |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1753 $sid = new_stream($sess, { headers => [ |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1754 { name => ':method', value => 'GET', mode => 0 }, |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1755 { name => ':scheme', value => 'http', mode => 0 }, |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1756 { name => ':path', value => '/', mode => 0 }, |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1757 { name => ':authority', value => '', mode => 0 }]}); |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1758 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]); |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1759 |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1760 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1761 is($frame->{headers}->{':status'}, 400, 'empty authority'); |
9d6c865c2869
Tests: HTTP/2 regression test for empty authority request header.
Sergey Kandaurov <pluknet@nginx.com>
parents:
672
diff
changeset
|
1762 |
697
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1763 # unknown frame type |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1764 |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1765 $sess = new_session(); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1766 h2_unknown($sess, 'payload'); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1767 h2_ping($sess, 'SEE-THIS'); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1768 $frames = h2_read($sess, all => [{ type => 'PING' }]); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1769 |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1770 ($frame) = grep { $_->{type} eq "PING" } @$frames; |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1771 is($frame->{value}, 'SEE-THIS', 'unknown frame type'); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1772 |
646 | 1773 # GOAWAY - force closing a connection by server |
1774 | |
1775 $sid = new_stream($sess, { path => 't1.html' }); | |
1776 h2_read($sess, all => [{ sid => $sid, length => 2**16 - 1 }]); | |
1777 | |
1778 $t->stop(); | |
1779 | |
1780 $frames = h2_read($sess, all => [{ type => 'GOAWAY' }]); | |
1781 | |
1782 ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames; | |
1783 ok($frame, 'GOAWAY on connection close'); | |
1784 | |
1785 ############################################################################### | |
1786 | |
1787 sub h2_ping { | |
1788 my ($sess, $payload) = @_; | |
1789 | |
1790 raw_write($sess->{socket}, pack("x2C2x5a8", 8, 0x6, $payload)); | |
1791 } | |
1792 | |
1793 sub h2_rst { | |
1794 my ($sess, $stream, $error) = @_; | |
1795 | |
1796 raw_write($sess->{socket}, pack("x2C2xNN", 4, 0x3, $stream, $error)); | |
1797 } | |
1798 | |
1799 sub h2_priority { | |
1800 my ($sess, $w, $stream, $dep) = @_; | |
1801 | |
1802 $stream = 0 unless defined $stream; | |
1803 $dep = 0 unless defined $dep; | |
1804 raw_write($sess->{socket}, pack("x2C2xNNC", 5, 0x2, $stream, $dep, $w)); | |
1805 } | |
1806 | |
1807 sub h2_window { | |
1808 my ($sess, $win, $stream) = @_; | |
1809 | |
1810 $stream = 0 unless defined $stream; | |
1811 raw_write($sess->{socket}, pack("x2C2xNN", 4, 0x8, $stream, $win)); | |
1812 } | |
1813 | |
1814 sub h2_settings { | |
1815 my ($sess, $ack, %extra) = @_; | |
1816 | |
1817 my $len = 6 * keys %extra; | |
1818 my $buf = pack_length($len) . pack "CCx4", 0x4, $ack ? 0x1 : 0x0; | |
1819 $buf .= join '', map { pack "nN", $_, $extra{$_} } keys %extra; | |
1820 raw_write($sess->{socket}, $buf); | |
1821 } | |
1822 | |
697
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1823 sub h2_unknown { |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1824 my ($sess, $payload) = @_; |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1825 |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1826 my $buf = pack_length(length($payload)) . pack("Cx5a*", 0xa, $payload); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1827 raw_write($sess->{socket}, $buf); |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1828 } |
46f698a7e59c
Tests: added HTTP/2 test for unknown frame type.
Sergey Kandaurov <pluknet@nginx.com>
parents:
696
diff
changeset
|
1829 |
646 | 1830 sub h2_continue { |
1831 my ($ctx, $stream, $uri) = @_; | |
1832 | |
1833 $uri->{h2_continue} = 1; | |
1834 return new_stream($ctx, $uri, $stream); | |
1835 } | |
1836 | |
1837 sub new_stream { | |
1838 my ($ctx, $uri, $stream) = @_; | |
1839 my ($input, $buf); | |
1840 my ($d, $status); | |
1841 | |
1842 my $host = $uri->{host} || '127.0.0.1:8080'; | |
1843 my $method = $uri->{method} || 'GET'; | |
1844 my $scheme = $uri->{scheme} || 'http'; | |
1845 my $path = $uri->{path} || '/'; | |
1846 my $headers = $uri->{headers}; | |
1847 my $body = $uri->{body}; | |
1848 my $prio = $uri->{prio}; | |
1849 my $dep = $uri->{dep}; | |
699
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1850 my $split = ref $uri->{continuation} && $uri->{continuation} || []; |
646 | 1851 |
1852 my $pad = defined $uri->{padding} ? $uri->{padding} : 0; | |
1853 my $padlen = defined $uri->{padding} ? 1 : 0; | |
1854 my $bpad = defined $uri->{body_padding} ? $uri->{body_padding} : 0; | |
1855 my $bpadlen = defined $uri->{body_padding} ? 1 : 0; | |
1856 | |
1857 my $type = defined $uri->{h2_continue} ? 0x9 : 0x1; | |
1858 my $flags = defined $uri->{continuation} ? 0x0 : 0x4; | |
1859 $flags |= 0x1 unless defined $body; | |
1860 $flags |= 0x8 if $padlen; | |
1861 $flags |= 0x20 if defined $dep || defined $prio; | |
1862 | |
1863 if ($stream) { | |
1864 $ctx->{last_stream} = $stream; | |
1865 } else { | |
1866 $ctx->{last_stream} += 2; | |
1867 } | |
1868 | |
1869 $buf = pack("xxx"); # Length stub | |
1870 $buf .= pack("CC", $type, $flags); # END_HEADERS | |
1871 $buf .= pack("N", $ctx->{last_stream}); # Stream-ID | |
1872 | |
1873 $dep = 0 if defined $prio and not defined $dep; | |
1874 $prio = 16 if defined $dep and not defined $prio; | |
1875 | |
1876 unless ($headers) { | |
1877 $input = hpack($ctx, ":method", $method); | |
1878 $input .= hpack($ctx, ":scheme", $scheme); | |
1879 $input .= hpack($ctx, ":path", $path); | |
1880 $input .= hpack($ctx, ":authority", $host); | |
1881 $input .= hpack($ctx, "content-length", length($body)) if $body; | |
1882 | |
1883 } else { | |
1884 $input = join '', map { | |
1885 hpack($ctx, $_->{name}, $_->{value}, | |
1886 mode => $_->{mode}, huff => $_->{huff}) | |
1887 } @$headers if $headers; | |
1888 } | |
1889 | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
1890 $input = pack("B*", '001' . ipack(5, $uri->{table_size})) . $input |
646 | 1891 if defined $uri->{table_size}; |
1892 | |
702
cc2b98d028c8
Tests: fixed HTTP/2 test for CONTINUATION while in header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
700
diff
changeset
|
1893 my @input = map { substr $input, 0, $_, "" } @$split; |
699
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1894 push @input, $input; |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1895 |
646 | 1896 # set length, attach headers, padding, priority |
1897 | |
699
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1898 my $hlen = length($input[0]) + $pad + $padlen; |
646 | 1899 $hlen += 5 if $flags & 0x20; |
1900 $buf |= pack_length($hlen); | |
1901 | |
1902 $buf .= pack 'C', $pad if $padlen; # Pad Length? | |
1903 $buf .= pack 'NC', $dep, $prio if $flags & 0x20; | |
699
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1904 $buf .= $input[0]; |
646 | 1905 $buf .= (pack 'C', 0) x $pad if $padlen; # Padding |
1906 | |
699
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1907 shift @input; |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1908 |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1909 while (@input) { |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1910 $input = shift @input; |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1911 $flags = @input ? 0x0 : 0x4; |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1912 $buf .= pack_length(length($input)); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1913 $buf .= pack("CC", 0x9, $flags); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1914 $buf .= pack("N", $ctx->{last_stream}); |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1915 $buf .= $input; |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1916 } |
5768830f01c4
Tests: HTTP/2 test for CONTINUATION in the middle of header field.
Sergey Kandaurov <pluknet@nginx.com>
parents:
698
diff
changeset
|
1917 |
646 | 1918 if (defined $body) { |
1919 $buf .= pack_length(length($body) + $bpad + $bpadlen); | |
1920 my $flags = $bpadlen ? 0x8 : 0x0; | |
1921 $buf .= pack 'CC', 0x0, 0x1 | $flags; # DATA, END_STREAM | |
1922 $buf .= pack 'N', $ctx->{last_stream}; | |
1923 $buf .= pack 'C', $bpad if $bpadlen; # DATA Pad Length? | |
1924 $buf .= $body; | |
1925 $buf .= (pack 'C', 0) x $bpad if $bpadlen; # DATA Padding | |
1926 } | |
1927 | |
1928 raw_write($ctx->{socket}, $buf); | |
1929 return $ctx->{last_stream}; | |
1930 } | |
1931 | |
1932 sub h2_read { | |
1933 my ($sess, %extra) = @_; | |
1934 my (@got); | |
1935 my $s = $sess->{socket}; | |
1936 my $buf = ''; | |
1937 | |
1938 while (1) { | |
1939 $buf = raw_read($s, $buf, 9); | |
1940 last unless length $buf; | |
1941 | |
1942 my $length = unpack_length($buf); | |
1943 my $type = unpack('x3C', $buf); | |
1944 my $flags = unpack('x4C', $buf); | |
1945 | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1946 my $stream = unpack "x5 B32", $buf; |
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1947 substr($stream, 0, 1) = 0; |
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1948 $stream = unpack("N", pack("B32", $stream)); |
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1949 |
679
b60c1a207675
Tests: fixed HTTP/2 tests with large frames.
Sergey Kandaurov <pluknet@nginx.com>
parents:
677
diff
changeset
|
1950 $buf = raw_read($s, $buf, $length + 9); |
646 | 1951 last unless length $buf; |
1952 | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1953 $buf = substr($buf, 9); |
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1954 |
646 | 1955 my $frame = $cframe{$type}{value}($sess, $buf, $length); |
1956 $frame->{length} = $length; | |
1957 $frame->{type} = $cframe{$type}{name}; | |
1958 $frame->{flags} = $flags; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1959 $frame->{sid} = $stream; |
646 | 1960 push @got, $frame; |
1961 | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
1962 $buf = substr($buf, $length); |
646 | 1963 |
1964 last unless test_fin($got[-1], $extra{all}); | |
1965 }; | |
1966 return \@got; | |
1967 } | |
1968 | |
1969 sub test_fin { | |
1970 my ($frame, $all) = @_; | |
1971 my @test = @{$all}; | |
1972 | |
1973 # wait for the specified DATA length | |
1974 | |
1975 for (@test) { | |
1976 if ($_->{length} && $frame->{type} eq 'DATA') { | |
1977 # check also for StreamID if needed | |
1978 | |
1979 if (!$_->{sid} || $_->{sid} == $frame->{sid}) { | |
1980 $_->{length} -= $frame->{length}; | |
1981 } | |
1982 } | |
1983 } | |
1984 @test = grep { !(defined $_->{length} && $_->{length} == 0) } @test; | |
1985 | |
1986 # wait for the fin flag | |
1987 | |
1988 @test = grep { !(defined $_->{fin} | |
1989 && $_->{sid} == $frame->{sid} && $_->{fin} & $frame->{flags}) | |
1990 } @test if defined $frame->{flags}; | |
1991 | |
1992 # wait for the specified frame | |
1993 | |
1994 @test = grep { !($_->{type} && $_->{type} eq $frame->{type}) } @test; | |
1995 | |
1996 @{$all} = @test; | |
1997 } | |
1998 | |
1999 sub headers { | |
2000 my ($ctx, $buf, $len) = @_; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2001 return { headers => hunpack($ctx, $buf, $len) }; |
646 | 2002 } |
2003 | |
2004 sub data { | |
2005 my ($ctx, $buf, $len) = @_; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2006 return { data => substr($buf, 0, $len) }; |
646 | 2007 } |
2008 | |
2009 sub settings { | |
2010 my ($ctx, $buf, $len) = @_; | |
2011 my %payload; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2012 my $skip = 0; |
646 | 2013 |
2014 for (1 .. $len / 6) { | |
2015 my $id = hex unpack "\@$skip n", $buf; $skip += 2; | |
2016 $payload{$id} = unpack "\@$skip N", $buf; $skip += 4; | |
2017 } | |
2018 return \%payload; | |
2019 } | |
2020 | |
2021 sub ping { | |
2022 my ($ctx, $buf, $len) = @_; | |
670
944b87756cab
Tests: fixed GOAWAY and PING frames parsing in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
669
diff
changeset
|
2023 return { value => unpack "A$len", $buf }; |
646 | 2024 } |
2025 | |
2026 sub rst_stream { | |
2027 my ($ctx, $buf, $len) = @_; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2028 return { code => unpack "N", $buf }; |
646 | 2029 } |
2030 | |
2031 sub goaway { | |
2032 my ($ctx, $buf, $len) = @_; | |
2033 my %payload; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2034 |
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2035 my $stream = unpack "B32", $buf; |
646 | 2036 substr($stream, 0, 1) = 0; |
2037 $stream = unpack("N", pack("B32", $stream)); | |
2038 $payload{last_sid} = $stream; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2039 |
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2040 $len -= 4; |
670
944b87756cab
Tests: fixed GOAWAY and PING frames parsing in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
669
diff
changeset
|
2041 $payload{code} = unpack "x4 N", $buf; |
944b87756cab
Tests: fixed GOAWAY and PING frames parsing in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
669
diff
changeset
|
2042 $payload{debug} = unpack "x8 A$len", $buf; |
646 | 2043 return \%payload; |
2044 } | |
2045 | |
2046 sub window_update { | |
2047 my ($ctx, $buf, $len) = @_; | |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2048 my $value = unpack "B32", $buf; |
646 | 2049 substr($value, 0, 1) = 0; |
655
75ecd26b8831
Tests: HTTP/2 tests cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
654
diff
changeset
|
2050 return { wdelta => unpack("N", pack("B32", $value)) }; |
646 | 2051 } |
2052 | |
2053 sub pack_length { | |
2054 pack 'c3', unpack 'xc3', pack 'N', $_[0]; | |
2055 } | |
2056 | |
2057 sub unpack_length { | |
2058 unpack 'N', pack 'xc3', unpack 'c3', $_[0]; | |
2059 } | |
2060 | |
2061 sub raw_read { | |
2062 my ($s, $buf, $len) = @_; | |
2063 my $got = ''; | |
2064 | |
2065 while (length($buf) < $len && IO::Select->new($s)->can_read(1)) { | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2066 $s->sysread($got, 16384) or last; |
646 | 2067 log_in($got); |
2068 $buf .= $got; | |
2069 } | |
2070 return $buf; | |
2071 } | |
2072 | |
2073 sub raw_write { | |
2074 my ($s, $message) = @_; | |
2075 | |
2076 local $SIG{PIPE} = 'IGNORE'; | |
2077 | |
2078 while (IO::Select->new($s)->can_write(0.4)) { | |
2079 log_out($message); | |
2080 my $n = $s->syswrite($message); | |
2081 last unless $n; | |
2082 $message = substr($message, $n); | |
2083 last unless length $message; | |
2084 } | |
2085 } | |
2086 | |
2087 sub new_session { | |
2088 my ($port, %extra) = @_; | |
2089 my ($s); | |
2090 | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2091 $s = new_socket($port, %extra); |
646 | 2092 |
2093 if ($extra{proxy}) { | |
2094 raw_write($s, $extra{proxy}); | |
2095 } | |
2096 | |
2097 # preface | |
2098 | |
2099 raw_write($s, 'PRI * HTTP/2.0' . CRLF . CRLF . 'SM' . CRLF . CRLF); | |
2100 | |
2101 return { socket => $s, last_stream => -1, | |
2102 dynamic_encode => [ static_table() ], | |
2103 dynamic_decode => [ static_table() ], | |
2104 static_table_size => scalar @{[static_table()]} }; | |
2105 } | |
2106 | |
2107 sub new_socket { | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2108 my ($port, %extra) = @_; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2109 my $npn = $extra{'npn'}; |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2110 my $alpn = $extra{'alpn'}; |
646 | 2111 my $s; |
2112 | |
2113 $port = 8080 unless defined $port; | |
2114 | |
2115 eval { | |
2116 local $SIG{ALRM} = sub { die "timeout\n" }; | |
2117 local $SIG{PIPE} = sub { die "sigpipe\n" }; | |
2118 alarm(2); | |
2119 $s = IO::Socket::INET->new( | |
2120 Proto => 'tcp', | |
2121 PeerAddr => "127.0.0.1:$port", | |
2122 ); | |
650
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2123 IO::Socket::SSL->start_SSL($s, |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2124 SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(), |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2125 SSL_npn_protocols => $npn ? [ $npn ] : undef, |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2126 SSL_alpn_protocols => $alpn ? [ $alpn ] : undef, |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2127 SSL_error_trap => sub { die $_[1] } |
8a2cf558b8ae
Tests: HTTP/2 tests for $http2 variable.
Sergey Kandaurov <pluknet@nginx.com>
parents:
647
diff
changeset
|
2128 ) if $extra{'SSL'}; |
646 | 2129 alarm(0); |
2130 }; | |
2131 alarm(0); | |
2132 | |
2133 if ($@) { | |
2134 log_in("died: $@"); | |
2135 return undef; | |
2136 } | |
2137 | |
2138 return $s; | |
2139 } | |
2140 | |
2141 sub static_table { | |
2142 [ '', '' ], # unused | |
2143 [ ':authority', '' ], | |
2144 [ ':method', 'GET' ], | |
2145 [ ':method', 'POST' ], | |
2146 [ ':path', '/' ], | |
2147 [ ':path', '/index.html' ], | |
2148 [ ':scheme', 'http' ], | |
2149 [ ':scheme', 'https' ], | |
2150 [ ':status', '200' ], | |
2151 [ ':status', '204' ], | |
2152 [ ':status', '206' ], | |
2153 [ ':status', '304' ], | |
2154 [ ':status', '400' ], | |
2155 [ ':status', '404' ], | |
2156 [ ':status', '500' ], | |
2157 [ 'accept-charset', '' ], | |
2158 [ 'accept-encoding', 'gzip, deflate' ], | |
2159 [ 'accept-language', '' ], | |
2160 [ 'accept-ranges', '' ], | |
2161 [ 'accept', '' ], | |
2162 [ 'access-control-allow-origin', | |
2163 '' ], | |
2164 [ 'age', '' ], | |
2165 [ 'allow', '' ], | |
2166 [ 'authorization', '' ], | |
2167 [ 'cache-control', '' ], | |
2168 [ 'content-disposition', | |
2169 '' ], | |
2170 [ 'content-encoding', '' ], | |
2171 [ 'content-language', '' ], | |
2172 [ 'content-length', '' ], | |
2173 [ 'content-location', '' ], | |
2174 [ 'content-range', '' ], | |
2175 [ 'content-type', '' ], | |
2176 [ 'cookie', '' ], | |
2177 [ 'date', '' ], | |
2178 [ 'etag', '' ], | |
2179 [ 'expect', '' ], | |
2180 [ 'expires', '' ], | |
2181 [ 'from', '' ], | |
2182 [ 'host', '' ], | |
2183 [ 'if-match', '' ], | |
2184 [ 'if-modified-since', '' ], | |
2185 [ 'if-none-match', '' ], | |
2186 [ 'if-range', '' ], | |
2187 [ 'if-unmodified-since', | |
2188 '' ], | |
2189 [ 'last-modified', '' ], | |
2190 [ 'link', '' ], | |
2191 [ 'location', '' ], | |
2192 [ 'max-forwards', '' ], | |
2193 [ 'proxy-authenticate', '' ], | |
2194 [ 'proxy-authorization', | |
2195 '' ], | |
2196 [ 'range', '' ], | |
2197 [ 'referer', '' ], | |
2198 [ 'refresh', '' ], | |
2199 [ 'retry-after', '' ], | |
2200 [ 'server', '' ], | |
2201 [ 'set-cookie', '' ], | |
2202 [ 'strict-transport-security', | |
2203 '' ], | |
2204 [ 'transfer-encoding', '' ], | |
2205 [ 'user-agent', '' ], | |
2206 [ 'vary', '' ], | |
2207 [ 'via', '' ], | |
2208 [ 'www-authenticate', '' ], | |
2209 } | |
2210 | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2211 # RFC 7541, 5.1. Integer Representation |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2212 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2213 sub ipack { |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2214 my ($base, $d) = @_; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2215 return sprintf("%.*b", $base, $d) if $d < 2**$base - 1; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2216 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2217 my $o = sprintf("%${base}b", 2**$base - 1); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2218 $d -= 2**$base - 1; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2219 while ($d >= 128) { |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2220 $o .= sprintf("%8b", $d % 128 + 128); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2221 $d /= 128; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2222 } |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2223 $o .= sprintf("%08b", $d); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2224 return $o; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2225 } |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2226 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2227 sub iunpack { |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2228 my ($base, $b, $s) = @_; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2229 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2230 my $len = unpack("\@$s B8", $b); $s++; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2231 my $prefix = substr($len, 0, 8 - $base); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2232 $len = '0' x (8 - $base) . substr($len, 8 - $base); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2233 $len = unpack("C", pack("B8", $len)); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2234 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2235 return ($len, $s, $prefix) if $len < 2**$base - 1; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2236 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2237 my $m = 0; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2238 my $d; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2239 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2240 do { |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2241 $d = unpack("\@$s C", $b); $s++; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2242 $len += ($d & 127) * 2**$m; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2243 $m += $base; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2244 } while (($d & 128) == 128); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2245 |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2246 return ($len, $s, $prefix); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2247 } |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2248 |
646 | 2249 sub hpack { |
2250 my ($ctx, $name, $value, %extra) = @_; | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2251 my $table = $ctx->{dynamic_encode}; |
646 | 2252 my $mode = defined $extra{mode} ? $extra{mode} : 1; |
2253 my $huff = $extra{huff}; | |
2254 | |
2255 my ($index, $buf) = 0; | |
2256 | |
2257 # 6.1. Indexed Header Field Representation | |
2258 | |
2259 if ($mode == 0) { | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2260 ++$index until $index > $#$table |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2261 or $table->[$index][0] eq $name |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2262 and $table->[$index][1] eq $value; |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2263 $buf = pack('B*', '1' . ipack(7, $index)); |
646 | 2264 } |
2265 | |
2266 # 6.2.1. Literal Header Field with Incremental Indexing | |
2267 | |
2268 if ($mode == 1) { | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2269 splice @$table, $ctx->{static_table_size}, 0, [ $name, $value ]; |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2270 |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2271 ++$index until $index > $#$table |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2272 or $table->[$index][0] eq $name; |
646 | 2273 my $value = $huff ? huff($value) : $value; |
2274 | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2275 $buf = pack('B*', '01' . ipack(6, $index) |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2276 . ($huff ? '1' : '0') . ipack(7, length($value))); |
646 | 2277 $buf .= $value; |
2278 } | |
2279 | |
2280 # 6.2.1. Literal Header Field with Incremental Indexing -- New Name | |
2281 | |
2282 if ($mode == 2) { | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2283 splice @$table, $ctx->{static_table_size}, 0, [ $name, $value ]; |
646 | 2284 |
2285 my $name = $huff ? huff($name) : $name; | |
2286 my $value = $huff ? huff($value) : $value; | |
2287 my $hbit = ($huff ? '1' : '0'); | |
2288 | |
2289 $buf = pack('B*', '01000000'); | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2290 $buf .= pack('B*', $hbit . ipack(7, length($name))); |
646 | 2291 $buf .= $name; |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2292 $buf .= pack('B*', $hbit . ipack(7, length($value))); |
646 | 2293 $buf .= $value; |
2294 } | |
2295 | |
2296 # 6.2.2. Literal Header Field without Indexing | |
2297 | |
2298 if ($mode == 3) { | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2299 ++$index until $index > $#$table |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2300 or $table->[$index][0] eq $name; |
646 | 2301 my $value = $huff ? huff($value) : $value; |
2302 | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2303 $buf = pack('B*', '0000' . ipack(4, $index) |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2304 . ($huff ? '1' : '0') . ipack(7, length($value))); |
646 | 2305 $buf .= $value; |
2306 } | |
2307 | |
2308 # 6.2.2. Literal Header Field without Indexing -- New Name | |
2309 | |
2310 if ($mode == 4) { | |
2311 my $name = $huff ? huff($name) : $name; | |
2312 my $value = $huff ? huff($value) : $value; | |
2313 my $hbit = ($huff ? '1' : '0'); | |
2314 | |
2315 $buf = pack('B*', '00000000'); | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2316 $buf .= pack('B*', $hbit . ipack(7, length($name))); |
646 | 2317 $buf .= $name; |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2318 $buf .= pack('B*', $hbit . ipack(7, length($value))); |
646 | 2319 $buf .= $value; |
2320 } | |
2321 | |
2322 # 6.2.3. Literal Header Field Never Indexed | |
2323 | |
2324 if ($mode == 5) { | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2325 ++$index until $index > $#$table |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2326 or $table->[$index][0] eq $name; |
646 | 2327 my $value = $huff ? huff($value) : $value; |
2328 | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2329 $buf = pack('B*', '0001' . ipack(4, $index) |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2330 . ($huff ? '1' : '0') . ipack(7, length($value))); |
646 | 2331 $buf .= $value; |
2332 } | |
2333 | |
2334 # 6.2.3. Literal Header Field Never Indexed -- New Name | |
2335 | |
2336 if ($mode == 6) { | |
2337 my $name = $huff ? huff($name) : $name; | |
2338 my $value = $huff ? huff($value) : $value; | |
2339 my $hbit = ($huff ? '1' : '0'); | |
2340 | |
2341 $buf = pack('B*', '00010000'); | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2342 $buf .= pack('B*', $hbit . ipack(7, length($name))); |
646 | 2343 $buf .= $name; |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2344 $buf .= pack('B*', $hbit . ipack(7, length($value))); |
646 | 2345 $buf .= $value; |
2346 } | |
2347 | |
2348 return $buf; | |
2349 } | |
2350 | |
2351 sub hunpack { | |
2352 my ($ctx, $data, $length) = @_; | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2353 my $table = $ctx->{dynamic_decode}; |
646 | 2354 my %headers; |
2355 my $skip = 0; | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2356 my ($index, $name, $value); |
646 | 2357 |
2358 sub field { | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2359 my ($b) = @_; |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2360 my ($len, $s, $huff) = iunpack(7, @_); |
646 | 2361 |
2362 my $field = substr($b, $s, $len); | |
2363 $field = $huff ? dehuff($field) : $field; | |
2364 $s += $len; | |
2365 return ($field, $s); | |
2366 } | |
2367 | |
2368 sub add { | |
2369 my ($h, $n, $v) = @_; | |
2370 return $h->{$n} = $v unless exists $h->{$n}; | |
2371 $h->{$n} = [ $h->{$n} ]; | |
647
4e36550410b3
Tests: h2.t fixes for older perl versions, and gzip test.
Sergey Kandaurov <pluknet@nginx.com>
parents:
646
diff
changeset
|
2372 push @{$h->{$n}}, $v; |
646 | 2373 } |
2374 | |
2375 while ($skip < $length) { | |
2376 my $ib = unpack("\@$skip B8", $data); | |
2377 | |
2378 if (substr($ib, 0, 1) eq '1') { | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2379 ($index, $skip) = iunpack(7, $data, $skip); |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2380 add(\%headers, |
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2381 $table->[$index][0], $table->[$index][1]); |
646 | 2382 next; |
2383 } | |
2384 | |
2385 if (substr($ib, 0, 2) eq '01') { | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2386 ($index, $skip) = iunpack(6, $data, $skip); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2387 $name = $table->[$index][0]; |
646 | 2388 |
2389 ($name, $skip) = field($data, $skip) unless $name; | |
2390 ($value, $skip) = field($data, $skip); | |
2391 | |
671
0c70eb166a3a
Tests: in HTTP/2 tests, always access a dynamic table by reference.
Sergey Kandaurov <pluknet@nginx.com>
parents:
670
diff
changeset
|
2392 splice @$table, |
646 | 2393 $ctx->{static_table_size}, 0, [ $name, $value ]; |
2394 add(\%headers, $name, $value); | |
2395 next; | |
2396 } | |
2397 | |
2398 if (substr($ib, 0, 4) eq '0000') { | |
694
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2399 ($index, $skip) = iunpack(4, $data, $skip); |
3eba6e1b8313
Tests: finished HPACK coding in HTTP/2 tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
692
diff
changeset
|
2400 $name = $table->[$index][0]; |
646 | 2401 |
2402 ($name, $skip) = field($data, $skip) unless $name; | |
2403 ($value, $skip) = field($data, $skip); | |
2404 | |
2405 add(\%headers, $name, $value); | |
2406 next; | |
2407 } | |
2408 } | |
2409 | |
2410 return \%headers; | |
2411 } | |
2412 | |
2413 sub huff_code { scalar { | |
2414 pack('C', 0) => '1111111111000', | |
2415 pack('C', 1) => '11111111111111111011000', | |
2416 pack('C', 2) => '1111111111111111111111100010', | |
2417 pack('C', 3) => '1111111111111111111111100011', | |
2418 pack('C', 4) => '1111111111111111111111100100', | |
2419 pack('C', 5) => '1111111111111111111111100101', | |
2420 pack('C', 6) => '1111111111111111111111100110', | |
2421 pack('C', 7) => '1111111111111111111111100111', | |
2422 pack('C', 8) => '1111111111111111111111101000', | |
2423 pack('C', 9) => '111111111111111111101010', | |
2424 pack('C', 10) => '111111111111111111111111111100', | |
2425 pack('C', 11) => '1111111111111111111111101001', | |
2426 pack('C', 12) => '1111111111111111111111101010', | |
2427 pack('C', 13) => '111111111111111111111111111101', | |
2428 pack('C', 14) => '1111111111111111111111101011', | |
2429 pack('C', 15) => '1111111111111111111111101100', | |
2430 pack('C', 16) => '1111111111111111111111101101', | |
2431 pack('C', 17) => '1111111111111111111111101110', | |
2432 pack('C', 18) => '1111111111111111111111101111', | |
2433 pack('C', 19) => '1111111111111111111111110000', | |
2434 pack('C', 20) => '1111111111111111111111110001', | |
2435 pack('C', 21) => '1111111111111111111111110010', | |
2436 pack('C', 22) => '111111111111111111111111111110', | |
2437 pack('C', 23) => '1111111111111111111111110011', | |
2438 pack('C', 24) => '1111111111111111111111110100', | |
2439 pack('C', 25) => '1111111111111111111111110101', | |
2440 pack('C', 26) => '1111111111111111111111110110', | |
2441 pack('C', 27) => '1111111111111111111111110111', | |
2442 pack('C', 28) => '1111111111111111111111111000', | |
2443 pack('C', 29) => '1111111111111111111111111001', | |
2444 pack('C', 30) => '1111111111111111111111111010', | |
2445 pack('C', 31) => '1111111111111111111111111011', | |
2446 pack('C', 32) => '010100', | |
2447 pack('C', 33) => '1111111000', | |
2448 pack('C', 34) => '1111111001', | |
2449 pack('C', 35) => '111111111010', | |
2450 pack('C', 36) => '1111111111001', | |
2451 pack('C', 37) => '010101', | |
2452 pack('C', 38) => '11111000', | |
2453 pack('C', 39) => '11111111010', | |
2454 pack('C', 40) => '1111111010', | |
2455 pack('C', 41) => '1111111011', | |
2456 pack('C', 42) => '11111001', | |
2457 pack('C', 43) => '11111111011', | |
2458 pack('C', 44) => '11111010', | |
2459 pack('C', 45) => '010110', | |
2460 pack('C', 46) => '010111', | |
2461 pack('C', 47) => '011000', | |
2462 pack('C', 48) => '00000', | |
2463 pack('C', 49) => '00001', | |
2464 pack('C', 50) => '00010', | |
2465 pack('C', 51) => '011001', | |
2466 pack('C', 52) => '011010', | |
2467 pack('C', 53) => '011011', | |
2468 pack('C', 54) => '011100', | |
2469 pack('C', 55) => '011101', | |
2470 pack('C', 56) => '011110', | |
2471 pack('C', 57) => '011111', | |
2472 pack('C', 58) => '1011100', | |
2473 pack('C', 59) => '11111011', | |
2474 pack('C', 60) => '111111111111100', | |
2475 pack('C', 61) => '100000', | |
2476 pack('C', 62) => '111111111011', | |
2477 pack('C', 63) => '1111111100', | |
2478 pack('C', 64) => '1111111111010', | |
2479 pack('C', 65) => '100001', | |
2480 pack('C', 66) => '1011101', | |
2481 pack('C', 67) => '1011110', | |
2482 pack('C', 68) => '1011111', | |
2483 pack('C', 69) => '1100000', | |
2484 pack('C', 70) => '1100001', | |
2485 pack('C', 71) => '1100010', | |
2486 pack('C', 72) => '1100011', | |
2487 pack('C', 73) => '1100100', | |
2488 pack('C', 74) => '1100101', | |
2489 pack('C', 75) => '1100110', | |
2490 pack('C', 76) => '1100111', | |
2491 pack('C', 77) => '1101000', | |
2492 pack('C', 78) => '1101001', | |
2493 pack('C', 79) => '1101010', | |
2494 pack('C', 80) => '1101011', | |
2495 pack('C', 81) => '1101100', | |
2496 pack('C', 82) => '1101101', | |
2497 pack('C', 83) => '1101110', | |
2498 pack('C', 84) => '1101111', | |
2499 pack('C', 85) => '1110000', | |
2500 pack('C', 86) => '1110001', | |
2501 pack('C', 87) => '1110010', | |
2502 pack('C', 88) => '11111100', | |
2503 pack('C', 89) => '1110011', | |
2504 pack('C', 90) => '11111101', | |
2505 pack('C', 91) => '1111111111011', | |
2506 pack('C', 92) => '1111111111111110000', | |
2507 pack('C', 93) => '1111111111100', | |
2508 pack('C', 94) => '11111111111100', | |
2509 pack('C', 95) => '100010', | |
2510 pack('C', 96) => '111111111111101', | |
2511 pack('C', 97) => '00011', | |
2512 pack('C', 98) => '100011', | |
2513 pack('C', 99) => '00100', | |
2514 pack('C', 100) => '100100', | |
2515 pack('C', 101) => '00101', | |
2516 pack('C', 102) => '100101', | |
2517 pack('C', 103) => '100110', | |
2518 pack('C', 104) => '100111', | |
2519 pack('C', 105) => '00110', | |
2520 pack('C', 106) => '1110100', | |
2521 pack('C', 107) => '1110101', | |
2522 pack('C', 108) => '101000', | |
2523 pack('C', 109) => '101001', | |
2524 pack('C', 110) => '101010', | |
2525 pack('C', 111) => '00111', | |
2526 pack('C', 112) => '101011', | |
2527 pack('C', 113) => '1110110', | |
2528 pack('C', 114) => '101100', | |
2529 pack('C', 115) => '01000', | |
2530 pack('C', 116) => '01001', | |
2531 pack('C', 117) => '101101', | |
2532 pack('C', 118) => '1110111', | |
2533 pack('C', 119) => '1111000', | |
2534 pack('C', 120) => '1111001', | |
2535 pack('C', 121) => '1111010', | |
2536 pack('C', 122) => '1111011', | |
2537 pack('C', 123) => '111111111111110', | |
2538 pack('C', 124) => '11111111100', | |
2539 pack('C', 125) => '11111111111101', | |
2540 pack('C', 126) => '1111111111101', | |
2541 pack('C', 127) => '1111111111111111111111111100', | |
2542 pack('C', 128) => '11111111111111100110', | |
2543 pack('C', 129) => '1111111111111111010010', | |
2544 pack('C', 130) => '11111111111111100111', | |
2545 pack('C', 131) => '11111111111111101000', | |
2546 pack('C', 132) => '1111111111111111010011', | |
2547 pack('C', 133) => '1111111111111111010100', | |
2548 pack('C', 134) => '1111111111111111010101', | |
2549 pack('C', 135) => '11111111111111111011001', | |
2550 pack('C', 136) => '1111111111111111010110', | |
2551 pack('C', 137) => '11111111111111111011010', | |
2552 pack('C', 138) => '11111111111111111011011', | |
2553 pack('C', 139) => '11111111111111111011100', | |
2554 pack('C', 140) => '11111111111111111011101', | |
2555 pack('C', 141) => '11111111111111111011110', | |
2556 pack('C', 142) => '111111111111111111101011', | |
2557 pack('C', 143) => '11111111111111111011111', | |
2558 pack('C', 144) => '111111111111111111101100', | |
2559 pack('C', 145) => '111111111111111111101101', | |
2560 pack('C', 146) => '1111111111111111010111', | |
2561 pack('C', 147) => '11111111111111111100000', | |
2562 pack('C', 148) => '111111111111111111101110', | |
2563 pack('C', 149) => '11111111111111111100001', | |
2564 pack('C', 150) => '11111111111111111100010', | |
2565 pack('C', 151) => '11111111111111111100011', | |
2566 pack('C', 152) => '11111111111111111100100', | |
2567 pack('C', 153) => '111111111111111011100', | |
2568 pack('C', 154) => '1111111111111111011000', | |
2569 pack('C', 155) => '11111111111111111100101', | |
2570 pack('C', 156) => '1111111111111111011001', | |
2571 pack('C', 157) => '11111111111111111100110', | |
2572 pack('C', 158) => '11111111111111111100111', | |
2573 pack('C', 159) => '111111111111111111101111', | |
2574 pack('C', 160) => '1111111111111111011010', | |
2575 pack('C', 161) => '111111111111111011101', | |
2576 pack('C', 162) => '11111111111111101001', | |
2577 pack('C', 163) => '1111111111111111011011', | |
2578 pack('C', 164) => '1111111111111111011100', | |
2579 pack('C', 165) => '11111111111111111101000', | |
2580 pack('C', 166) => '11111111111111111101001', | |
2581 pack('C', 167) => '111111111111111011110', | |
2582 pack('C', 168) => '11111111111111111101010', | |
2583 pack('C', 169) => '1111111111111111011101', | |
2584 pack('C', 170) => '1111111111111111011110', | |
2585 pack('C', 171) => '111111111111111111110000', | |
2586 pack('C', 172) => '111111111111111011111', | |
2587 pack('C', 173) => '1111111111111111011111', | |
2588 pack('C', 174) => '11111111111111111101011', | |
2589 pack('C', 175) => '11111111111111111101100', | |
2590 pack('C', 176) => '111111111111111100000', | |
2591 pack('C', 177) => '111111111111111100001', | |
2592 pack('C', 178) => '1111111111111111100000', | |
2593 pack('C', 179) => '111111111111111100010', | |
2594 pack('C', 180) => '11111111111111111101101', | |
2595 pack('C', 181) => '1111111111111111100001', | |
2596 pack('C', 182) => '11111111111111111101110', | |
2597 pack('C', 183) => '11111111111111111101111', | |
2598 pack('C', 184) => '11111111111111101010', | |
2599 pack('C', 185) => '1111111111111111100010', | |
2600 pack('C', 186) => '1111111111111111100011', | |
2601 pack('C', 187) => '1111111111111111100100', | |
2602 pack('C', 188) => '11111111111111111110000', | |
2603 pack('C', 189) => '1111111111111111100101', | |
2604 pack('C', 190) => '1111111111111111100110', | |
2605 pack('C', 191) => '11111111111111111110001', | |
2606 pack('C', 192) => '11111111111111111111100000', | |
2607 pack('C', 193) => '11111111111111111111100001', | |
2608 pack('C', 194) => '11111111111111101011', | |
2609 pack('C', 195) => '1111111111111110001', | |
2610 pack('C', 196) => '1111111111111111100111', | |
2611 pack('C', 197) => '11111111111111111110010', | |
2612 pack('C', 198) => '1111111111111111101000', | |
2613 pack('C', 199) => '1111111111111111111101100', | |
2614 pack('C', 200) => '11111111111111111111100010', | |
2615 pack('C', 201) => '11111111111111111111100011', | |
2616 pack('C', 202) => '11111111111111111111100100', | |
2617 pack('C', 203) => '111111111111111111111011110', | |
2618 pack('C', 204) => '111111111111111111111011111', | |
2619 pack('C', 205) => '11111111111111111111100101', | |
2620 pack('C', 206) => '111111111111111111110001', | |
2621 pack('C', 207) => '1111111111111111111101101', | |
2622 pack('C', 208) => '1111111111111110010', | |
2623 pack('C', 209) => '111111111111111100011', | |
2624 pack('C', 210) => '11111111111111111111100110', | |
2625 pack('C', 211) => '111111111111111111111100000', | |
2626 pack('C', 212) => '111111111111111111111100001', | |
2627 pack('C', 213) => '11111111111111111111100111', | |
2628 pack('C', 214) => '111111111111111111111100010', | |
2629 pack('C', 215) => '111111111111111111110010', | |
2630 pack('C', 216) => '111111111111111100100', | |
2631 pack('C', 217) => '111111111111111100101', | |
2632 pack('C', 218) => '11111111111111111111101000', | |
2633 pack('C', 219) => '11111111111111111111101001', | |
2634 pack('C', 220) => '1111111111111111111111111101', | |
2635 pack('C', 221) => '111111111111111111111100011', | |
2636 pack('C', 222) => '111111111111111111111100100', | |
2637 pack('C', 223) => '111111111111111111111100101', | |
2638 pack('C', 224) => '11111111111111101100', | |
2639 pack('C', 225) => '111111111111111111110011', | |
2640 pack('C', 226) => '11111111111111101101', | |
2641 pack('C', 227) => '111111111111111100110', | |
2642 pack('C', 228) => '1111111111111111101001', | |
2643 pack('C', 229) => '111111111111111100111', | |
2644 pack('C', 230) => '111111111111111101000', | |
2645 pack('C', 231) => '11111111111111111110011', | |
2646 pack('C', 232) => '1111111111111111101010', | |
2647 pack('C', 233) => '1111111111111111101011', | |
2648 pack('C', 234) => '1111111111111111111101110', | |
2649 pack('C', 235) => '1111111111111111111101111', | |
2650 pack('C', 236) => '111111111111111111110100', | |
2651 pack('C', 237) => '111111111111111111110101', | |
2652 pack('C', 238) => '11111111111111111111101010', | |
2653 pack('C', 239) => '11111111111111111110100', | |
2654 pack('C', 240) => '11111111111111111111101011', | |
2655 pack('C', 241) => '111111111111111111111100110', | |
2656 pack('C', 242) => '11111111111111111111101100', | |
2657 pack('C', 243) => '11111111111111111111101101', | |
2658 pack('C', 244) => '111111111111111111111100111', | |
2659 pack('C', 245) => '111111111111111111111101000', | |
2660 pack('C', 246) => '111111111111111111111101001', | |
2661 pack('C', 247) => '111111111111111111111101010', | |
2662 pack('C', 248) => '111111111111111111111101011', | |
2663 pack('C', 249) => '1111111111111111111111111110', | |
2664 pack('C', 250) => '111111111111111111111101100', | |
2665 pack('C', 251) => '111111111111111111111101101', | |
2666 pack('C', 252) => '111111111111111111111101110', | |
2667 pack('C', 253) => '111111111111111111111101111', | |
2668 pack('C', 254) => '111111111111111111111110000', | |
2669 pack('C', 255) => '11111111111111111111101110', | |
2670 '_eos' => '111111111111111111111111111111', | |
2671 }}; | |
2672 | |
2673 sub huff { | |
2674 my ($string) = @_; | |
2675 my $code = &huff_code; | |
2676 | |
2677 my $ret = join '', map { $code->{$_} } (split //, $string); | |
2678 my $len = length($ret) + (8 - length($ret) % 8); | |
2679 $ret .= $code->{_eos}; | |
2680 | |
2681 return pack("B$len", $ret); | |
2682 } | |
2683 | |
2684 sub dehuff { | |
2685 my ($string) = @_; | |
2686 my $code = &huff_code; | |
2687 my %decode = reverse %$code; | |
2688 | |
2689 my $ret = ''; my $c = ''; | |
2690 for (split //, unpack('B*', $string)) { | |
2691 $c .= $_; | |
2692 next unless exists $decode{$c}; | |
2693 last if $decode{$c} eq '_eos'; | |
2694 | |
2695 $ret .= $decode{$c}; | |
2696 $c = ''; | |
2697 } | |
2698 | |
2699 return $ret; | |
2700 } | |
2701 | |
2702 ############################################################################### | |
2703 | |
647
4e36550410b3
Tests: h2.t fixes for older perl versions, and gzip test.
Sergey Kandaurov <pluknet@nginx.com>
parents:
646
diff
changeset
|
2704 sub gunzip_like { |
4e36550410b3
Tests: h2.t fixes for older perl versions, and gzip test.
Sergey Kandaurov <pluknet@nginx.com>
parents:
646
diff
changeset
|
2705 my ($in, $re, $name) = @_; |
646 | 2706 |
2707 SKIP: { | |
2708 eval { require IO::Uncompress::Gunzip; }; | |
2709 Test::More::skip( | |
2710 "IO::Uncompress::Gunzip not installed", 1) if $@; | |
2711 | |
2712 my $out; | |
2713 | |
2714 IO::Uncompress::Gunzip::gunzip(\$in => \$out); | |
2715 | |
647
4e36550410b3
Tests: h2.t fixes for older perl versions, and gzip test.
Sergey Kandaurov <pluknet@nginx.com>
parents:
646
diff
changeset
|
2716 like($out, $re, $name); |
646 | 2717 } |
2718 } | |
2719 | |
2720 ############################################################################### | |
2721 | |
2722 # for tests with multiple header fields | |
2723 | |
2724 sub http_daemon { | |
2725 my $server = IO::Socket::INET->new( | |
2726 Proto => 'tcp', | |
2727 LocalHost => '127.0.0.1', | |
2728 LocalPort => 8083, | |
2729 Listen => 5, | |
2730 Reuse => 1 | |
2731 ) | |
2732 or die "Can't create listening socket: $!\n"; | |
2733 | |
2734 local $SIG{PIPE} = 'IGNORE'; | |
2735 | |
2736 while (my $client = $server->accept()) { | |
2737 $client->autoflush(1); | |
2738 | |
2739 my $headers = ''; | |
2740 my $uri = ''; | |
2741 | |
2742 while (<$client>) { | |
2743 $headers .= $_; | |
2744 last if (/^\x0d?\x0a?$/); | |
2745 } | |
2746 | |
2747 next if $headers eq ''; | |
2748 $uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i; | |
2749 | |
2750 if ($uri eq '/cookie') { | |
2751 | |
652
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2752 my ($cookie, $cookie2) = $headers =~ /Cookie: (.+)/ig; |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2753 $cookie2 = '' unless defined $cookie2; |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2754 |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2755 my ($cookie_a, $cookie_c) = ('', ''); |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2756 $cookie_a = $1 if $headers =~ /X-Cookie-a: (.+)/i; |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2757 $cookie_c = $1 if $headers =~ /X-Cookie-c: (.+)/i; |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2758 |
646 | 2759 print $client <<EOF; |
2760 HTTP/1.1 200 OK | |
2761 Connection: close | |
652
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2762 X-Sent-Cookie: $cookie |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2763 X-Sent-Cookie2: $cookie2 |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2764 X-Sent-Cookie-a: $cookie_a |
5a85ad9382a3
Tests: more Cookie tests for HTTP/2.
Sergey Kandaurov <pluknet@nginx.com>
parents:
651
diff
changeset
|
2765 X-Sent-Cookie-c: $cookie_c |
646 | 2766 |
2767 EOF | |
2768 | |
2769 } elsif ($uri eq '/set-cookie') { | |
2770 | |
2771 print $client <<EOF; | |
2772 HTTP/1.1 200 OK | |
2773 Connection: close | |
2774 Set-Cookie: a=b | |
2775 Set-Cookie: c=d | |
2776 | |
2777 EOF | |
2778 | |
2779 } | |
2780 | |
2781 } continue { | |
2782 close $client; | |
2783 } | |
2784 } | |
2785 | |
2786 ############################################################################### |