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) };