blob: 73b4f37fe101231e6dcbaaaf2fa19fe395c6751d [file] [log] [blame]
Andrey Zelenkov82aff462016-03-23 17:23:08 +03001#!/usr/bin/perl
2
3# (C) Sergey Kandaurov
4# (C) Nginx, Inc.
5
6# Tests for HTTP/2 protocol with priority.
7
8###############################################################################
9
10use warnings;
11use strict;
12
13use Test::More;
14
15BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17use lib 'lib';
18use Test::Nginx;
Sergey Kandaurov67599f42016-06-17 11:36:33 +030019use Test::Nginx::HTTP2;
Andrey Zelenkov82aff462016-03-23 17:23:08 +030020
21###############################################################################
22
23select STDERR; $| = 1;
24select STDOUT; $| = 1;
25
26my $t = Test::Nginx->new()->has(qw/http http_v2/)->plan(20)
27 ->write_file_expand('nginx.conf', <<'EOF');
28
29%%TEST_GLOBALS%%
30
31daemon off;
32
33events {
34}
35
36http {
37 %%TEST_GLOBALS_HTTP%%
38
39 server {
Andrey Zelenkove59bf362016-07-12 17:39:03 +030040 listen 127.0.0.1:8080 http2;
Andrey Zelenkov82aff462016-03-23 17:23:08 +030041 server_name localhost;
42 }
43}
44
45EOF
46
47$t->run();
48
49# file size is slightly beyond initial window size: 2**16 + 80 bytes
50
51$t->write_file('t1.html',
52 join('', map { sprintf "X%04dXXX", $_ } (1 .. 8202)));
53
54$t->write_file('t2.html', 'SEE-THIS');
55
56###############################################################################
57
58# stream muliplexing + PRIORITY frames
59
Sergey Kandaurov67599f42016-06-17 11:36:33 +030060my $s = Test::Nginx::HTTP2->new();
61my $sid = $s->new_stream({ path => '/t1.html' });
62$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030063
Sergey Kandaurov67599f42016-06-17 11:36:33 +030064my $sid2 = $s->new_stream({ path => '/t2.html' });
65$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030066
Sergey Kandaurov67599f42016-06-17 11:36:33 +030067$s->h2_priority(0, $sid);
68$s->h2_priority(255, $sid2);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030069
Sergey Kandaurov67599f42016-06-17 11:36:33 +030070$s->h2_window(2**17, $sid);
71$s->h2_window(2**17, $sid2);
72$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030073
Sergey Kandaurov67599f42016-06-17 11:36:33 +030074my $frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +030075 { sid => $sid, fin => 1 },
76 { sid => $sid2, fin => 1 }
77]);
78
79my @data = grep { $_->{type} eq "DATA" } @$frames;
80is(join(' ', map { $_->{sid} } @data), "$sid2 $sid", 'weight - PRIORITY 1');
81
82# and vice versa
83
Sergey Kandaurov67599f42016-06-17 11:36:33 +030084$s = Test::Nginx::HTTP2->new();
85$sid = $s->new_stream({ path => '/t1.html' });
86$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030087
Sergey Kandaurov67599f42016-06-17 11:36:33 +030088$sid2 = $s->new_stream({ path => '/t2.html' });
89$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030090
Sergey Kandaurov67599f42016-06-17 11:36:33 +030091$s->h2_priority(255, $sid);
92$s->h2_priority(0, $sid2);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030093
Sergey Kandaurov67599f42016-06-17 11:36:33 +030094$s->h2_window(2**17, $sid);
95$s->h2_window(2**17, $sid2);
96$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +030097
Sergey Kandaurov67599f42016-06-17 11:36:33 +030098$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +030099 { sid => $sid, fin => 1 },
100 { sid => $sid2, fin => 1 }
101]);
102
103@data = grep { $_->{type} eq "DATA" } @$frames;
104is(join(' ', map { $_->{sid} } @data), "$sid $sid2", 'weight - PRIORITY 2');
105
106# stream muliplexing + HEADERS PRIORITY flag
107
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300108$s = Test::Nginx::HTTP2->new();
109$sid = $s->new_stream({ path => '/t1.html', prio => 0 });
110$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300111
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300112$sid2 = $s->new_stream({ path => '/t2.html', prio => 255 });
113$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300114
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300115$s->h2_window(2**17, $sid);
116$s->h2_window(2**17, $sid2);
117$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300118
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300119$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300120 { sid => $sid, fin => 1 },
121 { sid => $sid2, fin => 1 }
122]);
123
124@data = grep { $_->{type} eq "DATA" } @$frames;
125my $sids = join ' ', map { $_->{sid} } @data;
126is($sids, "$sid2 $sid", 'weight - HEADERS PRIORITY 1');
127
128# and vice versa
129
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300130$s = Test::Nginx::HTTP2->new();
131$sid = $s->new_stream({ path => '/t1.html', prio => 255 });
132$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300133
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300134$sid2 = $s->new_stream({ path => '/t2.html', prio => 0 });
135$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300136
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300137$s->h2_window(2**17, $sid);
138$s->h2_window(2**17, $sid2);
139$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300140
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300141$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300142 { sid => $sid, fin => 1 },
143 { sid => $sid2, fin => 1 }
144]);
145
146@data = grep { $_->{type} eq "DATA" } @$frames;
147$sids = join ' ', map { $_->{sid} } @data;
148is($sids, "$sid $sid2", 'weight - HEADERS PRIORITY 2');
149
150# 5.3.1. Stream Dependencies
151
152# PRIORITY frame
153
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300154$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300155
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300156$s->h2_priority(16, 3, 0);
157$s->h2_priority(16, 1, 3);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300158
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300159$sid = $s->new_stream({ path => '/t1.html' });
160$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300161
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300162$sid2 = $s->new_stream({ path => '/t2.html' });
163$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300164
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300165$s->h2_window(2**17, $sid);
166$s->h2_window(2**17, $sid2);
167$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300168
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300169$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300170 { sid => $sid, fin => 1 },
171 { sid => $sid2, fin => 1 },
172]);
173
174@data = grep { $_->{type} eq "DATA" } @$frames;
175$sids = join ' ', map { $_->{sid} } @data;
176is($sids, "$sid2 $sid", 'dependency - PRIORITY 1');
177
178# and vice versa
179
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300180$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300181
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300182$s->h2_priority(16, 1, 0);
183$s->h2_priority(16, 3, 1);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300184
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300185$sid = $s->new_stream({ path => '/t1.html' });
186$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300187
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300188$sid2 = $s->new_stream({ path => '/t2.html' });
189$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300190
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300191$s->h2_window(2**17, $sid);
192$s->h2_window(2**17, $sid2);
193$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300194
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300195$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300196 { sid => $sid, fin => 1 },
197 { sid => $sid2, fin => 1 },
198]);
199
200@data = grep { $_->{type} eq "DATA" } @$frames;
201$sids = join ' ', map { $_->{sid} } @data;
202is($sids, "$sid $sid2", 'dependency - PRIORITY 2');
203
204# PRIORITY - self dependency
205
206# 5.3.1. Stream Dependencies
207# A stream cannot depend on itself. An endpoint MUST treat this as a
208# stream error of type PROTOCOL_ERROR.
Sergey Kandaurovcf7892d2019-09-09 17:16:00 +0300209# Instead, we respond with a connection error of type PROTOCOL_ERROR.
210
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300211$s = Test::Nginx::HTTP2->new();
212$sid = $s->new_stream();
213$s->read(all => [{ sid => $sid, fin => 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300214
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300215$s->h2_priority(0, $sid, $sid);
Sergey Kandaurovcf7892d2019-09-09 17:16:00 +0300216$frames = $s->read(all => [{ type => 'GOAWAY' }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300217
Sergey Kandaurovcf7892d2019-09-09 17:16:00 +0300218my ($frame) = grep { $_->{type} eq "GOAWAY" } @$frames;
219is($frame->{last_sid}, $sid, 'dependency - PRIORITY self - GOAWAY');
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300220is($frame->{code}, 1, 'dependency - PRIORITY self - PROTOCOL_ERROR');
221
222# HEADERS PRIORITY flag, reprioritize prior PRIORITY frame records
223
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300224$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300225
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300226$s->h2_priority(16, 1, 0);
227$s->h2_priority(16, 3, 0);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300228
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300229$sid = $s->new_stream({ path => '/t1.html', dep => 3 });
230$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300231
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300232$sid2 = $s->new_stream({ path => '/t2.html' });
233$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300234
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300235$s->h2_window(2**17, $sid);
236$s->h2_window(2**17, $sid2);
237$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300238
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300239$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300240 { sid => $sid, fin => 1 },
241 { sid => $sid2, fin => 1 },
242]);
243
244@data = grep { $_->{type} eq "DATA" } @$frames;
245$sids = join ' ', map { $_->{sid} } @data;
246is($sids, "$sid2 $sid", 'dependency - HEADERS PRIORITY 1');
247
248# and vice versa
249
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300250$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300251
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300252$s->h2_priority(16, 1, 0);
253$s->h2_priority(16, 3, 0);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300254
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300255$sid = $s->new_stream({ path => '/t1.html' });
256$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300257
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300258$sid2 = $s->new_stream({ path => '/t2.html', dep => 1 });
259$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300260
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300261$s->h2_window(2**17, $sid);
262$s->h2_window(2**17, $sid2);
263$s->h2_window(2**17);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300264
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300265$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300266 { sid => $sid, fin => 1 },
267 { sid => $sid2, fin => 1 },
268]);
269
270@data = grep { $_->{type} eq "DATA" } @$frames;
271$sids = join ' ', map { $_->{sid} } @data;
272is($sids, "$sid $sid2", 'dependency - HEADERS PRIORITY 2');
273
274# HEADERS - self dependency
275
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300276$s = Test::Nginx::HTTP2->new();
277$sid = $s->new_stream({ dep => 1 });
Sergey Kandaurovcf7892d2019-09-09 17:16:00 +0300278$frames = $s->read(all => [{ type => 'GOAWAY' }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300279
Sergey Kandaurov3457b852021-06-01 16:40:18 +0300280($frame) = grep { $_->{type} eq "GOAWAY" } @$frames;
Sergey Kandaurovcf7892d2019-09-09 17:16:00 +0300281is($frame->{last_sid}, 0, 'dependency - HEADERS self - GOAWAY');
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300282is($frame->{code}, 1, 'dependency - HEADERS self - PROTOCOL_ERROR');
283
284# PRIORITY frame, weighted dependencies
285
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300286$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300287
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300288$s->h2_priority(16, 5, 0);
289$s->h2_priority(255, 1, 5);
290$s->h2_priority(0, 3, 5);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300291
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300292$sid = $s->new_stream({ path => '/t1.html' });
293$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300294
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300295$sid2 = $s->new_stream({ path => '/t2.html' });
296$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300297
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300298my $sid3 = $s->new_stream({ path => '/t2.html' });
299$s->read(all => [{ sid => $sid3, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300300
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300301$s->h2_window(2**16, 1);
302$s->h2_window(2**16, 3);
303$s->h2_window(2**16, 5);
304$s->h2_window(2**16);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300305
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300306$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300307 { sid => $sid, fin => 1 },
308 { sid => $sid2, fin => 1 },
309 { sid => $sid3, fin => 1 },
310]);
311
312@data = grep { $_->{type} eq "DATA" } @$frames;
313$sids = join ' ', map { $_->{sid} } @data;
314is($sids, "$sid3 $sid $sid2", 'weighted dependency - PRIORITY 1');
315
316# and vice versa
317
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300318$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300319
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300320$s->h2_priority(16, 5, 0);
321$s->h2_priority(0, 1, 5);
322$s->h2_priority(255, 3, 5);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300323
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300324$sid = $s->new_stream({ path => '/t1.html' });
325$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300326
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300327$sid2 = $s->new_stream({ path => '/t2.html' });
328$s->read(all => [{ sid => $sid2, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300329
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300330$sid3 = $s->new_stream({ path => '/t2.html' });
331$s->read(all => [{ sid => $sid3, fin => 0x4 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300332
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300333$s->h2_window(2**16, 1);
334$s->h2_window(2**16, 3);
335$s->h2_window(2**16, 5);
336$s->h2_window(2**16);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300337
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300338$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300339 { sid => $sid, fin => 1 },
340 { sid => $sid2, fin => 1 },
341 { sid => $sid3, fin => 1 },
342]);
343
344@data = grep { $_->{type} eq "DATA" } @$frames;
345$sids = join ' ', map { $_->{sid} } @data;
346is($sids, "$sid3 $sid2 $sid", 'weighted dependency - PRIORITY 2');
347
348# PRIORITY - reprioritization with circular dependency - after [3] removed
349# initial dependency tree:
350# 1 <- [3] <- 5
351
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300352$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300353
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300354$s->h2_window(2**18);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300355
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300356$s->h2_priority(16, 1, 0);
357$s->h2_priority(16, 3, 1);
358$s->h2_priority(16, 5, 3);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300359
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300360$sid = $s->new_stream({ path => '/t1.html' });
361$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300362
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300363$sid2 = $s->new_stream({ path => '/t1.html' });
364$s->read(all => [{ sid => $sid2, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300365
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300366$sid3 = $s->new_stream({ path => '/t1.html' });
367$s->read(all => [{ sid => $sid3, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300368
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300369$s->h2_window(2**16, $sid2);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300370
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300371$frames = $s->read(all => [{ sid => $sid2, fin => 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300372$sids = join ' ', map { $_->{sid} } grep { $_->{type} eq "DATA" } @$frames;
373is($sids, $sid2, 'removed dependency');
374
375for (1 .. 40) {
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300376 $s->read(all => [{ sid => $s->new_stream(), fin => 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300377}
378
379# make circular dependency
380# 1 <- 5 -- current dependency tree before reprioritization
381# 5 <- 1
382# 1 <- 5
383
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300384$s->h2_priority(16, 1, 5);
385$s->h2_priority(16, 5, 1);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300386
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300387$s->h2_window(2**16, $sid);
388$s->h2_window(2**16, $sid3);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300389
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300390$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300391 { sid => $sid, fin => 1 },
392 { sid => $sid3, fin => 1 },
393]);
394
Sergey Kandaurov3457b852021-06-01 16:40:18 +0300395($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == $sid } @$frames;
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300396is($frame->{length}, 81, 'removed dependency - first stream');
397
398($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == $sid3 } @$frames;
399is($frame->{length}, 81, 'removed dependency - last stream');
400
401# PRIORITY - reprioritization with circular dependency - exclusive [5]
402# 1 <- [5] <- 3
403
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300404$s = Test::Nginx::HTTP2->new();
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300405
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300406$s->h2_window(2**18);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300407
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300408$s->h2_priority(16, 1, 0);
409$s->h2_priority(16, 3, 1);
410$s->h2_priority(16, 5, 1, excl => 1);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300411
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300412$sid = $s->new_stream({ path => '/t1.html' });
413$s->read(all => [{ sid => $sid, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300414
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300415$sid2 = $s->new_stream({ path => '/t1.html' });
416$s->read(all => [{ sid => $sid2, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300417
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300418$sid3 = $s->new_stream({ path => '/t1.html' });
419$s->read(all => [{ sid => $sid3, length => 2**16 - 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300420
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300421$s->h2_window(2**16, $sid);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300422
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300423$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300424$sids = join ' ', map { $_->{sid} } grep { $_->{type} eq "DATA" } @$frames;
425is($sids, $sid, 'exclusive dependency - parent removed');
426
427# make circular dependency
428# 5 <- 3 -- current dependency tree before reprioritization
429# 3 <- 5
430
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300431$s->h2_priority(16, 5, 3);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300432
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300433$s->h2_window(2**16, $sid2);
434$s->h2_window(2**16, $sid3);
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300435
Sergey Kandaurov67599f42016-06-17 11:36:33 +0300436$frames = $s->read(all => [
Andrey Zelenkov82aff462016-03-23 17:23:08 +0300437 { sid => $sid2, fin => 1 },
438 { sid => $sid3, fin => 1 },
439]);
440
441($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == $sid2 } @$frames;
442is($frame->{length}, 81, 'exclusive dependency - first stream');
443
444($frame) = grep { $_->{type} eq "DATA" && $_->{sid} == $sid3 } @$frames;
445is($frame->{length}, 81, 'exclusive dependency - last stream');
446
447###############################################################################