Mercurial > hg > nginx-tests
comparison h2.t @ 718:ba822b2e899c
Tests: rewrote HTTP/2 response CONTINUATION tests.
Notably, parsing a header block is postponed until after all header block
fragments are read. Tests replaced to check a reconstructed header list.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Mon, 28 Sep 2015 17:15:40 +0300 |
parents | 3b6ff3b7367d |
children | 91bedf9d60a7 |
comparison
equal
deleted
inserted
replaced
717:3b6ff3b7367d | 718:ba822b2e899c |
---|---|
30 eval { IO::Socket::SSL::SSL_VERIFY_NONE(); }; | 30 eval { IO::Socket::SSL::SSL_VERIFY_NONE(); }; |
31 plan(skip_all => 'IO::Socket::SSL too old') if $@; | 31 plan(skip_all => 'IO::Socket::SSL too old') if $@; |
32 | 32 |
33 my $t = Test::Nginx->new()->has(qw/http http_ssl http_v2 proxy cache/) | 33 my $t = Test::Nginx->new()->has(qw/http http_ssl http_v2 proxy cache/) |
34 ->has(qw/limit_conn rewrite realip shmem/) | 34 ->has(qw/limit_conn rewrite realip shmem/) |
35 ->has_daemon('openssl')->plan(211); | 35 ->has_daemon('openssl')->plan(207); |
36 | 36 |
37 # FreeBSD has a bug in not treating zero iovcnt as EINVAL | 37 # FreeBSD has a bug in not treating zero iovcnt as EINVAL |
38 | 38 |
39 $t->todo_alerts() unless $^O eq 'freebsd'; | 39 $t->todo_alerts() unless $^O eq 'freebsd'; |
40 | 40 |
1325 $sess = new_session(); | 1325 $sess = new_session(); |
1326 $sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**13 }); | 1326 $sid = new_stream($sess, { path => '/continuation?h=' . 'x' x 2**13 }); |
1327 | 1327 |
1328 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); | 1328 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); |
1329 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; | 1329 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; |
1330 is(@data, 3, 'response CONTINUATION - header block frames'); | 1330 is(@{$data[-1]->{headers}{'x-longheader'}}, 3, |
1331 is($data[0]->{type}, 'HEADERS', 'response CONTINUATION - first'); | 1331 'response CONTINUATION - headers'); |
1332 is($data[0]->{flags}, 0, 'response CONTINUATION - first flags'); | 1332 is($data[-1]->{headers}{'x-longheader'}[0], 'x' x 2**13, |
1333 is($data[1]->{type}, 'CONTINUATION', 'response CONTINUATION - second'); | 1333 'response CONTINUATION - header 1'); |
1334 is($data[1]->{flags}, 0, 'response CONTINUATION - second flags'); | 1334 is($data[-1]->{headers}{'x-longheader'}[1], 'x' x 2**13, |
1335 is($data[2]->{type}, 'CONTINUATION', 'response CONTINUATION - third'); | 1335 'response CONTINUATION - header 2'); |
1336 is($data[2]->{flags}, 4, 'response CONTINUATION - third flags'); | 1336 is($data[-1]->{headers}{'x-longheader'}[2], 'x' x 2**13, |
1337 'response CONTINUATION - header 3'); | |
1338 @data = sort { $a <=> $b } map { $_->{length} } @data; | |
1339 cmp_ok($data[-1], '<=', 2**14, 'response CONTINUATION - max frame size'); | |
1337 | 1340 |
1338 # same but without response DATA frames | 1341 # same but without response DATA frames |
1339 | 1342 |
1340 $sess = new_session(); | 1343 $sess = new_session(); |
1341 $sid = new_stream($sess, { path => '/continuation/204?h=' . 'x' x 2**13 }); | 1344 $sid = new_stream($sess, { path => '/continuation/204?h=' . 'x' x 2**13 }); |
1342 | 1345 |
1343 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); | 1346 $frames = h2_read($sess, all => [{ sid => $sid, fin => 0x4 }]); |
1344 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; | 1347 @data = grep { $_->{type} =~ "HEADERS|CONTINUATION" } @$frames; |
1345 is(@data, 3, 'no body CONTINUATION - header block frames'); | 1348 is(@{$data[-1]->{headers}{'x-longheader'}}, 3, |
1346 is($data[0]->{type}, 'HEADERS', 'no body CONTINUATION - first'); | 1349 'no body CONTINUATION - headers'); |
1347 is($data[0]->{flags}, 1, 'no body CONTINUATION - first flags'); | 1350 is($data[-1]->{headers}{'x-longheader'}[0], 'x' x 2**13, |
1348 is($data[1]->{type}, 'CONTINUATION', 'no body CONTINUATION - second'); | 1351 'no body CONTINUATION - header 1'); |
1349 is($data[1]->{flags}, 0, 'no body CONTINUATION - second flags'); | 1352 is($data[-1]->{headers}{'x-longheader'}[1], 'x' x 2**13, |
1350 is($data[2]->{type}, 'CONTINUATION', 'no body CONTINUATION - third'); | 1353 'no body CONTINUATION - header 2'); |
1351 is($data[2]->{flags}, 4, 'no body CONTINUATION - third flags'); | 1354 is($data[-1]->{headers}{'x-longheader'}[2], 'x' x 2**13, |
1355 'no body CONTINUATION - header 3'); | |
1356 @data = sort { $a <=> $b } map { $_->{length} } @data; | |
1357 cmp_ok($data[-1], '<=', 2**14, 'no body CONTINUATION - max frame size'); | |
1352 | 1358 |
1353 # response header block is always split by SETTINGS_MAX_FRAME_SIZE | 1359 # response header block is always split by SETTINGS_MAX_FRAME_SIZE |
1354 | 1360 |
1355 TODO: { | 1361 TODO: { |
1356 local $TODO = 'not yet'; | 1362 local $TODO = 'not yet'; |
2059 | 2065 |
2060 sub new_stream { | 2066 sub new_stream { |
2061 my ($ctx, $uri, $stream) = @_; | 2067 my ($ctx, $uri, $stream) = @_; |
2062 my ($input, $buf); | 2068 my ($input, $buf); |
2063 my ($d, $status); | 2069 my ($d, $status); |
2070 | |
2071 $ctx->{headers} = ''; | |
2064 | 2072 |
2065 my $host = $uri->{host} || '127.0.0.1:8080'; | 2073 my $host = $uri->{host} || '127.0.0.1:8080'; |
2066 my $method = $uri->{method} || 'GET'; | 2074 my $method = $uri->{method} || 'GET'; |
2067 my $scheme = $uri->{scheme} || 'http'; | 2075 my $scheme = $uri->{scheme} || 'http'; |
2068 my $path = $uri->{path} || '/'; | 2076 my $path = $uri->{path} || '/'; |
2179 $buf = raw_read($s, $buf, $length + 9); | 2187 $buf = raw_read($s, $buf, $length + 9); |
2180 last unless length $buf; | 2188 last unless length $buf; |
2181 | 2189 |
2182 $buf = substr($buf, 9); | 2190 $buf = substr($buf, 9); |
2183 | 2191 |
2184 my $frame = $cframe{$type}{value}($sess, $buf, $length); | 2192 my $frame = $cframe{$type}{value}($sess, $buf, $length, $flags); |
2185 $frame->{length} = $length; | 2193 $frame->{length} = $length; |
2186 $frame->{type} = $cframe{$type}{name}; | 2194 $frame->{type} = $cframe{$type}{name}; |
2187 $frame->{flags} = $flags; | 2195 $frame->{flags} = $flags; |
2188 $frame->{sid} = $stream; | 2196 $frame->{sid} = $stream; |
2189 push @got, $frame; | 2197 push @got, $frame; |
2224 | 2232 |
2225 @{$all} = @test; | 2233 @{$all} = @test; |
2226 } | 2234 } |
2227 | 2235 |
2228 sub headers { | 2236 sub headers { |
2229 my ($ctx, $buf, $len) = @_; | 2237 my ($ctx, $buf, $len, $flags) = @_; |
2230 return { headers => hunpack($ctx, $buf, $len) }; | 2238 $ctx->{headers} .= substr($buf, 0, $len); |
2239 return unless $flags & 0x4; | |
2240 { headers => hunpack($ctx, $ctx->{headers}, length($ctx->{headers})) }; | |
2231 } | 2241 } |
2232 | 2242 |
2233 sub data { | 2243 sub data { |
2234 my ($ctx, $buf, $len) = @_; | 2244 my ($ctx, $buf, $len) = @_; |
2235 return { data => substr($buf, 0, $len) }; | 2245 return { data => substr($buf, 0, $len) }; |